diff options
author | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
commit | 972dcfcdbfe75dcfeb777150c136576cf1a71e99 (patch) | |
tree | 97a61cd7e293d7ae9d56ef7ed0f81253365bb026 /bitbake/lib/prserv/db.py | |
download | poky-972dcfcdbfe75dcfeb777150c136576cf1a71e99.tar.gz |
initial commit for Enea Linux 5.0 arm
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'bitbake/lib/prserv/db.py')
-rw-r--r-- | bitbake/lib/prserv/db.py | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/bitbake/lib/prserv/db.py b/bitbake/lib/prserv/db.py new file mode 100644 index 0000000000..9d6d11526a --- /dev/null +++ b/bitbake/lib/prserv/db.py | |||
@@ -0,0 +1,258 @@ | |||
1 | import logging | ||
2 | import os.path | ||
3 | import errno | ||
4 | import prserv | ||
5 | import time | ||
6 | |||
7 | try: | ||
8 | import sqlite3 | ||
9 | except ImportError: | ||
10 | from pysqlite2 import dbapi2 as sqlite3 | ||
11 | |||
12 | logger = logging.getLogger("BitBake.PRserv") | ||
13 | |||
14 | sqlversion = sqlite3.sqlite_version_info | ||
15 | if sqlversion[0] < 3 or (sqlversion[0] == 3 and sqlversion[1] < 3): | ||
16 | raise Exception("sqlite3 version 3.3.0 or later is required.") | ||
17 | |||
18 | class PRTable(object): | ||
19 | def __init__(self, conn, table, nohist): | ||
20 | self.conn = conn | ||
21 | self.nohist = nohist | ||
22 | self.dirty = False | ||
23 | if nohist: | ||
24 | self.table = "%s_nohist" % table | ||
25 | else: | ||
26 | self.table = "%s_hist" % table | ||
27 | |||
28 | self._execute("CREATE TABLE IF NOT EXISTS %s \ | ||
29 | (version TEXT NOT NULL, \ | ||
30 | pkgarch TEXT NOT NULL, \ | ||
31 | checksum TEXT NOT NULL, \ | ||
32 | value INTEGER, \ | ||
33 | PRIMARY KEY (version, pkgarch, checksum));" % self.table) | ||
34 | |||
35 | def _execute(self, *query): | ||
36 | """Execute a query, waiting to acquire a lock if necessary""" | ||
37 | start = time.time() | ||
38 | end = start + 20 | ||
39 | while True: | ||
40 | try: | ||
41 | return self.conn.execute(*query) | ||
42 | except sqlite3.OperationalError as exc: | ||
43 | if 'is locked' in str(exc) and end > time.time(): | ||
44 | continue | ||
45 | raise exc | ||
46 | |||
47 | def sync(self): | ||
48 | self.conn.commit() | ||
49 | self._execute("BEGIN EXCLUSIVE TRANSACTION") | ||
50 | |||
51 | def sync_if_dirty(self): | ||
52 | if self.dirty: | ||
53 | self.sync() | ||
54 | self.dirty = False | ||
55 | |||
56 | def _getValueHist(self, version, pkgarch, checksum): | ||
57 | data=self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=?;" % self.table, | ||
58 | (version, pkgarch, checksum)) | ||
59 | row=data.fetchone() | ||
60 | if row != None: | ||
61 | return row[0] | ||
62 | else: | ||
63 | #no value found, try to insert | ||
64 | try: | ||
65 | self._execute("INSERT INTO %s VALUES (?, ?, ?, (select ifnull(max(value)+1,0) from %s where version=? AND pkgarch=?));" | ||
66 | % (self.table,self.table), | ||
67 | (version,pkgarch, checksum,version, pkgarch)) | ||
68 | except sqlite3.IntegrityError as exc: | ||
69 | logger.error(str(exc)) | ||
70 | |||
71 | self.dirty = True | ||
72 | |||
73 | data=self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=?;" % self.table, | ||
74 | (version, pkgarch, checksum)) | ||
75 | row=data.fetchone() | ||
76 | if row != None: | ||
77 | return row[0] | ||
78 | else: | ||
79 | raise prserv.NotFoundError | ||
80 | |||
81 | def _getValueNohist(self, version, pkgarch, checksum): | ||
82 | data=self._execute("SELECT value FROM %s \ | ||
83 | WHERE version=? AND pkgarch=? AND checksum=? AND \ | ||
84 | value >= (select max(value) from %s where version=? AND pkgarch=?);" | ||
85 | % (self.table, self.table), | ||
86 | (version, pkgarch, checksum, version, pkgarch)) | ||
87 | row=data.fetchone() | ||
88 | if row != None: | ||
89 | return row[0] | ||
90 | else: | ||
91 | #no value found, try to insert | ||
92 | try: | ||
93 | self._execute("INSERT OR REPLACE INTO %s VALUES (?, ?, ?, (select ifnull(max(value)+1,0) from %s where version=? AND pkgarch=?));" | ||
94 | % (self.table,self.table), | ||
95 | (version, pkgarch, checksum, version, pkgarch)) | ||
96 | except sqlite3.IntegrityError as exc: | ||
97 | logger.error(str(exc)) | ||
98 | self.conn.rollback() | ||
99 | |||
100 | self.dirty = True | ||
101 | |||
102 | data=self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=?;" % self.table, | ||
103 | (version, pkgarch, checksum)) | ||
104 | row=data.fetchone() | ||
105 | if row != None: | ||
106 | return row[0] | ||
107 | else: | ||
108 | raise prserv.NotFoundError | ||
109 | |||
110 | def getValue(self, version, pkgarch, checksum): | ||
111 | if self.nohist: | ||
112 | return self._getValueNohist(version, pkgarch, checksum) | ||
113 | else: | ||
114 | return self._getValueHist(version, pkgarch, checksum) | ||
115 | |||
116 | def _importHist(self, version, pkgarch, checksum, value): | ||
117 | val = None | ||
118 | data = self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=?;" % self.table, | ||
119 | (version, pkgarch, checksum)) | ||
120 | row = data.fetchone() | ||
121 | if row != None: | ||
122 | val=row[0] | ||
123 | else: | ||
124 | #no value found, try to insert | ||
125 | try: | ||
126 | self._execute("INSERT INTO %s VALUES (?, ?, ?, ?);" % (self.table), | ||
127 | (version, pkgarch, checksum, value)) | ||
128 | except sqlite3.IntegrityError as exc: | ||
129 | logger.error(str(exc)) | ||
130 | |||
131 | self.dirty = True | ||
132 | |||
133 | data = self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=?;" % self.table, | ||
134 | (version, pkgarch, checksum)) | ||
135 | row = data.fetchone() | ||
136 | if row != None: | ||
137 | val = row[0] | ||
138 | return val | ||
139 | |||
140 | def _importNohist(self, version, pkgarch, checksum, value): | ||
141 | try: | ||
142 | #try to insert | ||
143 | self._execute("INSERT INTO %s VALUES (?, ?, ?, ?);" % (self.table), | ||
144 | (version, pkgarch, checksum,value)) | ||
145 | except sqlite3.IntegrityError as exc: | ||
146 | #already have the record, try to update | ||
147 | try: | ||
148 | self._execute("UPDATE %s SET value=? WHERE version=? AND pkgarch=? AND checksum=? AND value<?" | ||
149 | % (self.table), | ||
150 | (value,version,pkgarch,checksum,value)) | ||
151 | except sqlite3.IntegrityError as exc: | ||
152 | logger.error(str(exc)) | ||
153 | |||
154 | self.dirty = True | ||
155 | |||
156 | data = self._execute("SELECT value FROM %s WHERE version=? AND pkgarch=? AND checksum=? AND value>=?;" % self.table, | ||
157 | (version,pkgarch,checksum,value)) | ||
158 | row=data.fetchone() | ||
159 | if row != None: | ||
160 | return row[0] | ||
161 | else: | ||
162 | return None | ||
163 | |||
164 | def importone(self, version, pkgarch, checksum, value): | ||
165 | if self.nohist: | ||
166 | return self._importNohist(version, pkgarch, checksum, value) | ||
167 | else: | ||
168 | return self._importHist(version, pkgarch, checksum, value) | ||
169 | |||
170 | def export(self, version, pkgarch, checksum, colinfo): | ||
171 | metainfo = {} | ||
172 | #column info | ||
173 | if colinfo: | ||
174 | metainfo['tbl_name'] = self.table | ||
175 | metainfo['core_ver'] = prserv.__version__ | ||
176 | metainfo['col_info'] = [] | ||
177 | data = self._execute("PRAGMA table_info(%s);" % self.table) | ||
178 | for row in data: | ||
179 | col = {} | ||
180 | col['name'] = row['name'] | ||
181 | col['type'] = row['type'] | ||
182 | col['notnull'] = row['notnull'] | ||
183 | col['dflt_value'] = row['dflt_value'] | ||
184 | col['pk'] = row['pk'] | ||
185 | metainfo['col_info'].append(col) | ||
186 | |||
187 | #data info | ||
188 | datainfo = [] | ||
189 | |||
190 | if self.nohist: | ||
191 | sqlstmt = "SELECT T1.version, T1.pkgarch, T1.checksum, T1.value FROM %s as T1, \ | ||
192 | (SELECT version,pkgarch,max(value) as maxvalue FROM %s GROUP BY version,pkgarch) as T2 \ | ||
193 | WHERE T1.version=T2.version AND T1.pkgarch=T2.pkgarch AND T1.value=T2.maxvalue " % (self.table, self.table) | ||
194 | else: | ||
195 | sqlstmt = "SELECT * FROM %s as T1 WHERE 1=1 " % self.table | ||
196 | sqlarg = [] | ||
197 | where = "" | ||
198 | if version: | ||
199 | where += "AND T1.version=? " | ||
200 | sqlarg.append(str(version)) | ||
201 | if pkgarch: | ||
202 | where += "AND T1.pkgarch=? " | ||
203 | sqlarg.append(str(pkgarch)) | ||
204 | if checksum: | ||
205 | where += "AND T1.checksum=? " | ||
206 | sqlarg.append(str(checksum)) | ||
207 | |||
208 | sqlstmt += where + ";" | ||
209 | |||
210 | if len(sqlarg): | ||
211 | data = self._execute(sqlstmt, tuple(sqlarg)) | ||
212 | else: | ||
213 | data = self._execute(sqlstmt) | ||
214 | for row in data: | ||
215 | if row['version']: | ||
216 | col = {} | ||
217 | col['version'] = row['version'] | ||
218 | col['pkgarch'] = row['pkgarch'] | ||
219 | col['checksum'] = row['checksum'] | ||
220 | col['value'] = row['value'] | ||
221 | datainfo.append(col) | ||
222 | return (metainfo, datainfo) | ||
223 | |||
224 | class PRData(object): | ||
225 | """Object representing the PR database""" | ||
226 | def __init__(self, filename, nohist=True): | ||
227 | self.filename=os.path.abspath(filename) | ||
228 | self.nohist=nohist | ||
229 | #build directory hierarchy | ||
230 | try: | ||
231 | os.makedirs(os.path.dirname(self.filename)) | ||
232 | except OSError as e: | ||
233 | if e.errno != errno.EEXIST: | ||
234 | raise e | ||
235 | self.connection=sqlite3.connect(self.filename, isolation_level="EXCLUSIVE", check_same_thread = False) | ||
236 | self.connection.row_factory=sqlite3.Row | ||
237 | self.connection.execute("pragma synchronous = off;") | ||
238 | self.connection.execute("PRAGMA journal_mode = WAL;") | ||
239 | self._tables={} | ||
240 | |||
241 | def __del__(self): | ||
242 | self.connection.close() | ||
243 | |||
244 | def __getitem__(self,tblname): | ||
245 | if not isinstance(tblname, basestring): | ||
246 | raise TypeError("tblname argument must be a string, not '%s'" % | ||
247 | type(tblname)) | ||
248 | if tblname in self._tables: | ||
249 | return self._tables[tblname] | ||
250 | else: | ||
251 | tableobj = self._tables[tblname] = PRTable(self.connection, tblname, self.nohist) | ||
252 | return tableobj | ||
253 | |||
254 | def __delitem__(self, tblname): | ||
255 | if tblname in self._tables: | ||
256 | del self._tables[tblname] | ||
257 | logger.info("drop table %s" % (tblname)) | ||
258 | self.connection.execute("DROP TABLE IF EXISTS %s;" % tblname) | ||