pyP2Monitor  1.0.0
Monitor a P2 furnace activity reading data on serial port
 All Data Structures Namespaces Functions Variables Groups Pages
p2dbstore.py
1 # -*- coding: utf-8 -*-#
2 
3 # Copyright 2013, 2014 Weber Yann, Weber Laurent
4 #
5 # This file is part of pyP2Monitor.
6 #
7 # pyP2Monitor is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # pyP2Monitor is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with pyP2Monitor. If not, see <http://www.gnu.org/licenses/>.
19 #
20 
21 ##@package p2dbstore Define the P2DbStore object, used to store P2's datas in a database
22 
23 import sqlite3
24 import logging
25 import utils
26 
27 ##Use to log
28 #@see utils.getLogger()
29 logger = utils.getLogger()
30 
31 ##Used to handle the Sqlite database connection
32 # @ingroup msgprocess
33 class P2DbStore:
34 
35  ##Maximum insery buffer size
36  INSERTBUFFSZ = 60
37 
38  ##Create the Database object
39  #
40  #@param filename The Sqlite file name
41  def __init__(self, filename="p2.db"):
42 
43  ##The database connection
44  #self.conn = sqlite3.connect(filename, 5)
45  self.conn = sqlite3.connect(filename, 1, 0, None)
46  ##The database cursor
47  self.c = self.conn.cursor()
48  ##A buffer used to store valued that failed to be inserted previously
49  self.insertBuff = []
50 
51  locked = True
52  while locked:
53  try:
54  ##Database initialisation
55  self.c.execute('create table if not exists p2data (date integer, data collate binary)')
56  #self.conn.commit()
57  locked = False
58  except sqlite3.OperationalError:
59  locked = True
60  logger.warning("Database opening failed, database locked")
61 
62  pass
63 
64  ##Insert datas into database
65  #
66  #@param timestamp The data's timestamp
67  #@param datas The data to store
68  def insert(self, timestamp, datas):
69  #Maybe add checks
70 
71  #val = (timestamp,pickle.dumps(datas))
72  val = (timestamp,datas)
73 
74  req = 'insert into p2data values (?,?)'
75 
76  self.insertBuff.append(val)
77 
78  try:
79  self.c.executemany(req, self.insertBuff)
80  logger.debug("Inserted "+str(len(self.insertBuff))+" datas")
81  self.insertBuff = []
82  except sqlite3.OperationalError:
83  if len(self.insertBuff) > P2DbStore.INSERTBUFFSZ:
84  logger.warning("Data lost after failing too many times to insert because of database lock.")
85  self.insertBuff.pop(0)
86 
87  logger.debug('Data inserted in db')
88  logger.debug('Data stored in database')
89  pass
90 
91  ##Retrieve data from database
92  #
93  #@param dateMin is the smaller data's timestamp returned
94  #@param dateMax is the higher data's timestamp returned (0 or less mean no limit)
95  #
96  #@return An array of selected datas
97  def getData(self, dateMin=0, dateMax=0):
98  val = () #Store SQL query parameters
99 
100  #SQL query construction
101  req = 'select * from p2data'
102  if dateMin > 0:
103  req += ' where date >= ?'
104  val += (dateMin,)
105  if dateMax > 0:
106  if len(val) == 0:
107  req += ' where '
108  else:
109  req += ' and '
110  req += ' date <= ?'
111  val += (dateMax,)
112  req += ' order by date'
113 
114  logger.debug('Executing : \''+req+'\' on database')
115 
116  #Getting results
117  locked = True
118  while locked:
119  try:
120  #SQL query execution
121  self.c.execute(req, val)
122  res = self.c.fetchall()
123  locked = False
124  except sqlite3.OperationalError:
125  locked = True
126  logger.warning("Database reading failed, database locked")
127 
128  #Return selected rows as an array
129 
130  return res
131 
132  ##Retrieve the oldest date in the db
133  #
134  #@return The smallest timestamp in the db
135  def getFirst(self, oldest=True):
136  locked = True
137  while locked:
138  try:
139  req = 'SELECT * FROM p2data ORDER BY date LIMIT 1'
140  self.c.execute(req, ())
141  res = self.c.fetchone()
142  locked = False
143  except sqlite3.OperationalError:
144  locked = True
145  logger.warning("Database reading failed, database locked")
146 
147  if res != None:
148  res = res[0]
149  return res
150 
151  ##Retrieve the last (newest) data in db
152  #
153  # Can be a relatively long query
154  #
155  #@return The bigger timestamp
156  def getLastData(self):
157  locked = True
158  while locked:
159  try:
160  req = 'SELECT * FROM p2data ORDER BY date DESC LIMIT 10'
161  self.c.execute(req,())
162  res = self.c.fetchall()
163  locked = False
164  except sqlite3.OperationalError:
165  locked = True
166  logger.warning("Database reading failed, database locked")
167 
168  return res
169 
170  ##P2DbStore destructor
171  def __del__(self):
172  self.c.close()