Ticket #986: trac-mysql-r2944.patch
| File trac-mysql-r2944.patch, 13.4 kB (added by Andres Salomon <dilinger@…>, 3 years ago) |
|---|
-
trac/db/mysql_backend.py
diff -x.bzr -x.svn -urN trac.svn/trac/db/mysql_backend.py trac-addmysql/trac/db/mysql_backend.py
old new 1 # -*- coding: iso8859-1 -*- 2 # 3 # Copyright (C) 2005 Edgewall Software 4 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de> 5 # Copyright (C) 2005 Jeff Weiss <trac@jeffweiss.org> 6 # Copyright (C) 2006 Andres Salomon <dilinger@athenacr.com> 7 # All rights reserved. 8 # 9 # This software is licensed as described in the file COPYING, which 10 # you should have received as part of this distribution. The terms 11 # are also available at http://trac.edgewall.com/license.html. 12 # 13 # This software consists of voluntary contributions made by many 14 # individuals. For the exact contribution history, see the revision 15 # history and logs, available at http://projects.edgewall.com/trac/. 16 # 17 # Derived from postgres_backend.py 18 # Author: Christopher Lenz <cmlenz@gmx.de> 19 # Author: Jeff Weiss <trac@jeffweiss.org> 20 21 from trac.core import * 22 from trac.db.api import IDatabaseConnector 23 from trac.db.util import ConnectionWrapper 24 25 class MySQLConnector(Component): 26 """MySQL database support. Still extremely experimental! 27 Currently only supports database urls of the following formats: 28 mysql://user:password@host/database 29 mysql://user:password@host:port/database 30 """ 31 32 implements(IDatabaseConnector) 33 34 def get_supported_schemes(self): 35 return [('mysql', 1)] 36 37 def get_connection(self, path, user=None, password=None, host=None, 38 port=None, params={}): 39 return MySQLConnection(path, user, password, host, port, params) 40 41 def init_db(self, path, user=None, password=None, host=None, port=None, 42 params={}): 43 cnx = self.get_connection(path, user, password, host, port, params) 44 cursor = cnx.cursor() 45 from trac.db_default import schema 46 for table in schema: 47 for stmt in self.to_sql(table): 48 self.env.log.debug(stmt) 49 cursor.execute(stmt) 50 cnx.commit() 51 52 def to_sql(self, table): 53 sql = ["CREATE TABLE %s (" % table.name] 54 coldefs = [] 55 textkeys = [] 56 textcols = [] 57 mytablekey = [] 58 num_key_text = 0 59 for column in table.columns: 60 ctype = column.type 61 if column.auto_increment: 62 ctype = "INT AUTO_INCREMENT" 63 # Overide the column type because otherwise it will screw 64 # up the rest of the code for indexes and constraints 65 column.type = 'int' 66 if column.name in table.key: 67 mytablekey.append(column.name) 68 if column.type == 'text': 69 num_key_text += 1 70 textkeys.append(column.name) 71 if column.type == 'text': 72 textcols.append(column.name) 73 coldefs.append(" `%s` %s" % (column.name, ctype)) 74 if len(table.key) >= 1: 75 if num_key_text == 0: 76 num_key_text = 1 77 size = 767 / num_key_text 78 keysize = "(%s)" % size 79 for key in textkeys: 80 if key in mytablekey: 81 mytablekey.remove(key) 82 sizedkey = '`'+key+'`' + keysize 83 mytablekey.append(sizedkey) 84 coldefs.append(" CONSTRAINT %s_pk PRIMARY KEY (%s)" 85 % (table.name, ','.join(mytablekey))) 86 sql.append(',\n'.join(coldefs) + '\n)') 87 yield '\n'.join(sql) 88 # This does not work because what I need to do is not add something about 89 # the index size for the text fields because MySQL apparrently can't index 90 # on the entire length of the text field 91 for index in table.indices: 92 myidxcols = set([]) 93 processedidx = set([]) 94 for col in index.columns: 95 if col in textcols: 96 myidxcols.add(col) 97 myidx = set(index.columns) - myidxcols 98 for col in myidx: 99 escaped_col = '`'+col+'`' 100 processedidx.add(escaped_col) 101 if len(myidxcols) > 0: 102 size = 767 / len(myidxcols) 103 idxsize = "(%s)" % size 104 for col in myidxcols: 105 sizedidx = '`'+col+'`'+idxsize 106 processedidx.add(sizedidx) 107 yield "CREATE INDEX %s_%s_idx ON %s (%s)" % (table.name, 108 '_'.join(index.columns), table.name, ','.join(processedidx)) 109 110 111 class MySQLConnection(ConnectionWrapper): 112 """Connection wrapper for MySQL.""" 113 114 poolable = True 115 116 def __init__(self, path, user=None, password=None, host=None, 117 port=None, params={}): 118 import MySQLdb 119 120 if path.startswith('/'): 121 path = path[1:] 122 if port == None: 123 port = 3306 124 cnx = MySQLdb.connect(db=path, user=user, passwd=password, host=host, port=port) 125 ConnectionWrapper.__init__(self, cnx) 126 127 def cast(self, column, type): 128 # Temporary hack needed for the union of selects in the search module 129 return 'CAST(%s AS %s)' % (column, type) 130 131 def like(self): 132 # Temporary hack needed for the case-insensitive string matching in the 133 # search module 134 return 'LIKE' 135 136 def get_last_id(self, cursor, table, column='id'): 137 return self.cnx.insert_id() -
trac/db/tests/api.py
diff -x.bzr -x.svn -urN trac.svn/trac/db/tests/api.py trac-addmysql/trac/db/tests/api.py
old new 40 40 'path': '/trac'}), 41 41 _parse_db_str('postgres://john:letmein@localhost:9431/trac')) 42 42 43 def test_mysql_simple(self): 44 self.assertEqual(('mysql', {'host': 'localhost', 'path': '/trac'}), 45 _parse_db_str('mysql://localhost/trac')) 46 47 def test_mysql_with_creds(self): 48 self.assertEqual(('mysql', {'user': 'john', 'password': 'letmein', 49 'host': 'localhost', 'port': 3306, 50 'path': '/trac'}), 51 _parse_db_str('mysql://john:letmein@localhost:3306/trac')) 43 52 44 53 def suite(): 45 54 return unittest.makeSuite(ParseConnectionStringTestCase,'test') -
trac/db_default.py
diff -x.bzr -x.svn -urN trac.svn/trac/db_default.py trac-addmysql/trac/db_default.py
old new 148 148 Column('id', auto_increment=True), 149 149 Column('author'), 150 150 Column('title'), 151 Column(' sql'),151 Column('query'), 152 152 Column('description')], 153 153 ] 154 154 … … 379 379 ('name', 'value'), 380 380 (('database_version', str(db_version)),)), 381 381 ('report', 382 ('author', 'title', ' sql', 'description'),382 ('author', 'title', 'query', 'description'), 383 383 __mkreports(reports))) 384 384 385 385 default_config = \ … … 442 442 443 443 default_components = ('trac.About', 'trac.attachment', 444 444 'trac.db.postgres_backend', 'trac.db.sqlite_backend', 445 'trac.db.mysql_backend', 445 446 'trac.mimeview.enscript', 'trac.mimeview.patch', 446 447 'trac.mimeview.php', 'trac.mimeview.rst', 447 448 'trac.mimeview.silvercity', 'trac.mimeview.txtl', -
trac/ticket/report.py
diff -x.bzr -x.svn -urN trac.svn/trac/ticket/report.py trac-addmysql/trac/ticket/report.py
old new 148 148 req.redirect(self.env.href.report()) 149 149 150 150 title = req.args.get('title', '') 151 sql = req.args.get('sql', '')151 query = req.args.get('query', '') 152 152 description = req.args.get('description', '') 153 153 cursor = db.cursor() 154 cursor.execute("INSERT INTO report (title, sql,description) "155 "VALUES (%s,%s,%s)", (title, sql, description))154 cursor.execute("INSERT INTO report (title,query,description) " 155 "VALUES (%s,%s,%s)", (title, query, description)) 156 156 id = db.get_last_id(cursor, 'report') 157 157 db.commit() 158 158 req.redirect(self.env.href.report(id)) … … 176 176 177 177 if not req.args.has_key('cancel'): 178 178 title = req.args.get('title', '') 179 sql = req.args.get('sql', '')179 query = req.args.get('query', '') 180 180 description = req.args.get('description', '') 181 181 cursor = db.cursor() 182 cursor.execute("UPDATE report SET title=%s, sql=%s,description=%s "183 "WHERE id=%s", (title, sql, description, id))182 cursor.execute("UPDATE report SET title=%s,query=%s,description=%s " 183 "WHERE id=%s", (title, query, description, id)) 184 184 db.commit() 185 185 req.redirect(self.env.href.report(id)) 186 186 … … 204 204 def _render_editor(self, req, db, id, copy=False): 205 205 if id == -1: 206 206 req.perm.assert_permission('REPORT_CREATE') 207 title = sql= description = ''207 title = query = description = '' 208 208 else: 209 209 req.perm.assert_permission('REPORT_MODIFY') 210 210 cursor = db.cursor() 211 cursor.execute("SELECT title,description, sqlFROM report "211 cursor.execute("SELECT title,description,query FROM report " 212 212 "WHERE id=%s", (id,)) 213 213 row = cursor.fetchone() 214 214 if not row: … … 216 216 'Invalid Report Number') 217 217 title = row[0] or '' 218 218 description = row[1] or '' 219 sql= row[2] or ''219 query = row[2] or '' 220 220 221 221 if copy: 222 222 title += ' (copy)' … … 233 233 req.hdf['report.id'] = id 234 234 req.hdf['report.mode'] = 'edit' 235 235 req.hdf['report.title'] = title 236 req.hdf['report.sql'] = sql236 req.hdf['report.sql'] = query 237 237 req.hdf['report.description'] = description 238 238 239 239 def _render_view(self, req, db, id): … … 426 426 description = 'This is a list of reports available.' 427 427 else: 428 428 cursor = db.cursor() 429 cursor.execute("SELECT title, sql,description from report "429 cursor.execute("SELECT title,query,description from report " 430 430 "WHERE id=%s", (id,)) 431 431 row = cursor.fetchone() 432 432 if not row: -
trac/upgrades/db17.py
diff -x.bzr -x.svn -urN trac.svn/trac/upgrades/db17.py trac-addmysql/trac/upgrades/db17.py
old new 2 2 3 3 def do_upgrade(env, ver, cursor): 4 4 """Rename the columns `kind` and `change` in the `node_change` table for 5 compatibity with MySQL .5 compatibity with MySQL, as well as the `sql` column in the `reports` table. 6 6 """ 7 db_connector, _ = DatabaseManager(env)._get_connector() 8 9 # alter node_change table 7 10 cursor.execute("CREATE TEMP TABLE nc_old AS SELECT * FROM node_change") 8 11 cursor.execute("DROP TABLE node_change") 9 12 … … 16 19 Column('base_rev'), 17 20 Index(['rev']) 18 21 ] 19 db_connector, _ = DatabaseManager(env)._get_connector()20 22 for stmt in db_connector.to_sql(table): 21 23 cursor.execute(stmt) 22 24 23 25 cursor.execute("INSERT INTO node_change (rev,path,node_type,change_type," 24 26 "base_path,base_rev) SELECT rev,path,kind,change," 25 27 "base_path,base_rev FROM nc_old") 28 29 # alter report table 30 cursor.execute("CREATE TEMP TABLE report_old AS SELECT * FROM report") 31 cursor.execute("DROP TABLE report") 32 33 table = Table('report', key='id')[ 34 Column('id', auto_increment=True), 35 Column('author'), 36 Column('title'), 37 Column('query'), 38 Column('description') 39 ] 40 for stmt in db_connector.to_sql(table): 41 cursor.execute(stmt) 42 43 cursor.execute("INSERT INTO report (id,author,title,query,description) " 44 "SELECT id,author,title,sql,description FROM report_old") -
trac/web/session.py
diff -x.bzr -x.svn -urN trac.svn/trac/web/session.py trac-addmysql/trac/web/session.py
old new 181 181 # changed as to minimize the purging. 182 182 mintime = now - PURGE_AGE 183 183 self.env.log.debug('Purging old, expired, sessions.') 184 cursor.execute("DELETE FROM session WHERE authenticated=0 AND " 185 "sid IN (SELECT sid FROM session WHERE " 186 "var_name='last_visit' AND var_value < %s)", 184 cursor.execute("SELECT DISTINCT sid FROM session WHERE " 185 "var_name='last_visit' AND var_value < %s", 187 186 (mintime,)) 188 187 args = cursor.fetchall() 188 sql = 'DELETE FROM session WHERE authenticated = 0 AND (' 189 sql += ' OR '.join(['sid = %s'] * len(args)) + ')' 190 cursor.execute(sql, args) 189 191 db.commit()
