|
@@ -1,24 +1,23 @@
|
|
|
-#============================================================================
|
|
|
+# ============================================================================
|
|
|
# This file is part of Pwman3.
|
|
|
-#
|
|
|
+#
|
|
|
# Pwman3 is free software; you can redistribute it and/or modify
|
|
|
# it under the terms of the GNU General Public License, version 2
|
|
|
-# as published by the Free Software Foundation;
|
|
|
-#
|
|
|
+# as published by the Free Software Foundation;
|
|
|
+#
|
|
|
# Pwman3 is distributed in the hope that it will be useful,
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
# GNU General Public License for more details.
|
|
|
-#
|
|
|
+#
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
# along with Pwman3; if not, write to the Free Software
|
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
-#============================================================================
|
|
|
+# ============================================================================
|
|
|
# Copyright (C) 2012 Oz Nahum <nahumoz@gmail.com>
|
|
|
-#============================================================================
|
|
|
-#============================================================================
|
|
|
+# ============================================================================
|
|
|
# Copyright (C) 2006 Ivan Kelly <ivan@ivankelly.net>
|
|
|
-#============================================================================
|
|
|
+# ============================================================================
|
|
|
|
|
|
"""Postgresql Database implementation."""
|
|
|
from pwman.data.database import Database, DatabaseException
|
|
@@ -29,19 +28,20 @@ import pgdb
|
|
|
import pwman.util.config as config
|
|
|
import cPickle
|
|
|
|
|
|
+
|
|
|
class PostgresqlDatabase(Database):
|
|
|
"""Postgresql Database implementation"""
|
|
|
-
|
|
|
+
|
|
|
def __init__(self):
|
|
|
"""Initialise PostgresqlDatabase instance."""
|
|
|
Database.__init__(self)
|
|
|
|
|
|
self._tagidcache = {}
|
|
|
-
|
|
|
- config.add_defaults({"Database" : {"server": "localhost",
|
|
|
- "port" : "5432",
|
|
|
- "database" : "pwman",
|
|
|
- "table_prefix" : "pwman_"}})
|
|
|
+
|
|
|
+ config.add_defaults({"Database": {"server": "localhost",
|
|
|
+ "port": "5432",
|
|
|
+ "database": "pwman",
|
|
|
+ "table_prefix": "pwman_"}})
|
|
|
try:
|
|
|
self._server = config.get_value('Database', 'server')
|
|
|
self._port = config.get_value('Database', 'port')
|
|
@@ -68,15 +68,15 @@ class PostgresqlDatabase(Database):
|
|
|
|
|
|
def _get_cur(self):
|
|
|
try:
|
|
|
- if (self._con != None):
|
|
|
+ if self._con is not None:
|
|
|
return self._con.cursor()
|
|
|
- except pgdb.DatabaseError as e:
|
|
|
+ except pgdb.DatabaseError:
|
|
|
pass
|
|
|
server = "%s:%s" % (self._server, self._port)
|
|
|
- self._con = pgdb.connect(host = server,
|
|
|
- database = self._database,
|
|
|
- user = self._user,
|
|
|
- password = self._password)
|
|
|
+ self._con = pgdb.connect(host=server,
|
|
|
+ database=self._database,
|
|
|
+ user=self._user,
|
|
|
+ password=self._password)
|
|
|
self._cur = self._con.cursor()
|
|
|
return self._cur
|
|
|
|
|
@@ -92,9 +92,10 @@ class PostgresqlDatabase(Database):
|
|
|
sql = "SELECT DATA FROM %sTAGS ORDER BY DATA ASC" % (self._prefix)
|
|
|
else:
|
|
|
sql = ("SELECT %sTAGS.DATA FROM %sLOOKUP"
|
|
|
- +" INNER JOIN %sTAGS ON %sLOOKUP.TAG = %sTAGS.ID"
|
|
|
- +" WHERE NODE IN (") % (self._prefix, self._prefix, self._prefix,
|
|
|
- self._prefix, self._prefix)
|
|
|
+ + " INNER JOIN %sTAGS ON %sLOOKUP.TAG = %sTAGS.ID"
|
|
|
+ + " WHERE NODE IN (") % (self._prefix, self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ self._prefix, self._prefix)
|
|
|
first = True
|
|
|
|
|
|
i += 1
|
|
@@ -104,13 +105,16 @@ class PostgresqlDatabase(Database):
|
|
|
sql += " INTERSECT "
|
|
|
else:
|
|
|
first = False
|
|
|
-
|
|
|
- sql += ("SELECT NODE FROM %sLOOKUP LEFT JOIN %sTAGS ON TAG = %sTAGS.ID "
|
|
|
- + " WHERE %sTAGS.DATA = %%(%s)s") % (self._prefix, self._prefix,
|
|
|
- self._prefix, self._prefix,
|
|
|
- paramname)
|
|
|
+
|
|
|
+ sql += ("SELECT NODE FROM %sLOOKUP LEFT JOIN %sTAGS ON TAG "
|
|
|
+ "= %sTAGS.ID "
|
|
|
+ " WHERE %sTAGS.DATA = %%(%s)s" % (self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ paramname))
|
|
|
params[paramname] = cPickle.dumps(t)
|
|
|
- sql += ") EXCEPT SELECT DATA FROM %sTAGS WHERE " %(self._prefix)
|
|
|
+ sql += ") EXCEPT SELECT DATA FROM %sTAGS WHERE " % self._prefix
|
|
|
first = True
|
|
|
for t in self._filtertags:
|
|
|
if not first:
|
|
@@ -124,14 +128,14 @@ class PostgresqlDatabase(Database):
|
|
|
|
|
|
tags = []
|
|
|
row = cursor.fetchone()
|
|
|
- while (row != None):
|
|
|
+ while row:
|
|
|
tag = cPickle.loads(str(row[0]))
|
|
|
tags.append(tag)
|
|
|
row = cursor.fetchone()
|
|
|
return tags
|
|
|
except pgdb.DatabaseError as e:
|
|
|
raise DatabaseException("Postgresql: %s" % (e))
|
|
|
-
|
|
|
+
|
|
|
def getnodes(self, ids):
|
|
|
nodes = []
|
|
|
idstr = ""
|
|
@@ -145,15 +149,15 @@ class PostgresqlDatabase(Database):
|
|
|
first = False
|
|
|
else:
|
|
|
idstr += ", %d" % (i)
|
|
|
-
|
|
|
- sql = "SELECT ID,DATA FROM %sNODES WHERE ID IN (%s)" % (self._prefix,
|
|
|
- pgdb.escape_string(idstr))
|
|
|
+
|
|
|
+ sql = ("SELECT ID,DATA FROM %sNODES WHERE ID IN (%s)"
|
|
|
+ "" % (self._prefix, pgdb.escape_string(idstr)))
|
|
|
try:
|
|
|
cursor = self._get_cur()
|
|
|
cursor.execute(sql)
|
|
|
-
|
|
|
+
|
|
|
row = cursor.fetchone()
|
|
|
- while row != None:
|
|
|
+ while row:
|
|
|
node = cPickle.loads(str(row[1]))
|
|
|
node.set_id(row[0])
|
|
|
nodes.append(node)
|
|
@@ -163,14 +167,16 @@ class PostgresqlDatabase(Database):
|
|
|
return nodes
|
|
|
|
|
|
def editnode(self, id, node):
|
|
|
- if not isinstance(node, Node): raise DatabaseException(
|
|
|
- "Tried to insert foreign object into database [%s]" % node)
|
|
|
+ if not isinstance(node, Node):
|
|
|
+ raise DatabaseException("Tried to insert foreign object into "
|
|
|
+ "database [%s]" % node)
|
|
|
try:
|
|
|
cursor = self._get_cur()
|
|
|
- sql = "UPDATE %sNODES SET DATA = %%(data)s WHERE ID = %%(id)d" % (self._prefix)
|
|
|
- cursor.execute(sql, {"data":cPickle.dumps(node),
|
|
|
+ sql = ("UPDATE %sNODES SET DATA = %%(data)s WHERE ID = %%(id)d"
|
|
|
+ "" % (self._prefix))
|
|
|
+ cursor.execute(sql, {"data": cPickle.dumps(node),
|
|
|
"id": id})
|
|
|
-
|
|
|
+
|
|
|
except pgdb.DatabaseError as e:
|
|
|
raise DatabaseException("Postgresql: %s" % (e))
|
|
|
self._setnodetags(node)
|
|
@@ -181,8 +187,9 @@ class PostgresqlDatabase(Database):
|
|
|
cursor = self._get_cur()
|
|
|
for n in nodes:
|
|
|
sql = "INSERT INTO %sNODES(DATA) VALUES(%%(data)s)" % (self._prefix)
|
|
|
- if not isinstance(n, Node): raise DatabaseException(
|
|
|
- "Tried to insert foreign object into database [%s]", n)
|
|
|
+ if not isinstance(n, Node):
|
|
|
+ raise DatabaseException("Tried to insert foreign object into "
|
|
|
+ "database [%s]", n)
|
|
|
values = {"data": cPickle.dumps(n)}
|
|
|
try:
|
|
|
cursor.execute(sql, values)
|
|
@@ -193,16 +200,17 @@ class PostgresqlDatabase(Database):
|
|
|
|
|
|
self._setnodetags(n)
|
|
|
self._commit()
|
|
|
-
|
|
|
+
|
|
|
def removenodes(self, nodes):
|
|
|
cursor = self._get_cur()
|
|
|
for n in nodes:
|
|
|
- if not isinstance(n, Node): raise DatabaseException(
|
|
|
- "Tried to delete foreign object from database [%s]", n)
|
|
|
+ if not isinstance(n, Node):
|
|
|
+ raise DatabaseException("Tried to delete foreign object"
|
|
|
+ "from database [%s]", n)
|
|
|
try:
|
|
|
sql = "DELETE FROM %sNODES WHERE ID = %%(id)d" % (self._prefix)
|
|
|
cursor.execute(sql, {"id": n.get_id()})
|
|
|
-
|
|
|
+
|
|
|
except pgdb.DatabaseError as e:
|
|
|
raise DatabaseException("Postgresql: %s" % (e))
|
|
|
self._deletenodetags(n)
|
|
@@ -227,17 +235,20 @@ class PostgresqlDatabase(Database):
|
|
|
i += 1
|
|
|
paramname = "tag%d" % (i)
|
|
|
|
|
|
- sql += (("SELECT NODE FROM %sLOOKUP LEFT JOIN %sTAGS ON TAG = %sTAGS.ID"
|
|
|
- + " WHERE %sTAGS.DATA = %%(%s)s ") % (self._prefix, self._prefix,
|
|
|
- self._prefix, self._prefix,
|
|
|
- paramname))
|
|
|
+ sql += (("SELECT NODE FROM %sLOOKUP LEFT JOIN %sTAGS ON"
|
|
|
+ " TAG = %sTAGS.ID"
|
|
|
+ " WHERE %sTAGS.DATA = %%(%s)s ") % (self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ self._prefix,
|
|
|
+ paramname))
|
|
|
params[paramname] = cPickle.dumps(t)
|
|
|
try:
|
|
|
cursor.execute(sql, params)
|
|
|
|
|
|
ids = []
|
|
|
row = cursor.fetchone()
|
|
|
- while (row != None):
|
|
|
+ while row:
|
|
|
ids.append(row[0])
|
|
|
row = cursor.fetchone()
|
|
|
return ids
|
|
@@ -261,20 +272,22 @@ class PostgresqlDatabase(Database):
|
|
|
ids.append(self._tagidcache[pickled])
|
|
|
continue
|
|
|
except KeyError as e:
|
|
|
- pass # not in cache
|
|
|
+ pass # not in cache
|
|
|
sql = "SELECT ID FROM %sTAGS WHERE DATA = %%(tag)s" % (self._prefix)
|
|
|
- if not isinstance(t, Tag): raise DatabaseException(
|
|
|
- "Tried to insert foreign object into database [%s]", t)
|
|
|
- data = {"tag" : pickled }
|
|
|
-
|
|
|
+ if not isinstance(t, Tag):
|
|
|
+ raise DatabaseException("Tried to insert foreign object"
|
|
|
+ " into database [%s]", t)
|
|
|
+ data = {"tag": pickled}
|
|
|
+
|
|
|
try:
|
|
|
cursor.execute(sql, data)
|
|
|
row = cursor.fetchone()
|
|
|
- if (row != None):
|
|
|
+ if row:
|
|
|
ids.append(row[0])
|
|
|
self._tagidcache[pickled] = row[0]
|
|
|
else:
|
|
|
- sql = "INSERT INTO %sTAGS(DATA) VALUES(%%(tag)s)" % (self._prefix)
|
|
|
+ sql = "INSERT INTO %sTAGS(DATA) VALUES(%%(tag)s)" % (
|
|
|
+ self._prefix)
|
|
|
cursor.execute(sql, data)
|
|
|
id = self._lastrowid("TAGS")
|
|
|
ids.append(id)
|
|
@@ -287,19 +300,20 @@ class PostgresqlDatabase(Database):
|
|
|
try:
|
|
|
cursor = self._get_cur()
|
|
|
sql = "DELETE FROM %sLOOKUP WHERE NODE = %%(node)d" % (self._prefix)
|
|
|
- cursor.execute(sql, {"node":node.get_id()})
|
|
|
-
|
|
|
+ cursor.execute(sql, {"node": node.get_id()})
|
|
|
+
|
|
|
except pgdb.DatabaseError as e:
|
|
|
raise DatabaseException("Postgresql: %s" % (e))
|
|
|
-
|
|
|
+
|
|
|
def _setnodetags(self, node):
|
|
|
self._deletenodetags(node)
|
|
|
ids = self._tagids(node.get_tags())
|
|
|
-
|
|
|
+
|
|
|
for i in ids:
|
|
|
- sql = "INSERT INTO %sLOOKUP VALUES(%%(node)d, %%(tag)d)" % (self._prefix)
|
|
|
+ sql = "INSERT INTO %sLOOKUP VALUES(%%(node)d, %%(tag)d)" % (
|
|
|
+ self._prefix)
|
|
|
params = {"node": node.get_id(), "tag": i}
|
|
|
-
|
|
|
+
|
|
|
try:
|
|
|
cursor = self._get_cur()
|
|
|
cursor.execute(sql, params)
|
|
@@ -320,39 +334,37 @@ class PostgresqlDatabase(Database):
|
|
|
|
|
|
def _lastrowid(self, name):
|
|
|
cursor = self._get_cur()
|
|
|
- cursor.execute("SELECT LAST_VALUE FROM %s%s_ID_SEQ" % (self._prefix, name))
|
|
|
+ cursor.execute("SELECT LAST_VALUE FROM %s%s_ID_SEQ" % (self._prefix,
|
|
|
+ name))
|
|
|
row = cursor.fetchone()
|
|
|
- if row == None:
|
|
|
- return 0;
|
|
|
+ if not row:
|
|
|
+ return 0
|
|
|
else:
|
|
|
return row[0]
|
|
|
-
|
|
|
+
|
|
|
def _checktables(self):
|
|
|
""" Check if the Pwman tables exist """
|
|
|
cursor = self._get_cur()
|
|
|
- cursor.execute(
|
|
|
- "SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '%snodes'"
|
|
|
- % (self._prefix))
|
|
|
+ cursor.execute("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE "
|
|
|
+ "TABLE_NAME = '%snodes'" % (self._prefix))
|
|
|
|
|
|
- if (cursor.fetchone() == None):
|
|
|
+ if not cursor.fetchone():
|
|
|
# table doesn't exist, create it
|
|
|
- cursor.execute(("CREATE TABLE %sNODES"
|
|
|
- +"(ID SERIAL PRIMARY KEY, DATA TEXT NOT NULL)")
|
|
|
- % (self._prefix))
|
|
|
+ cursor.execute(("CREATE TABLE %sNODES "
|
|
|
+ "(ID SERIAL PRIMARY KEY, DATA TEXT NOT NULL)"
|
|
|
+ % (self._prefix)))
|
|
|
cursor.execute(("CREATE TABLE %sTAGS"
|
|
|
- + "(ID SERIAL PRIMARY KEY,"
|
|
|
- + "DATA TEXT NOT NULL UNIQUE)")
|
|
|
- % (self._prefix))
|
|
|
+ "(ID SERIAL PRIMARY KEY,"
|
|
|
+ "DATA TEXT NOT NULL UNIQUE)") % (self._prefix))
|
|
|
cursor.execute(("CREATE TABLE %sLOOKUP"
|
|
|
- + "(NODE INTEGER NOT NULL, TAG INTEGER NOT NULL,"
|
|
|
- + " PRIMARY KEY(NODE, TAG))")
|
|
|
- % (self._prefix))
|
|
|
+ "(NODE INTEGER NOT NULL, TAG INTEGER NOT NULL,"
|
|
|
+ " PRIMARY KEY(NODE, TAG))") % self._prefix)
|
|
|
|
|
|
cursor.execute(("CREATE TABLE %sKEY"
|
|
|
- + "(THEKEY TEXT NOT NULL DEFAULT '')")
|
|
|
- % (self._prefix));
|
|
|
- cursor.execute("INSERT INTO %sKEY VALUES('')" % (self._prefix));
|
|
|
-
|
|
|
+ + "(THEKEY TEXT NOT NULL DEFAULT '')")
|
|
|
+ % (self._prefix))
|
|
|
+ cursor.execute("INSERT INTO %sKEY VALUES('')" % (self._prefix))
|
|
|
+
|
|
|
try:
|
|
|
self._con.commit()
|
|
|
except pgdb.DatabaseError as e:
|
|
@@ -370,11 +382,10 @@ class PostgresqlDatabase(Database):
|
|
|
self._con.rollback()
|
|
|
raise DatabaseException(
|
|
|
"Postgresql: Error saving key [%s]" % (e))
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
def loadkey(self):
|
|
|
cursor = self._get_cur()
|
|
|
- cursor.execute("SELECT THEKEY FROM %sKEY" % (self._prefix));
|
|
|
+ cursor.execute("SELECT THEKEY FROM %sKEY" % (self._prefix))
|
|
|
keyrow = cursor.fetchone()
|
|
|
if (keyrow[0] == ''):
|
|
|
return None
|