root / pykota / trunk / pykota / storages / pgstorage.py @ 3294

Revision 3294, 6.1 kB (checked in by jerome, 16 years ago)

Added modules to store utility functions and application
intialization code, which has nothing to do in classes.
Modified tool.py accordingly (far from being finished)
Use these new modules where necessary.
Now converts all command line arguments to unicode before
beginning to work. Added a proper logging method for already
encoded query strings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: UTF-8 -*-
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003, 2004, 2005, 2006, 2007, 2008 Jerome Alet <alet@librelogiciel.com>
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21#
22
23"""This module defines a class to access to a PostgreSQL database backend."""
24
25import time
26from types import StringType
27
28from pykota.errors import PyKotaStorageError
29from pykota.storage import BaseStorage
30from pykota.storages.sql import SQLStorage
31
32from pykota.utils import *                           
33
34try :
35    import pg
36except ImportError :   
37    import sys
38    # TODO : to translate or not to translate ?
39    raise PyKotaStorageError, "This python version (%s) doesn't seem to have the PygreSQL module installed correctly." % sys.version.split()[0]
40else :   
41    try :
42        PGError = pg.Error
43    except AttributeError :   
44        PGError = pg.error
45
46class Storage(BaseStorage, SQLStorage) :
47    def __init__(self, pykotatool, host, dbname, user, passwd) :
48        """Opens the PostgreSQL database connection."""
49        BaseStorage.__init__(self, pykotatool)
50        try :
51            (host, port) = host.split(":")
52            port = int(port)
53        except ValueError :   
54            port = 5432         # Use PostgreSQL's default tcp/ip port (5432).
55       
56        self.tool.logdebug("Trying to open database (host=%s, port=%s, dbname=%s, user=%s)..." % (host, port, dbname, user))
57        try :
58            self.database = pg.connect(host=host, port=port, dbname=dbname, user=user, passwd=passwd)
59        except PGError, msg :   
60            msg = "%(msg)s --- the most probable cause of your problem is that PostgreSQL is down, or doesn't accept incoming connections because you didn't configure it as explained in PyKota's documentation." % locals()
61            raise PGError, msg
62        self.closed = 0
63        try :
64            self.database.query("SET CLIENT_ENCODING TO 'UTF-8';")
65        except PGError, msg :   
66            self.tool.logdebug("Impossible to set database client encoding to UTF-8 : %s" % msg)
67        self.tool.logdebug("Database opened (host=%s, port=%s, dbname=%s, user=%s)" % (host, port, dbname, user))
68           
69    def close(self) :   
70        """Closes the database connection."""
71        if not self.closed :
72            self.database.close()
73            self.closed = 1
74            self.tool.logdebug("Database closed.")
75       
76    def beginTransaction(self) :   
77        """Starts a transaction."""
78        self.before = time.time()
79        self.database.query("BEGIN;")
80        self.tool.logdebug("Transaction begins...")
81       
82    def commitTransaction(self) :   
83        """Commits a transaction."""
84        self.database.query("COMMIT;")
85        after = time.time()
86        self.tool.logdebug("Transaction committed.")
87        #self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))
88       
89    def rollbackTransaction(self) :     
90        """Rollbacks a transaction."""
91        self.database.query("ROLLBACK;")
92        after = time.time()
93        self.tool.logdebug("Transaction aborted.")
94        #self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))
95       
96    def doRawSearch(self, query) :
97        """Does a raw search query."""
98        query = query.strip()   
99        if not query.endswith(';') :   
100            query += ';'
101        try :
102            before = time.time()
103            self.querydebug("QUERY : %s" % query)
104            result = self.database.query(query)
105        except PGError, msg :   
106            raise PyKotaStorageError, str(msg)
107        else :   
108            after = time.time()
109            #self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
110            return result
111           
112    def doSearch(self, query) :       
113        """Does a search query."""
114        result = self.doRawSearch(query)
115        if (result is not None) and (result.ntuples() > 0) : 
116            return result.dictresult()
117       
118    def doModify(self, query) :
119        """Does a (possibly multiple) modify query."""
120        query = query.strip()   
121        if not query.endswith(';') :   
122            query += ';'
123        try :
124            before = time.time()
125            self.querydebug("QUERY : %s" % query)
126            result = self.database.query(query)
127        except PGError, msg :   
128            self.tool.logdebug("Query failed : %s" % repr(msg))
129            raise PyKotaStorageError, str(msg)
130        else :   
131            after = time.time()
132            #self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
133            return result
134           
135    def doQuote(self, field) :
136        """Quotes a field for use as a string in SQL queries."""
137        if type(field) == type(0.0) : 
138            typ = "decimal"
139        elif type(field) == type(0) :   
140            typ = "int"
141        elif type(field) == type(0L) :   
142            typ = "int"
143        else :   
144            typ = "text"
145        return pg._quote(field, typ)
146       
147    def prepareRawResult(self, result) :
148        """Prepares a raw result by including the headers."""
149        if result.ntuples() > 0 :
150            entries = [result.listfields()]
151            entries.extend(result.getresult())
152            nbfields = len(entries[0])
153            for i in range(1, len(entries)) :
154                fields = list(entries[i])
155                for j in range(nbfields) :
156                    field = fields[j]
157                    if type(field) == StringType :
158                        fields[j] = databaseToUnicode(field) 
159                entries[i] = tuple(fields)   
160            return entries
161       
Note: See TracBrowser for help on using the browser.