techrec.py 7.9 KB

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