Merge branch 'bugfix_pgsql_default_stmt'
[bitcoin:eloipool.git] / sharelogging / sql.py
1 # Eloipool - Python Bitcoin pool server
2 # Copyright (C) 2011-2012  Luke Dashjr <luke-jr+eloipool@utopios.org>
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as
6 # published by the Free Software Foundation, either version 3 of the
7 # License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 import logging
18 from util import shareLogFormatter
19
20 _logger = logging.getLogger('sharelogging.sql')
21
22 class sql:
23         _psf = {
24                 'qmark': '?',
25                 'format': '%s',
26                 'pyformat': '%s',
27         }
28         
29         def __init__(self, **ka):
30                 self.opts = ka
31                 dbe = ka['engine']
32                 if 'statement' not in ka:
33                         _logger.warn('"statement" not specified for sql logger, but default may vary!')
34                 getattr(self, 'setup_%s' % (dbe,))()
35         
36         def setup_mysql(self):
37                 import pymysql
38                 self.db = pymysql.connect(**self.opts.get('dbopts', {}))
39                 self.modsetup(mysql)
40         
41         def setup_postgres(self):
42                 import psycopg2
43                 self.db = psycopg2.connect(**self.opts.get('dbopts', {}))
44                 self.opts.setdefault('statement', "insert into shares (rem_host, username, our_result, upstream_result, reason, solution) values ({Q(remoteHost)}, {username}, {YN(not(rejectReason))}, {YN(upstreamResult)}, {rejectReason}, decode({solution}, 'hex'))")
45                 self.modsetup(psycopg2)
46         
47         def setup_sqlite(self):
48                 import sqlite3
49                 self.db = sqlite3.connect(**self.opts.get('dbopts', {}))
50                 self.modsetup(sqlite3)
51         
52         def modsetup(self, mod):
53                 psf = self._psf[mod.paramstyle]
54                 self.opts.setdefault('statement', "insert into shares (remoteHost, username, rejectReason, upstreamResult, solution) values ({remoteHost}, {username}, {rejectReason}, {upstreamResult}, {solution})")
55                 stmt = self.opts['statement']
56                 self.pstmt = shareLogFormatter(stmt, psf)
57         
58         def logShare(self, share):
59                 (stmt, params) = self.pstmt.applyToShare(share)
60                 dbc = self.db.cursor()
61                 dbc.execute(stmt, params)
62                 self.db.commit()