1 ##############################################################################
3 # Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 # $Id: pooler.py 1310 2005-09-08 20:40:15Z pinky $
7 # WARNING: This program as such is intended to be used by professional
8 # programmers who take the whole responsability of assessing all potential
9 # consequences resulting from its eventual inadequacies and bugs
10 # End users who are looking for a ready-to-use solution with commercial
11 # garantees and support are strongly adviced to contract a Free Software
14 # This program is Free Software; you can redistribute it and/or
15 # modify it under the terms of the GNU General Public License
16 # as published by the Free Software Foundation; either version 2
17 # of the License, or (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 ##############################################################################
37 # from tools import decimal
42 from mx import DateTime as mdt
43 re_from = re.compile('.* from ([a-zA-Z_0-9]+) .*$');
44 re_into = re.compile('.* into ([a-zA-Z_0-9]+) .*$');
54 def __init__(self, db, con, dbname):
56 self.obj = db.cursor()
60 def execute_not_run(self,*args):
61 #if not fake_cursor.nbr % 1:
62 # print 'sql: ',fake_cursor.nbr, args
63 res = re.match('^select.* from ([a-zA-Z_]+) .*$', args[0], re.I)
65 fake_cursor._tables.setdefault(res.group(1), 0)
66 fake_cursor._tables[res.group(1)] += 1
70 # print 'sql: ',fake_cursor.nbr, args[0], args[1]
72 # print 'sql: ',fake_cursor.nbr, args[0]
74 #if not fake_cursor.nbr % 5000:
76 # for t,c in fake_cursor._tables.items():
80 # print 'After %d queries' % (fake_cursor.nbr,)
81 # for line in ct[:50]:
82 # print ' %s: %d' % (line[1], line[0])
85 # print 'sql: ',fake_cursor.nbr, args[0], args[1]
87 # print 'sql: ',fake_cursor.nbr, args[0]
90 return self.obj.execute(*args)
92 def execute(self, sql, params=None):
96 if isinstance(s, unicode):
97 return s.encode('utf-8')
99 p=map(base_string, params)
100 if isinstance(sql, unicode):
101 sql = sql.encode('utf-8')
105 res = self.obj.execute(sql, p)
107 res = self.obj.execute(sql)
110 res_from = re_from.match(sql.lower())
112 self.sql_from_log.setdefault(res_from.group(1), [0, 0])
113 self.sql_from_log[res_from.group(1)][0] += 1
114 self.sql_from_log[res_from.group(1)][1] += mdt.now() - now
115 res_into = re_into.match(sql.lower())
117 self.sql_into_log.setdefault(res_into.group(1), [0, 0])
118 self.sql_into_log[res_into.group(1)][0] += 1
119 self.sql_into_log[res_into.group(1)][1] += mdt.now() - now
122 def print_log(self, type='from'):
123 print "SQL LOG %s:" % (type,)
125 logs = self.sql_from_log.items()
127 logs = self.sql_into_log.items()
128 logs.sort(lambda x, y: cmp(x[1][1], y[1][1]))
131 print "table:", r[0], ":", str(r[1][1]), "/", r[1][0]
133 print "SUM:%s/%d"% (sum, self.count)
137 self.print_log('from')
138 self.print_log('into')
141 # This force the cursor to be freed, and thus, available again. It is
142 # important because otherwise we can overload the server very easily
143 # because of a cursor shortage (because cursors are not garbage
144 # collected as fast as they should). The problem is probably due in
145 # part because browse records keep a reference to the cursor.
148 def __getattr__(self, name):
149 return getattr(self.obj, name)
152 def __init__(self, truedb, dbname):
157 return fake_cursor(self.truedb, {}, self.dbname)
159 def decimalize(symb):
160 if symb is None: return None
161 if isinstance(symb, float):
162 return decimal.Decimal('%f' % symb)
163 return decimal.Decimal(symb)
165 def db_connect(db_name):
166 host = tools.config['db_host'] and "host=%s" % tools.config['db_host'] or ''
167 port = tools.config['db_port'] and "port=%s" % tools.config['db_port'] or ''
168 name = "dbname=%s" % db_name
169 user = tools.config['db_user'] and "user=%s" % tools.config['db_user'] or ''
170 password = tools.config['db_password'] and "password=%s" % tools.config['db_password'] or ''
171 maxconn = int(tools.config['db_maxconn']) or 64
172 tdb = psycopg.connect('%s %s %s %s %s' % (host, port, name, user, password), serialize=0, maxconn=maxconn)
173 fdb = fakedb(tdb, db_name)
177 #define DATEOID 1082, define TIMESTAMPOID 1114 see pgtypes.h
178 psycopg.register_type(psycopg.new_type((1082,), "date", lambda x:x))
179 psycopg.register_type(psycopg.new_type((1083,), "time", lambda x:x))
180 psycopg.register_type(psycopg.new_type((1114,), "datetime", lambda x:x))
181 #psycopg.register_type(psycopg.new_type((700, 701, 1700), 'decimal', decimalize))
183 psycopg.register_type(psycopg.new_type((1082,), "date", lambda x:x))
184 psycopg.register_type(psycopg.new_type((1083,), "time", lambda x:x))
185 psycopg.register_type(psycopg.new_type((1114,), "datetime", lambda x:x))