Mercurial > sqlpython
annotate sqlpython/connections.py @ 434:8e822859e3a4
tweaking ls hits
author | catherine@dellzilla |
---|---|
date | Wed, 27 Jan 2010 10:40:40 -0500 |
parents | 439621c917c4 |
children | 5443c5d5ed8c |
rev | line source |
---|---|
427 | 1 import re |
2 import os | |
428 | 3 import getpass |
427 | 4 import gerald |
5 import schemagroup | |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
6 import time |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
7 import threading |
427 | 8 |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
9 class ObjectDescriptor(object): |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
10 def __init__(self, name, dbobj): |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
11 self.fullname = name |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
12 self.dbobj = dbobj |
433 | 13 self.type = str(type(self.dbobj)).split('.')[-1].lower().strip("'>") |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
14 self.path = '%s/%s' % (self.type, self.fullname) |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
15 #self.type_path = '%s/' % self.dbobj.type |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
16 (self.owner, self.unqualified_name) = self.fullname.split('.') |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
17 self.owner = self.owner.lower() |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
18 def match_pattern(self, pattern, specific_owner=None): |
433 | 19 return ( pattern.match(self.fullname) or |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
20 pattern.match(self.type) or |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
21 ((not specific_owner) and pattern.match(self.unqualified_name)) or |
433 | 22 (specific_owner and (self.owner == specific_owner.lower()) and pattern.match(self.unqualified_name)) ) |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
23 |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
24 class GeraldPlaceholder(object): |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
25 current = False |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
26 complete = False |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
27 |
428 | 28 class DatabaseInstance(object): |
427 | 29 password = None |
30 uri = None | |
31 connection_uri_parser = re.compile('(postgres|oracle|mysql|sqlite|mssql):/(.*$)', re.IGNORECASE) | |
32 | |
33 def __init__(self, arg, opts, default_rdbms = 'oracle'): | |
34 self.default_rdbms = default_rdbms | |
35 if not self.parse_connect_uri(arg): | |
36 self.parse_connect_arg(arg, opts) | |
428 | 37 self.connection = self.new_connection() |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
38 self.gerald = GeraldPlaceholder() |
433 | 39 self.discover_metadata() |
40 | |
41 def discover_metadata(self): | |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
42 self.metadata_discovery_thread = MetadataDiscoveryThread(self) |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
43 self.metadata_discovery_thread.start() |
427 | 44 |
45 def parse_connect_uri(self, uri): | |
46 results = self.connection_uri_parser.search(uri) | |
47 if results: | |
48 (self.username, self.password, self.host, self.port, self.db_name | |
49 ) = gerald.utilities.dburi.Connection().parse_uri(results.group(2)) | |
50 self.__class__ = rdbms_types.get(results.group(1)) | |
51 self.uri = uri | |
52 self.port = self.port or self.default_port | |
53 return True | |
54 else: | |
55 return False | |
56 | |
57 def parse_connect_arg(self, arg, opts): | |
58 self.host = opts.hostname | |
59 self.oracle_connect_mode = 0 | |
60 if opts.postgres: | |
428 | 61 self.__class__ = PostgresDatabaseInstance |
427 | 62 elif opts.mysql: |
428 | 63 self.__class__ = MySQLDatabaseInstance |
427 | 64 elif opts.oracle: |
428 | 65 self.__class__ = OracleDatabaseInstance |
427 | 66 else: |
67 self.__class__ = rdbms_types.get(self.default_rdbms) | |
68 self.assign_args(arg, opts) | |
69 self.db_name = opts.database or self.db_name | |
70 self.port = self.port or self.default_port | |
430
aa1a603740fe
making progress, but there is something awful about threaded calls to sysdate
catherine@dellzilla
parents:
428
diff
changeset
|
71 self.password = self.password or opts.password or getpass.getpass('Password: ') |
427 | 72 self.uri = self.uri or '%s://%s:%s@%s:%s/%s' % (self.rdbms, self.username, self.password, |
73 self.host, self.port, self.db_name) | |
74 | |
75 def gerald_uri(self): | |
76 return self.uri.split('?mode=')[0] | |
433 | 77 |
428 | 78 def set_instance_number(self, instance_number): |
79 self.instance_number = instance_number | |
80 self.prompt = "%d:%s@%s> " % (self.instance_number, self.username, self.db_name) | |
427 | 81 |
428 | 82 class OpenSourceDatabaseInstance(DatabaseInstance): |
83 def assign_args(self, arg, opts): | |
84 self.assign_details(arg, opts) | |
85 self.username = self.username or os.environ['USER'] | |
427 | 86 self.db_name = self.db_name or self.username |
428 | 87 self.host = opts.hostname or self.host or 'localhost' |
427 | 88 |
89 try: | |
90 import psycopg2 | |
428 | 91 class PostgresDatabaseInstance(OpenSourceDatabaseInstance): |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
92 gerald_class = gerald.PostgresSchema |
427 | 93 rdbms = 'postgres' |
94 default_port = 5432 | |
95 def assign_details(self, arg, opts): | |
428 | 96 self.port = opts.port or os.getenv('PGPORT') or self.default_port |
427 | 97 self.host = self.host or os.getenv('PGHOST') |
98 args = arg.split() | |
99 if len(args) > 1: | |
100 self.username = args[1] | |
101 if len(args) > 0: | |
102 self.db_name = args[0] | |
103 def new_connection(self): | |
104 return psycopg2.connect(host = self.host, user = self.username, | |
105 password = self.password, database = self.db_name, | |
106 port = self.port) | |
107 except ImportError: | |
428 | 108 class PostgresDatabaseInstance(OpenSourceDatabaseInstance): |
427 | 109 pass |
110 | |
111 try: | |
112 import MySQLdb | |
428 | 113 class MySQLDatabaseInstance(OpenSourceDatabaseInstance): |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
114 gerald_class = gerald.MySQLSchema |
427 | 115 rdbms = 'mysql' |
116 default_port = 3306 | |
117 def assign_details(self, arg, opts): | |
118 self.db_name = arg | |
119 def new_connection(self): | |
120 return MySQLdb.connect(host = self.host, user = self.username, | |
121 passwd = self.password, db = self.db_name, | |
122 port = self.port, sql_mode = 'ANSI') | |
123 except ImportError: | |
428 | 124 class MySQLDatabaseInstance(OpenSourceDatabaseInstance): |
427 | 125 pass |
126 | |
127 try: | |
128 import cx_Oracle | |
129 | |
428 | 130 class OracleDatabaseInstance(DatabaseInstance): |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
131 gerald_class = gerald.oracle_schema.User |
427 | 132 rdbms = 'oracle' |
434 | 133 connection_parser = re.compile('(?P<username>[^/\s@]*)(/(?P<password>[^/\s@]*))?(@((?P<host>[^/\s:]*)(:(?P<port>\d{1,4}))?/)?(?P<db_name>[^/\s:]*))?(\s+as\s+(?P<mode>sys(dba|oper)))?', |
427 | 134 re.IGNORECASE) |
135 connection_modes = {'SYSDBA': cx_Oracle.SYSDBA, 'SYSOPER': cx_Oracle.SYSOPER} | |
136 oracle_connect_mode = 0 | |
137 default_port = 1521 | |
138 def assign_args(self, arg, opts): | |
139 connectargs = self.connection_parser.search(arg) | |
140 self.username = connectargs.group('username') | |
141 self.password = connectargs.group('password') | |
434 | 142 self.db_name = connectargs.group('db_name') or os.getenv('ORACLE_SID') |
427 | 143 self.port = connectargs.group('port') or self.default_port |
144 self.host = connectargs.group('host') | |
145 if self.host: | |
146 self.dsn = cx_Oracle.makedsn(self.host, self.port, self.db_name) | |
147 else: | |
148 self.dsn = self.db_name | |
149 self.uri = '%s://%s:%s@%s' % (self.rdbms, self.username, self.password, self.db_name) | |
150 if connectargs.group('mode'): | |
151 self.oracle_connect_mode = self.connection_modes.get(connectargs.group('mode').upper()) | |
152 def new_connection(self): | |
153 return cx_Oracle.connect(user = self.username, | |
154 password = self.password, | |
155 dsn = self.dsn, | |
156 mode = self.oracle_connect_mode) | |
157 | |
158 | |
159 except ImportError: | |
428 | 160 class OracleDatabaseInstance(DatabaseInstance): |
427 | 161 pass |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
162 |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
163 class MetadataDiscoveryThread(threading.Thread): |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
164 def __init__(self, db_instance): |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
165 threading.Thread.__init__(self) |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
166 self.db_instance = db_instance |
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
167 def run(self): |
433 | 168 self.db_instance.gerald.current = False |
169 newgerald = self.db_instance.gerald_class(self.db_instance.username, self.db_instance.gerald_uri()) | |
170 newgerald.descriptions = {} | |
171 for (name, obj) in newgerald.schema.items(): | |
172 newgerald.descriptions[name] = ObjectDescriptor(name, obj) | |
173 newgerald.current = True | |
174 newgerald.complete = True | |
175 self.db_instance.gerald = newgerald | |
432
26b09e1481e7
beginning to reimplement threaded metadata discovery
catherine@dellzilla
parents:
431
diff
changeset
|
176 |
428 | 177 rdbms_types = {'oracle': OracleDatabaseInstance, 'mysql': MySQLDatabaseInstance, 'postgres': PostgresDatabaseInstance} |
427 | 178 |
179 |