sqlite.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. #============================================================================
  2. # This file is part of Pwman3.
  3. #
  4. # Pwman3 is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License, version 2
  6. # as published by the Free Software Foundation;
  7. #
  8. # Pwman3 is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with Pwman3; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. #============================================================================
  17. # Copyright (C) 2012 Oz Nahum <nahumoz@gmail.com>
  18. #============================================================================
  19. #============================================================================
  20. # Copyright (C) 2006 Ivan Kelly <ivan@ivankelly.net>
  21. #============================================================================
  22. """SQLite Database implementation."""
  23. from pwman.data.database import Database, DatabaseException
  24. from pwman.data.nodes import Node
  25. from pwman.data.nodes import NewNode
  26. from pwman.data.tags import Tag
  27. import re
  28. import sys
  29. if sys.version_info > (2, 5):
  30. import sqlite3 as sqlite
  31. else:
  32. try:
  33. from pysqlite2 import dbapi2 as sqlite
  34. except ImportError:
  35. raise DatabaseException("python-sqlite2 not installed")
  36. import pwman.util.config as config
  37. import cPickle
  38. def check_db_version():
  39. """
  40. check the data base version query the right table
  41. """
  42. try:
  43. filename = config.get_value('Database', 'filename')
  44. con = sqlite.connect(filename)
  45. cur = con.cursor()
  46. cur.execute("PRAGMA TABLE_INFO(DBVERSION)")
  47. row = cur.fetchone()
  48. if row is None:
  49. return "0.3"
  50. try:
  51. return row[-2]
  52. except IndexError:
  53. raise DatabaseException("Something seems fishy with the DB")
  54. except sqlite.DatabaseError, e:
  55. raise DatabaseException("SQLite: %s" % (e))
  56. class SQLiteDatabaseNewForm(Database):
  57. """SQLite Database implementation"""
  58. def __init__(self, filename=None):
  59. """Initialise SQLitePwmanDatabase instance."""
  60. Database.__init__(self)
  61. if filename:
  62. self._filename = filename
  63. else:
  64. try:
  65. self._filename = config.get_value('Database', 'filename')
  66. except KeyError, e:
  67. raise DatabaseException(
  68. "SQLite: missing parameter [%s]" % (e))
  69. def _open(self):
  70. try:
  71. self._con = sqlite.connect(self._filename)
  72. self._cur = self._con.cursor()
  73. self._checktables()
  74. except sqlite.DatabaseError, e:
  75. raise DatabaseException("SQLite: %s" % (e))
  76. def close(self):
  77. self._cur.close()
  78. self._con.close()
  79. def listtags(self, alltags=False):
  80. sql = ''
  81. params = []
  82. if len(self._filtertags) == 0 or alltags:
  83. sql = "SELECT DATA FROM TAGS ORDER BY DATA ASC"
  84. else:
  85. sql = ("SELECT TAGS.DATA FROM LOOKUP"
  86. + " INNER JOIN TAGS ON LOOKUP.TAG = TAGS.ID"
  87. + " WHERE NODE IN (")
  88. first = True
  89. # if using the command filter, the code crashes ...
  90. #
  91. for t in self._filtertags:
  92. if not first:
  93. sql += " INTERSECT "
  94. else:
  95. first = False
  96. sql += ("SELECT NODE FROM LOOKUP LEFT JOIN TAGS ON TAG = "
  97. + " TAGS.ID WHERE TAGS.DATA = ?")
  98. params.append(t.get_name())
  99. sql += ") EXCEPT SELECT DATA FROM TAGS WHERE "
  100. first = True
  101. for t in self._filtertags:
  102. if not first:
  103. sql += " OR "
  104. else:
  105. first = False
  106. sql += "TAGS.DATA = ?"
  107. params.append(t.get_name())
  108. import ipdb
  109. ipdb.set_trace()
  110. try:
  111. self._cur.execute(sql, params)
  112. tags = []
  113. row = self._cur.fetchone()
  114. while row is not None:
  115. tagstring = str(row[0])
  116. #m = re.search('S\"S\'(.+?)\'', tagstring)
  117. #if m:
  118. # found = m.group(1)
  119. tags.append(tagstring)
  120. row = self._cur.fetchone()
  121. return tags
  122. except sqlite.DatabaseError, e:
  123. raise DatabaseException("SQLite: %s" % (e))
  124. def parse_node_string(self, string):
  125. nodestring = string.split("##")
  126. keyvals = {}
  127. for pair in nodestring[:-1]:
  128. key, val = pair.split(":")
  129. keyvals[key.lstrip('##')] = val
  130. tags = nodestring[-1]
  131. tags = tags.lstrip("tags:")
  132. tags = tags.split("tag:")
  133. taginsts = []
  134. for tag in tags:
  135. _Tag = tag.rstrip("**endtag**")
  136. Tag = (_Tag)
  137. taginsts.append(Tag)
  138. return keyvals, taginsts
  139. def getnodes(self, ids):
  140. """
  141. object should always be: (ipwman.data.nodes
  142. """
  143. nodes = []
  144. for i in ids:
  145. sql = "SELECT DATA FROM NODES WHERE ID = ?"
  146. # try:
  147. self._cur.execute(sql, [i])
  148. row = self._cur.fetchone()
  149. if row is not None:
  150. nodestring = str(row[0])
  151. # if not nodestring.startswith("(ipwman.data.nodes"):
  152. # raise DatabaseException(
  153. #"Tried to load foreign object from database," \
  154. #+ " this looks fishy in here...")
  155. nodeargs, tags = self.parse_node_string(nodestring)
  156. node = NewNode(**nodeargs)
  157. node.set_tags(tags)
  158. node.set_id(i)
  159. nodes.append(node)
  160. # except sqlite.DatabaseError, e:
  161. # raise DatabaseException("SQLite: %s" % (e))
  162. return nodes
  163. def editnode(self, id, node):
  164. try:
  165. sql = "UPDATE NODES SET DATA = ? WHERE ID = ?"
  166. self._cur.execute(sql, [node.dump_edit_to_db()[0], id])
  167. except sqlite.DatabaseError, e:
  168. raise DatabaseException("SQLite: %s" % (e))
  169. self._setnodetags(node)
  170. self._checktags()
  171. self._commit()
  172. def addnodes(self, nodes):
  173. """
  174. This method injects the data as PWMAN object using cPickle.
  175. To make pwman more secure, either this method has to replaced.
  176. Or whenever stuff is read from the database, there must be a
  177. security check that it contains the correct objects!
  178. Nodes passed to this methos are instances!
  179. """
  180. for n in nodes:
  181. sql = "INSERT INTO NODES(DATA) VALUES(?)"
  182. # if not isinstance(n, Node): raise DatabaseException(
  183. # "Tried to insert foreign object into database [%s]", n)
  184. value = n.dump_to_db()
  185. try:
  186. self._cur.execute(sql, value)
  187. except sqlite.DatabaseError, e:
  188. raise DatabaseException("SQLite: %s" % (e))
  189. idx = self._cur.lastrowid
  190. n.set_id(idx)
  191. self._setnodetags(n)
  192. self._commit()
  193. def removenodes(self, nodes):
  194. for n in nodes:
  195. # if not isinstance(n, Node): raise DatabaseException(
  196. # "Tried to delete foreign object from database [%s]", n)
  197. try:
  198. sql = "DELETE FROM NODES WHERE ID = ?"
  199. self._cur.execute(sql, [n.get_id()])
  200. except sqlite.DatabaseError, e:
  201. raise DatabaseException("SQLite: %s" % (e))
  202. self._deletenodetags(n)
  203. self._checktags()
  204. self._commit()
  205. def listnodes(self):
  206. sql = ''
  207. params = []
  208. if len(self._filtertags) == 0:
  209. sql = "SELECT ID FROM NODES ORDER BY ID ASC"
  210. else:
  211. first = True
  212. for t in self._filtertags:
  213. if not first:
  214. sql += " INTERSECT "
  215. else:
  216. first = False
  217. sql += ("SELECT NODE FROM LOOKUP LEFT JOIN TAGS ON TAG = "
  218. " TAGS.ID WHERE TAGS.DATA = ? ")
  219. params.append(t.get_name())
  220. try:
  221. self._cur.execute(sql, params)
  222. ids = []
  223. row = self._cur.fetchone()
  224. while row is not None:
  225. ids.append(row[0])
  226. row = self._cur.fetchone()
  227. return ids
  228. except sqlite.DatabaseError, e:
  229. raise DatabaseException("SQLite: %s" % (e))
  230. def _commit(self):
  231. try:
  232. self._con.commit()
  233. except sqlite.DatabaseError, e:
  234. self._con.rollback()
  235. raise DatabaseException(
  236. "SQLite: Error commiting data to db [%s]" % (e))
  237. def _tagids(self, tags):
  238. ids = []
  239. for tag in tags:
  240. sql = "SELECT ID FROM TAGS WHERE DATA = ?"
  241. # if not isinstance(t, Tag): raise DatabaseException(
  242. # "Tried to insert foreign object into database [%s]", t)
  243. try:
  244. if isinstance(tag, str):
  245. self._cur.execute(sql, [tag])
  246. else:
  247. self._cur.execute(sql, [tag.get_name()])
  248. row = self._cur.fetchone()
  249. if (row is not None):
  250. ids.append(row[0])
  251. else:
  252. sql = "INSERT INTO TAGS(DATA) VALUES(?)"
  253. if isinstance(tag, str):
  254. self._cur.execute(sql, [tag])
  255. else:
  256. self._cur.execute(sql, [tag.get_name()])
  257. ids.append(self._cur.lastrowid)
  258. except sqlite.DatabaseError, e:
  259. raise DatabaseException("SQLite: %s" % (e))
  260. return ids
  261. def _deletenodetags(self, node):
  262. try:
  263. sql = "DELETE FROM LOOKUP WHERE NODE = ?"
  264. self._cur.execute(sql, [node.get_id()])
  265. except sqlite.DatabaseError, e:
  266. raise DatabaseException("SQLite: %s" % (e))
  267. self._commit()
  268. def _setnodetags(self, node):
  269. self._deletenodetags(node)
  270. ids = self._tagids(node.get_tags())
  271. for i in ids:
  272. sql = "INSERT OR REPLACE INTO LOOKUP VALUES(?, ?)"
  273. params = [node.get_id(), i]
  274. try:
  275. self._cur.execute(sql, params)
  276. except sqlite.DatabaseError, e:
  277. raise DatabaseException("SQLite: %s" % (e))
  278. self._commit()
  279. def _checktags(self):
  280. try:
  281. sql = "DELETE FROM TAGS WHERE ID NOT IN (SELECT TAG FROM" \
  282. + " LOOKUP GROUP BY TAG)"
  283. self._cur.execute(sql)
  284. except sqlite.DatabaseError, e:
  285. raise DatabaseException("SQLite: %s" % (e))
  286. self._commit()
  287. def _checktables(self):
  288. """
  289. Check if the Pwman tables exist.
  290. TODO: This method should check the version of the
  291. database. If it finds an old format it should
  292. exis, and prompt the user to convert the database
  293. to the new version with a designated script.
  294. """
  295. self._cur.execute("PRAGMA TABLE_INFO(NODES)")
  296. if (self._cur.fetchone() is None):
  297. # table doesn't exist, create it
  298. # SQLite does have constraints implemented at the moment
  299. # so datatype will just be a string
  300. self._cur.execute("CREATE TABLE NODES (ID INTEGER PRIMARY KEY"
  301. + " AUTOINCREMENT,DATA BLOB NOT NULL)")
  302. self._cur.execute("CREATE TABLE TAGS"
  303. + "(ID INTEGER PRIMARY KEY AUTOINCREMENT,"
  304. + "DATA BLOB NOT NULL UNIQUE)")
  305. self._cur.execute("CREATE TABLE LOOKUP"
  306. + "(NODE INTEGER NOT NULL, TAG INTEGER NOT NULL,"
  307. + " PRIMARY KEY(NODE, TAG))")
  308. self._cur.execute("CREATE TABLE KEY"
  309. + "(THEKEY TEXT NOT NULL DEFAULT '')")
  310. self._cur.execute("INSERT INTO KEY VALUES('')")
  311. # create a table to hold DB version info
  312. self._cur.execute("CREATE TABLE DBVERSION"
  313. + "(DBVERSION TEXT NOT NULL DEFAULT '0.4')")
  314. self._cur.execute("INSERT INTO DBVERSION VALUES('0.4')")
  315. try:
  316. self._con.commit()
  317. except DatabaseException, e:
  318. self._con.rollback()
  319. raise e
  320. def savekey(self, key):
  321. """
  322. This function is saving the key to table KEY.
  323. The key already arrives as an encrypted string.
  324. It is the same self._keycrypted from
  325. crypto py (check with id(self._keycrypted) and
  326. id(key) here.
  327. """
  328. sql = "UPDATE KEY SET THEKEY = ?"
  329. values = [key]
  330. self._cur.execute(sql, values)
  331. try:
  332. self._con.commit()
  333. except sqlite.DatabaseError, e:
  334. self._con.rollback()
  335. raise DatabaseException(
  336. "SQLite: Error saving key [%s]" % (e))
  337. def loadkey(self):
  338. """
  339. fetch the key to database. the key is also stored
  340. encrypted.
  341. """
  342. self._cur.execute("SELECT THEKEY FROM KEY")
  343. keyrow = self._cur.fetchone()
  344. if (keyrow[0] == ''):
  345. return None
  346. else:
  347. return keyrow[0]
  348. class SQLiteDatabase(Database):
  349. """SQLite Database implementation"""
  350. def __init__(self):
  351. """Initialise SQLitePwmanDatabase instance."""
  352. Database.__init__(self)
  353. try:
  354. self._filename = config.get_value('Database', 'filename')
  355. except KeyError, e:
  356. raise DatabaseException(
  357. "SQLite: missing parameter [%s]" % (e))
  358. def _open(self):
  359. try:
  360. self._con = sqlite.connect(self._filename)
  361. self._cur = self._con.cursor()
  362. self._checktables()
  363. except sqlite.DatabaseError, e:
  364. raise DatabaseException("SQLite: %s" % (e))
  365. def close(self):
  366. self._cur.close()
  367. self._con.close()
  368. def listtags(self, alltags=False):
  369. sql = ''
  370. params = []
  371. if len(self._filtertags) == 0 or alltags:
  372. sql = "SELECT DATA FROM TAGS ORDER BY DATA ASC"
  373. else:
  374. sql = ("SELECT TAGS.DATA FROM LOOKUP"
  375. + " INNER JOIN TAGS ON LOOKUP.TAG = TAGS.ID"
  376. + " WHERE NODE IN (")
  377. first = True
  378. # if using the command filter, the code crashes ...
  379. #
  380. for t in self._filtertags:
  381. if not first:
  382. sql += " INTERSECT "
  383. else:
  384. first = False
  385. sql += ("SELECT NODE FROM LOOKUP LEFT JOIN TAGS ON TAG " +
  386. + " = TAGS.ID "
  387. + " WHERE TAGS.DATA = ?")
  388. params.append(cPickle.dumps(t))
  389. sql += ") EXCEPT SELECT DATA FROM TAGS WHERE "
  390. first = True
  391. for t in self._filtertags:
  392. if not first:
  393. sql += " OR "
  394. else:
  395. first = False
  396. sql += "TAGS.DATA = ?"
  397. params.append(t)
  398. try:
  399. print params
  400. self._cur.execute(sql, params)
  401. tags = []
  402. row = self._cur.fetchone()
  403. while (row is not None):
  404. tag = cPickle.loads(str(row[0]))
  405. tags.append(tag)
  406. row = self._cur.fetchone()
  407. return tags
  408. except sqlite.DatabaseError, e:
  409. raise DatabaseException("SQLite: %s" % (e))
  410. def getnodes(self, ids):
  411. nodes = []
  412. for i in ids:
  413. sql = "SELECT DATA FROM NODES WHERE ID = ?"
  414. try:
  415. self._cur.execute(sql, [i])
  416. row = self._cur.fetchone()
  417. if row is not None:
  418. node = cPickle.loads(str(row[0]))
  419. node.set_id(i)
  420. nodes.append(node)
  421. except sqlite.DatabaseError, e:
  422. raise DatabaseException("SQLite: %s" % (e))
  423. return nodes
  424. def editnode(self, id, node):
  425. if not isinstance(node, Node):
  426. raise DatabaseException(
  427. "Tried to insert foreign object into database [%s]" % node)
  428. try:
  429. sql = "UPDATE NODES SET DATA = ? WHERE ID = ?"
  430. self._cur.execute(sql, [cPickle.dumps(node), id])
  431. except sqlite.DatabaseError, e:
  432. raise DatabaseException("SQLite: %s" % (e))
  433. self._setnodetags(node)
  434. self._checktags()
  435. self._commit()
  436. def addnodes(self, nodes):
  437. for n in nodes:
  438. sql = "INSERT INTO NODES(DATA) VALUES(?)"
  439. if not isinstance(n, Node):
  440. raise DatabaseException(
  441. "Tried to insert foreign object into database [%s]", n)
  442. value = cPickle.dumps(n)
  443. try:
  444. self._cur.execute(sql, [value])
  445. except sqlite.DatabaseError, e:
  446. raise DatabaseException("SQLite: %s" % (e))
  447. id = self._cur.lastrowid
  448. n.set_id(id)
  449. self._setnodetags(n)
  450. self._commit()
  451. def removenodes(self, nodes):
  452. for n in nodes:
  453. if not isinstance(n, Node):
  454. raise DatabaseException(
  455. "Tried to delete foreign object from database [%s]", n)
  456. try:
  457. sql = "DELETE FROM NODES WHERE ID = ?"
  458. self._cur.execute(sql, [n.get_id()])
  459. except sqlite.DatabaseError, e:
  460. raise DatabaseException("SQLite: %s" % (e))
  461. self._deletenodetags(n)
  462. self._checktags()
  463. self._commit()
  464. def listnodes(self):
  465. sql = ''
  466. params = []
  467. if len(self._filtertags) == 0:
  468. sql = "SELECT ID FROM NODES ORDER BY ID ASC"
  469. else:
  470. first = True
  471. for t in self._filtertags:
  472. if not first:
  473. sql += " INTERSECT "
  474. else:
  475. first = False
  476. sql += ("SELECT NODE FROM LOOKUP LEFT JOIN TAGS "
  477. + " ON TAG = TAGS.ID"
  478. + " WHERE TAGS.DATA = ? ")
  479. params.append(cPickle.dumps(t))
  480. try:
  481. self._cur.execute(sql, params)
  482. ids = []
  483. row = self._cur.fetchone()
  484. while (row is not None):
  485. ids.append(row[0])
  486. row = self._cur.fetchone()
  487. return ids
  488. except sqlite.DatabaseError, e:
  489. raise DatabaseException("SQLite: %s" % (e))
  490. def _commit(self):
  491. try:
  492. self._con.commit()
  493. except sqlite.DatabaseError, e:
  494. self._con.rollback()
  495. raise DatabaseException(
  496. "SQLite: Error commiting data to db [%s]" % (e))
  497. def _tagids(self, tags):
  498. ids = []
  499. for t in tags:
  500. sql = "SELECT ID FROM TAGS WHERE DATA = ?"
  501. if not isinstance(t, Tag):
  502. raise DatabaseException(
  503. "Tried to insert foreign object into database [%s]", t)
  504. data = cPickle.dumps(t)
  505. try:
  506. self._cur.execute(sql, [data])
  507. row = self._cur.fetchone()
  508. if (row is not None):
  509. ids.append(row[0])
  510. else:
  511. sql = "INSERT INTO TAGS(DATA) VALUES(?)"
  512. self._cur.execute(sql, [data])
  513. ids.append(self._cur.lastrowid)
  514. except sqlite.DatabaseError, e:
  515. raise DatabaseException("SQLite: %s" % (e))
  516. return ids
  517. def _deletenodetags(self, node):
  518. try:
  519. sql = "DELETE FROM LOOKUP WHERE NODE = ?"
  520. self._cur.execute(sql, [node.get_id()])
  521. except sqlite.DatabaseError, e:
  522. raise DatabaseException("SQLite: %s" % (e))
  523. self._commit()
  524. def _setnodetags(self, node):
  525. self._deletenodetags(node)
  526. ids = self._tagids(node.get_tags())
  527. for i in ids:
  528. sql = "INSERT OR REPLACE INTO LOOKUP VALUES(?, ?)"
  529. params = [node.get_id(), i]
  530. try:
  531. self._cur.execute(sql, params)
  532. except sqlite.DatabaseError, e:
  533. raise DatabaseException("SQLite: %s" % (e))
  534. self._commit()
  535. def _checktags(self):
  536. try:
  537. sql = "DELETE FROM TAGS WHERE ID NOT IN (SELECT TAG FROM " \
  538. + "LOOKUP GROUP BY TAG)"
  539. self._cur.execute(sql)
  540. except sqlite.DatabaseError, e:
  541. raise DatabaseException("SQLite: %s" % (e))
  542. self._commit()
  543. def _checktables(self):
  544. """ Check if the Pwman tables exist """
  545. self._cur.execute("PRAGMA TABLE_INFO(NODES)")
  546. if (self._cur.fetchone() is None):
  547. # table doesn't exist, create it
  548. # SQLite does have constraints implemented at the moment
  549. # so datatype will just be a string
  550. self._cur.execute("CREATE TABLE NODES "
  551. "(ID INTEGER PRIMARY KEY AUTOINCREMENT,"
  552. "DATA BLOB NOT NULL)")
  553. self._cur.execute("CREATE TABLE TAGS "
  554. "(ID INTEGER PRIMARY KEY AUTOINCREMENT,"
  555. "DATA BLOB NOT NULL UNIQUE)")
  556. self._cur.execute("CREATE TABLE LOOKUP "
  557. "(NODE INTEGER NOT NULL, TAG INTEGER NOT NULL,"
  558. " PRIMARY KEY(NODE, TAG))")
  559. self._cur.execute("CREATE TABLE KEY "
  560. + "(THEKEY TEXT NOT NULL DEFAULT '')")
  561. self._cur.execute("INSERT INTO KEY VALUES('')")
  562. try:
  563. self._con.commit()
  564. except DatabaseException, e:
  565. self._con.rollback()
  566. raise e
  567. def savekey(self, key):
  568. """
  569. This function is saving the key to table KEY.
  570. The key already arrives as an encrypted string.
  571. It is the same self._keycrypted from
  572. crypto py (check with id(self._keycrypted) and
  573. id(key) here.
  574. """
  575. sql = "UPDATE KEY SET THEKEY = ?"
  576. values = [key]
  577. self._cur.execute(sql, values)
  578. try:
  579. self._con.commit()
  580. except sqlite.DatabaseError, e:
  581. self._con.rollback()
  582. raise DatabaseException(
  583. "SQLite: Error saving key [%s]" % (e))
  584. def loadkey(self):
  585. """
  586. fetch the key to database. the key is also stored
  587. encrypted.
  588. """
  589. self._cur.execute("SELECT THEKEY FROM KEY")
  590. keyrow = self._cur.fetchone()
  591. if (keyrow[0] == ''):
  592. return None
  593. else:
  594. return keyrow[0]