db.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. """
  2. This module contains DB logic
  3. """
  4. from __future__ import print_function
  5. import logging
  6. from datetime import datetime, timedelta
  7. import sys
  8. from sqlalchemy import create_engine, Column, Integer, String, DateTime, inspect
  9. from sqlalchemy.orm import sessionmaker
  10. from sqlalchemy.ext.declarative import declarative_base
  11. from .config_manager import get_config
  12. PAGESIZE = 10
  13. Base = declarative_base()
  14. class Rec(Base):
  15. """Entry on the DB"""
  16. __tablename__ = "rec"
  17. id = Column(Integer, primary_key=True)
  18. name = Column(String, nullable=True)
  19. starttime = Column(DateTime, nullable=True)
  20. endtime = Column(DateTime, nullable=True)
  21. filename = Column(String, nullable=True)
  22. def __init__(self, name="", starttime=None, endtime=None, filename=None):
  23. self.name = name
  24. self.starttime = starttime
  25. self.endtime = endtime
  26. self.filename = filename
  27. def serialize(self):
  28. """json-friendly encoding"""
  29. return {
  30. "id": self.id,
  31. "name": self.name,
  32. "starttime": self.starttime,
  33. "endtime": self.endtime,
  34. "filename": self.filename,
  35. }
  36. def __repr__(self):
  37. contents = "id:'%s',name:'%s',Start: '%s',End: '%s'" % (
  38. self.id,
  39. self.name,
  40. self.starttime,
  41. self.endtime,
  42. )
  43. if self.filename is not None:
  44. contents += ",Filename: '%s'" % self.filename
  45. return "<Rec(%s)>" % contents
  46. class RecDB:
  47. def __init__(self, uri):
  48. self.engine = create_engine(uri, echo=False)
  49. self.conn = self.engine.connect()
  50. self.log = logging.getLogger(name=self.__class__.__name__)
  51. logging.getLogger("sqlalchemy.engine").setLevel(logging.FATAL)
  52. logging.getLogger("sqlalchemy.engine.base.Engine").setLevel(logging.FATAL)
  53. logging.getLogger("sqlalchemy.dialects").setLevel(logging.FATAL)
  54. logging.getLogger("sqlalchemy.pool").setLevel(logging.FATAL)
  55. logging.getLogger("sqlalchemy.orm").setLevel(logging.FATAL)
  56. Base.metadata.create_all(self.engine) # create Database
  57. Session = sessionmaker(bind=self.engine)
  58. self.session = Session()
  59. self.err = ""
  60. def add(self, simplerecord):
  61. s = self.get_session()
  62. s.add(simplerecord)
  63. s.commit()
  64. self.log.info("New Record: %s" % simplerecord)
  65. return simplerecord
  66. def update(self, id, rec):
  67. # TODO: rlist = results list
  68. _rlist = self._search(_id=id)
  69. if not len(_rlist) == 1:
  70. raise ValueError("Too many recs with id=%s" % id)
  71. self.log.debug("DB:: Update request %s:%s " % (id, rec))
  72. self.log.debug("DB:: Update: data before %s" % _rlist[0])
  73. # 2013-11-24 22:22:42
  74. _rlist[0].starttime = rec["starttime"]
  75. _rlist[0].endtime = rec["endtime"]
  76. if "name" in rec:
  77. _rlist[0].name = rec["name"]
  78. self.log.debug("DB:: Update: data AFTER %s" % _rlist[0])
  79. self.get_session(_rlist[0]).commit()
  80. self.log.debug("DB:: Update complete")
  81. return _rlist[0]
  82. def delete(self, recid):
  83. _rlist = self._search(id=recid)
  84. if len(_rlist) == 0:
  85. self.log.info("DB: Delete: no record found!")
  86. self.err = "No rec found"
  87. return False
  88. if len(_rlist) > 1:
  89. self.log.warning("DB: Delete: multiple records found!")
  90. self.err = "multiple ID Found %s" % (_rlist)
  91. return False
  92. s = self.get_session()
  93. s.delete(_rlist[0])
  94. self.log.info("Delete: delete complete")
  95. s.commit()
  96. return True
  97. def commit(self):
  98. self.log.info("Commit!!")
  99. self.session.commit()
  100. def get_session(self, rec=None):
  101. if rec is None:
  102. Session = sessionmaker(bind=self.engine)
  103. return Session()
  104. else:
  105. return inspect(rec).session
  106. def get_all(self, page=0, page_size=PAGESIZE):
  107. return self._search(page=page, page_size=page_size)
  108. def get_ongoing(self, page=0, page_size=PAGESIZE):
  109. query = self._query_page(self._query_ongoing(), page, page_size)
  110. return query.all()
  111. def get_not_completed(self, minseconds=36000):
  112. query = self._query_ongoing()
  113. query = self._query_older(timedelta(seconds=minseconds), query)
  114. return query.all()
  115. def get_archive_recent(self):
  116. query = self._query_saved()
  117. query = self._query_newer(timedelta(days=15), query)
  118. query = query.order_by(Rec.starttime.desc())
  119. return query.all()
  120. def _query_ongoing(self, query=None):
  121. """
  122. Not terminated AND recent.
  123. The meaning is "a query that makes sense to stop"
  124. """
  125. delta = timedelta(seconds=get_config()["FORGE_MAX_DURATION"])
  126. return self._query_newer(delta, self._query_not_saved(query))
  127. def _query_not_saved(self, query=None):
  128. """Still not saved"""
  129. if query is None:
  130. query = self.get_session().query(Rec)
  131. return query.filter(Rec.filename == None)
  132. def _query_saved(self, query=None):
  133. """Still not saved"""
  134. if query is None:
  135. query = self.get_session().query(Rec)
  136. return query.filter(Rec.filename != None)
  137. def _query_newer(self, delta, query=None):
  138. """Get Rec older than delta seconds"""
  139. if query is None:
  140. query = self.get_session().query(Rec)
  141. return query.filter(Rec.starttime > datetime.now() - delta)
  142. def _query_older(self, delta, query=None):
  143. """Get Rec older than delta seconds"""
  144. if query is None:
  145. query = self.get_session().query(Rec)
  146. return query.filter(Rec.starttime < datetime.now() - delta)
  147. def _query_page(self, query, page=0, page_size=PAGESIZE):
  148. if page_size:
  149. page_size = int(page_size)
  150. query = query.limit(page_size)
  151. if page:
  152. query = query.offset(page * page_size)
  153. return query
  154. def _query_generic(self, query, _id=None, name=None, starttime=None, endtime=None):
  155. if _id is not None:
  156. query = query.filter_by(id=_id)
  157. if name is not None:
  158. query = query.filter(Rec.name.like("%" + name + "%"))
  159. if starttime is not None:
  160. _st = starttime
  161. query = query.filter(Rec.starttime > _st)
  162. if endtime is not None:
  163. _et = endtime
  164. query = query.filter(Rec.endtime < _et)
  165. return query
  166. def _search(
  167. self,
  168. _id=None,
  169. name=None,
  170. starttime=None,
  171. endtime=None,
  172. page=0,
  173. page_size=PAGESIZE,
  174. ):
  175. self.log.debug(
  176. "DB: Search => id:%s name:%s starttime:%s endtime=%s"
  177. % (_id, name, starttime, endtime)
  178. )
  179. query = self.get_session().query(Rec)
  180. query = self._query_generic(query, _id, name, starttime, endtime)
  181. query = self._query_page(query, page, page_size)
  182. self.log.debug("Searching: %s" % str(query))
  183. ret = query.all()
  184. return ret
  185. def get_err(self):
  186. print("DB error: %s" % (self.err))
  187. t = self.err
  188. self.err = ""
  189. return t
  190. if __name__ == "__main__":
  191. def printall(queryres):
  192. for record in queryres:
  193. print("Record: %s" % record)
  194. db = RecDB()
  195. _mytime = datetime(2014, 5, 23, 15, 12, 17)
  196. _endtime = datetime(2014, 5, 24, 17, 45, 17)
  197. a = Rec(name="Mimmo1", starttime=_mytime, endtime=_endtime)
  198. printall(db._search())
  199. sys.exit("End test job")
  200. # a = Rec(name="Mimmo1", starttime=_mytime, endtime=None)
  201. print("Aggiunto", db.add(a))
  202. printall(db.get_all(page_size=5, page=0))
  203. print("Mimmo ")
  204. printall(db._search(name="Mimmo1"))
  205. print("Search")
  206. printall(db._search(name="Mimmo1", starttime=datetime(2014, 5, 24, 15, 16, 1)))
  207. a = db.get_by_id(5)
  208. a.start()
  209. db.delete(1)
  210. db.delete(2)
  211. db.delete(4)
  212. db.delete(1)
  213. printall(db._search())