00001 import silme.io
00002 from silme.core import L10nPackage, L10nObject, EntityList, Blob, Entity
00003 from silme.io.clients import IOClient, DBClient
00004
00005 import os
00006 import MySQLdb
00007 import re
00008
00009 def register(Manager):
00010 Manager.register(MysqlClient)
00011
00012 class MysqlClient(DBClient):
00013 name = 'mysql'
00014 desc = "MySQL reader/writer"
00015 type = IOClient.__name__
00016 connection = None
00017
00018 @classmethod
00019 def matches_path(cls, path):
00020 """
00021 tests if the ioclient should be used for this type of path
00022 Matches any mysql://
00023 """
00024 print path
00025 return path.startswith('mysql://')
00026
00027 @classmethod
00028 def get_entitylist(cls, path, source=False, code='default', parser=None):
00029 entitylist = EntityList()
00030
00031 con = cls._connected()
00032 if not con:
00033 (host, port, db, user, password, table) = cls._explode_path(path)
00034 cls._connect(path)
00035 else:
00036 table = path
00037 entitylist.id = table
00038 cursor = cls.connection.cursor()
00039 cursor.execute('SELECT * FROM '+table)
00040 for row in cursor:
00041 entitylist.add_entity(Entity(row[0],row[1]))
00042 cursor.close()
00043 if not con:
00044 cls._close()
00045 return entitylist
00046
00047 @classmethod
00048 def get_l10npackage(cls, path,
00049 code='default',
00050 object_type='l10nobject',
00051 source=None,
00052 ignore=['CVS','.svn','.DS_Store', '.hg']):
00053 l10npackage = L10nPackage()
00054 cls._connect(path)
00055 cursor = cls.connection.cursor()
00056 cursor.execute('SHOW TABLES')
00057 for row in cursor:
00058 elist = cls.get_entitylist(row[0])
00059 l10npackage.add_object(elist)
00060 cursor.close()
00061 cls._close()
00062 return l10npackage
00063
00064 @classmethod
00065 def write_entitylist(cls, elist, path, encoding=None):
00066 con = cls._connected()
00067 if not con:
00068 cls._connect(path)
00069
00070 table = elist.id
00071 cursor = cls.connection.cursor()
00072 cursor.execute('DELETE FROM '+table)
00073 l = [(e.id, e.get_value()) for e in elist.values()]
00074 cursor.executemany("""INSERT INTO """+table+""" (id, value)
00075 VALUES (%s, %s)""",
00076 l)
00077 if not con:
00078 cls._close()
00079 return True
00080
00081 @classmethod
00082 def write_l10npackage(cls, l10npack, path):
00083 cls._connect(path)
00084 for i in l10npack.objects:
00085 cls.write_entitylist(l10npack.objects[i], path)
00086 cls._close()
00087 return True
00088
00089 @classmethod
00090 def path_type(cls, path):
00091 """
00092 returns 'package', 'object' depending on the path type
00093 """
00094 (host, port, db, user, password, table) = cls._explode_path(path)
00095 if not table:
00096 return 'package'
00097 else:
00098 return 'object'
00099
00100
00101
00102 @classmethod
00103
00104 def _explode_path(cls, path):
00105 pattern = re.compile('^mysql://([^:\/]+):?([0-9]+)?\/?([^\?]+)?\??(.+)?')
00106 match = pattern.match(path)
00107 if match:
00108 host = match.group(1)
00109 port = match.group(2) or False
00110 db = match.group(3)
00111 params = {}
00112 s = match.group(4)
00113 if s:
00114 for i in s.split('&'):
00115 pair = i.split('=')
00116 key = pair[0].strip()
00117 val = pair[1].strip()
00118 params[key] = val
00119 user = params.get('user') or ''
00120 password = params.get('password') or ''
00121 table = params.get('table') or None
00122 return (host, port, db, user, password, table)
00123 else:
00124 raise Exception('path is not parseable')
00125
00126 @classmethod
00127 def _connect(cls, path):
00128 if not cls._connected():
00129 (host, port, db, user, password, table) = cls._explode_path(path)
00130 cls.connection = MySQLdb.connect(host = host,
00131 port = port,
00132 user = user,
00133 passwd = password,
00134 db = db,
00135 use_unicode = True)
00136
00137 @classmethod
00138 def _close(cls):
00139 if cls._connected():
00140 cls.connection.close()
00141 cls.connection = None
00142
00143 @classmethod
00144 def _connected(cls):
00145 return bool(cls.connection)