PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/sagator-1.2.3/db.py

#
Python | 313 lines | 291 code | 4 blank | 18 comment | 20 complexity | 1c6778d23731aad7b4bab9cb3ffd948a MD5 | raw file
Possible License(s): GPL-2.0
  1. '''
  2. db.py - Database connection module.
  3. (c) 2005-2009 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. '''
  9. from avlib import debug, safe
  10. import sys, time, re
  11. classes = ['MySQLdb', 'sqlite', 'pg', 'pgdb', 'psycopg']
  12. class dbconn:
  13. name='connection_template'
  14. params=('host','port','dbname','dbuser','dbpasswd')
  15. next_refresh = 0
  16. refresh_time = 60 # 60 seconds
  17. def __init__(self,db=None,params=[]):
  18. self.DB = db
  19. self.PARAMS = params
  20. self.IntegrityError = db.IntegrityError
  21. def __del__(self):
  22. self.close()
  23. def refresh(self):
  24. t0 = time.time()
  25. if t0>=self.next_refresh:
  26. debug.echo(6, "%s: Database connection refresh" % self.name)
  27. self.close()
  28. self.connect()
  29. self.next_refresh = t0+self.refresh_time
  30. def execute(self, sql_cmd, sql_args=[], commit=True):
  31. if self.DB.paramstyle=='qmark':
  32. sql_cmd = sql_cmd.replace("%s", "?")
  33. # try to replace pyformat
  34. if type(sql_args)==type({}):
  35. reg_subst = re.compile('%\((.+?)\)s')
  36. r = reg_subst.search(sql_cmd)
  37. if r:
  38. sql_args = tuple([
  39. sql_args.get(x)
  40. for x in re.compile('%\((.+?)\)s').findall(sql_cmd)
  41. ])
  42. sql_cmd = reg_subst.sub('?', sql_cmd)
  43. debug.echo(9, sql_cmd, " ", [sql_args])
  44. try:
  45. cur=self.DBC.cursor()
  46. if sql_args==[]:
  47. cur.execute(sql_cmd)
  48. else:
  49. cur.execute(sql_cmd, sql_args)
  50. except:
  51. self.connect()
  52. cur=self.DBC.cursor()
  53. if sql_args==[]:
  54. cur.execute(sql_cmd)
  55. else:
  56. cur.execute(sql_cmd, sql_args)
  57. self.rowcount=cur.rowcount
  58. if commit:
  59. self.DBC.commit()
  60. return cur
  61. def execute_cycle(self, sql_cmd, sql_args=[], commit=True, times=5):
  62. for counter in range(times):
  63. try:
  64. return self.execute(sql_cmd, sql_args, commit)
  65. except self.IntegrityError:
  66. raise
  67. except Exception, es:
  68. debug.traceback(9, "db connection:")
  69. time.sleep(0.1*counter)
  70. raise
  71. def query(self, sql_cmd, sql_args=[]):
  72. r = self.execute(sql_cmd, sql_args, False).fetchall()
  73. # simulate rowcount, if it's not implemented in DB API
  74. if self.rowcount<0:
  75. self.rowcount = len(r)
  76. return r
  77. def commit(self):
  78. try:
  79. self.DBC.commit()
  80. except AttributeError:
  81. pass # self.DBC is not defined
  82. def quote(self, s):
  83. return s.replace("'", "''").replace('\\', '\\\\')
  84. def close(self):
  85. try:
  86. self.DBC.commit()
  87. except:
  88. pass
  89. try:
  90. self.DBC.close()
  91. except:
  92. pass
  93. class MySQLdb(dbconn):
  94. '''
  95. MySQL database connection.
  96. Requires: MySQLdb python module
  97. Usage: db.MySQLdb(host='127.0.0.1',port=3306,dbname='sagator',
  98. dbuser='sagator',dbpasswd='xxxxxx')
  99. Parameters:
  100. host - database server hostname or unix socket path
  101. port - tcp socket port for database server
  102. dbname - database name
  103. dbuser - authorization username
  104. dbpasswd - authorization password
  105. Database creation script: scripts/db/mysql.sh
  106. '''
  107. name='MySQLdb'
  108. params=('host','port','dbname','dbuser','dbpasswd')
  109. def __init__(self,*args,**kwargs):
  110. try:
  111. import MySQLdb, encodings.latin_1, encodings.utf_8
  112. except ImportError,es:
  113. sys.exit("Error importing MySQLdb module for python: "+str(es))
  114. if args:
  115. dbconn.__init__(self,MySQLdb,args[0])
  116. else:
  117. dbconn.__init__(self,MySQLdb,kwargs)
  118. # load required modules only
  119. try: self.connect()
  120. except: pass
  121. def connect(self):
  122. if self.PARAMS.get('host')[0]=='/':
  123. self.DBC=self.DB.connect(
  124. unix_socket=self.PARAMS.get('host'),
  125. db=self.PARAMS.get('dbname'),
  126. user=self.PARAMS.get('dbuser'),
  127. passwd=self.PARAMS.get('dbpasswd'),
  128. connect_timeout=5,
  129. charset=self.PARAMS.get('charset', 'utf8')
  130. )
  131. else:
  132. self.DBC=self.DB.connect(
  133. host=self.PARAMS.get('host'),
  134. port=self.PARAMS.get('port'),
  135. db=self.PARAMS.get('dbname'),
  136. user=self.PARAMS.get('dbuser'),
  137. passwd=self.PARAMS.get('dbpasswd'),
  138. connect_timeout=5,
  139. charset=self.PARAMS.get('charset', 'utf8')
  140. )
  141. def quote(self,s):
  142. return self.DB.escape_string(s)
  143. class sqlite(dbconn):
  144. '''
  145. SQLite database conenction.
  146. Requires: sqlite python module
  147. Usage: db.sqlite(dbname='/var/lib/sagator/sqlitedb')
  148. Parameters:
  149. dbname - database name
  150. Database creation script: scripts/db/sqlite.sh
  151. '''
  152. name='sqlite'
  153. params=('dbname')
  154. def __init__(self,*args,**kwargs):
  155. try:
  156. # pysqlite 3.x version
  157. import sqlite3 as sqlite
  158. except ImportError,es0:
  159. try:
  160. # pysqlite 2.x version
  161. from pysqlite2 import dbapi2 as sqlite
  162. except ImportError,es1:
  163. try:
  164. # pysqlite 1.x version
  165. import sqlite
  166. except ImportError,es2:
  167. sys.exit("Error importing SQLite module for python: %s or %s" \
  168. % (str(es1), str(es2)))
  169. if args:
  170. dbconn.__init__(self,sqlite,args[0])
  171. elif kwargs:
  172. dbconn.__init__(self,sqlite,kwargs)
  173. else:
  174. dbconn.__init__(self,sqlite,{'dbname':'/var/lib/sagator/sqlitedb'})
  175. #self.connect()
  176. def connect(self):
  177. self.DBC=self.DB.connect(
  178. safe.fn(self.PARAMS.get('dbname'))
  179. )
  180. class pg(dbconn):
  181. '''
  182. PostgreSQL support via pg python module.
  183. Requires: pg python module
  184. Usage: db.pg(host='127.0.0.1',port=5432,dbname='sagator',
  185. dbuser='sagator',dbpasswd='xxxxxx')
  186. Parameters:
  187. host - database server hostname
  188. port - tcp socket port for database server
  189. dbname - database name
  190. dbuser - authorization username
  191. dbpasswd - authorization password
  192. Database creation script: scripts/db/pgsql.sh
  193. '''
  194. name='pg'
  195. params=('host','port','dbname','dbuser','dbpasswd')
  196. def __init__(self,*args,**kwargs):
  197. try:
  198. import pg
  199. except ImportError,es:
  200. sys.exit("Error importing PostgreSQL module for python: "+str(es))
  201. if args:
  202. dbconn.__init__(self,pg,args[0])
  203. else:
  204. dbconn.__init__(self,pg,kwargs)
  205. #self.connect()
  206. def connect(self):
  207. self.DBC=self.DB.connect(
  208. dbname=self.PARAMS.get('dbname'),
  209. host=self.PARAMS.get('host'),
  210. port=self.PARAMS.get('port'),
  211. user=self.PARAMS.get('dbuser'),
  212. passwd=self.PARAMS.get('dbpasswd')
  213. )
  214. class pgdb(dbconn):
  215. '''
  216. PostgreSQL support via pgdb python module. [recomended]
  217. Requires: pgdb python module
  218. Usage: db.pgdb(host='127.0.0.1',port=5432,dbname='sagator',
  219. dbuser='sagator',dbpasswd='xxxxxx')
  220. Parameters:
  221. host - database server hostname
  222. port - tcp socket port for database server
  223. dbname - database name
  224. dbuser - authorization username
  225. dbpasswd - authorization password
  226. Database creation script: scripts/db/pgsql.sh
  227. '''
  228. name='pgdb'
  229. params=('host','port','dbname','dbuser','dbpasswd')
  230. def __init__(self,*args,**kwargs):
  231. try:
  232. import pgdb
  233. except ImportError,es:
  234. sys.exit("Error importing PostgreSQL module for python: "+str(es))
  235. if args:
  236. dbconn.__init__(self,pgdb,args[0])
  237. else:
  238. dbconn.__init__(self,pgdb,kwargs)
  239. #self.connect()
  240. def connect(self):
  241. self.DBC=self.DB.connect(
  242. user=self.PARAMS.get('dbuser'),
  243. password=self.PARAMS.get('dbpasswd'),
  244. host="%s:%s" % (self.PARAMS.get('host'),self.PARAMS.get('port')),
  245. database=self.PARAMS.get('dbname')
  246. )
  247. class psycopg(dbconn):
  248. '''
  249. PostgreSQL support via psycopg python module.
  250. Requires: psycopg python module
  251. Usage: db.psycopg(host='127.0.0.1',port=5432,dbname='sagator',
  252. dbuser='sagator',dbpasswd='xxxxxx')
  253. Parameters:
  254. host - database server hostname
  255. port - tcp socket port for database server
  256. dbname - database name
  257. dbuser - authorization username
  258. dbpasswd - authorization password
  259. Database creation script: scripts/db/pgsql.sh
  260. '''
  261. name='psycopg'
  262. params=('host','port','dbname','dbuser','dbpasswd')
  263. def __init__(self,*args,**kwargs):
  264. try:
  265. import psycopg
  266. except ImportError,es:
  267. sys.exit("Error importing psycopg module for python: "+str(es))
  268. if args:
  269. dbconn.__init__(self,psycopg,args[0])
  270. else:
  271. dbconn.__init__(self,psycopg,kwargs)
  272. #self.connect()
  273. def connect(self):
  274. self.DBC=self.DB.connect(
  275. "host=%s:%d dbname=%s user=%s password=%s" % (
  276. self.PARAMS.get('host'),
  277. self.PARAMS.get('port') or 5432,
  278. self.PARAMS.get('dbname'),
  279. self.PARAMS.get('dbuser'),
  280. self.PARAMS.get('dbpasswd')
  281. )
  282. )