Changeset 146
- Timestamp:
- 08/23/07 21:15:00
- Files:
-
- trunk/geniusql/objects.py (modified) (9 diffs)
- trunk/geniusql/providers/ado.py (modified) (3 diffs)
- trunk/geniusql/providers/firebird.py (modified) (3 diffs)
- trunk/geniusql/providers/msaccess.py (modified) (3 diffs)
- trunk/geniusql/providers/mysql.py (modified) (7 diffs)
- trunk/geniusql/providers/postgres.py (modified) (7 diffs)
- trunk/geniusql/providers/pypgsql.py (modified) (2 diffs)
- trunk/geniusql/providers/sqlite.py (modified) (4 diffs)
- trunk/geniusql/providers/sqlserver.py (modified) (3 diffs)
- trunk/geniusql/test/benchmark.py (modified) (1 diff)
- trunk/geniusql/test/test_firebird.py (modified) (1 diff)
- trunk/geniusql/test/test_msaccess.py (modified) (4 diffs)
- trunk/geniusql/test/test_mysql.py (modified) (2 diffs)
- trunk/geniusql/test/test_pypgsql.py (modified) (3 diffs)
- trunk/geniusql/test/test_sqlite.py (modified) (3 diffs)
- trunk/geniusql/test/test_sqlserver.py (modified) (1 diff)
- trunk/geniusql/test/zoo_fixture.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/geniusql/objects.py
r145 r146 483 483 """ 484 484 485 name = None 486 qname = None 487 485 488 tableclass = Table 486 489 indexsetclass = IndexSet 487 490 488 def __new__(cls, db, name ):491 def __new__(cls, db, name=None): 489 492 return dict.__new__(cls) 490 493 491 def __init__(self, db, name ):494 def __init__(self, db, name=None): 492 495 dict.__init__(self) 493 496 494 497 self.db = db 495 self.name = self.db.sql_name(name) 496 self.qname = self.db.quote(self.name) 498 # Although __init__ should set this instance's "name" attribute, 499 # allow subclasses to pull that information from other sources 500 # if necessary. 501 if name is not None: 502 self.name = self.db.sql_name(name) 503 self.qname = self.db.quote(name) 497 504 self._discover_lock = threading.Lock() 498 self.discover_dbinfo()499 505 500 506 def __repr__(self): … … 503 509 504 510 # Discovery # 505 506 def _get_dbinfo(self, conn=None):507 return {}508 509 def discover_dbinfo(self, conn=None):510 """Set attributes on self with actual DB metadata, where possible."""511 for k, v in self._get_dbinfo(conn).iteritems():512 setattr(self, k, v)513 511 514 512 def _get_tables(self, conn=None): … … 730 728 dict.__setitem__(self, newkey, newtable) 731 729 732 def create _database(self):733 self.db.execute_ddl("CREATE DATABASE %s;" % self.qname)730 def create(self): 731 """Create this schema in the database.""" 734 732 self.clear() 735 733 736 def drop_database(self): 734 def drop(self): 735 """Drop this schema from the database.""" 737 736 # Must shut down all connections to avoid 738 737 # "being accessed by other users" error. 739 738 self.db.connections.shutdown() 740 self.db.execute_ddl("DROP DATABASE %s;" % self.qname) 741 self.clear() 739 740 seen = {} 741 for tkey, table in self.items(): 742 # We might have multiple keys pointing at the same table. 743 if table.name not in seen: 744 del self[tkey] 745 seen[table.name] = None 742 746 743 747 … … 745 749 746 750 __metaclass__ = geniusql._AttributeDocstrings 751 752 name = None 753 qname = None 747 754 748 755 typeset = dbtypes.DatabaseTypeSet() … … 757 764 758 765 multischema = True 759 multischema__doc = """If True, instances of this Database class may760 spawn multiple Schema instances. This is False, for example, when761 the underlying Databaseengine binds connections to individual files.766 multischema__doc = """If True, instances of this Database class 767 may spawn multiple Schema instances. This is False, for example, 768 when the underlying engine binds connections to individual files. 762 769 In most applications (that use a single schema) this presents no 763 770 problems; applications that need to handle more than one schema … … 773 780 774 781 def __init__(self, **kwargs): 782 # Although __init__ should set this instance's "name" attribute, 783 # allow subclasses to pull that information from other kwargs 784 # or other sources if necessary. 785 self.name = kwargs.get('name', None) 786 if self.name: 787 self.qname = self.quote(self.name) 788 775 789 self.connections = self.connectionmanager(self) 776 790 … … 787 801 childobj = getattr(self, namespace) 788 802 setattr(childobj, name, v) 803 804 self.discover_dbinfo() 789 805 790 806 def version(self): … … 795 811 pass 796 812 797 def schema(self, name ):813 def schema(self, name=None): 798 814 return self.schemaclass(self, name) 815 816 def create(self): 817 """Create this database.""" 818 self.execute_ddl("CREATE DATABASE %s;" % self.qname) 819 820 def drop(self): 821 """Drop this database.""" 822 # Must shut down all connections to avoid 823 # "being accessed by other users" error. 824 self.connections.shutdown() 825 self.execute_ddl("DROP DATABASE %s;" % self.qname) 826 827 # Discovery # 828 829 def _get_dbinfo(self, conn=None): 830 return {} 831 832 def discover_dbinfo(self, conn=None): 833 """Set attributes on self with actual DB metadata, where possible.""" 834 for k, v in self._get_dbinfo(conn).iteritems(): 835 setattr(self, k, v) 836 837 def _get_schemas(self, conn=None): 838 """Return a list of schema names.""" 839 raise NotImplementedError 840 841 def discover_schemas(self, conn=None): 842 """Return a list of Schema objects.""" 843 if self.multischema: 844 return [self.schema(name) for name in self._get_schemas(conn)] 845 else: 846 return self.schema() 799 847 800 848 # Naming # … … 810 858 811 859 def sql_name(self, key): 812 """Return the native SQL version of key ."""860 """Return the native SQL version of key (unquoted).""" 813 861 if self.sql_name_caseless: 814 862 key = key.lower() trunk/geniusql/providers/ado.py
r145 r146 381 381 for row in data 382 382 # Ignore linked and system tables 383 if row[3] == "TABLE" ]383 if row[3] == "TABLE" and row[1] == self.name] 384 384 385 385 def _get_table(self, tablename, conn=None): … … 391 391 for row in data: 392 392 name = str(row[2]) 393 if name == tablename :393 if name == tablename and row[1] == self.name: 394 394 return self.tableclass(name, self.db.quote(name), 395 395 self, created=True) … … 411 411 # I tried passing criteria to OpenSchema, but passing None is 412 412 # not the same as passing pythoncom.Empty (which errors). 413 if table.name and row[2] != table.name: 414 continue 415 i = geniusql.Index(row[5], self.db.quote(row[5]), 416 row[2], row[17], row[7]) 417 indices.append(i) 413 if (row[2] == table.name and row[1] == self.name): 414 i = geniusql.Index(row[5], self.db.quote(row[5]), 415 row[2], row[17], row[7]) 416 indices.append(i) 418 417 return indices 419 418 trunk/geniusql/providers/firebird.py
r145 r146 732 732 tableclass = FirebirdTable 733 733 734 def __init__(self, db, name):735 dict.__init__(self)736 737 self.db = db738 739 # Here's where we differ from the superclass.740 # The Firebird "database name" is a filename, not an identifier,741 # so we don't set self.name = sql_name(name).742 self.name = name743 # We also have to set our parent's "name" so conns can use it.744 self.db.name = name745 746 self.qname = self.db.quote(self.name)747 self._discover_lock = threading.Lock()748 self.discover_dbinfo()749 750 734 def _get_tables(self, conn=None): 751 735 data, _ = self.db.fetch( … … 876 860 self.db.execute_ddl("DROP GENERATOR %s;" % column.sequence_name) 877 861 column.sequence_name = None 878 879 def create_database(self):880 # Firebird DB 'names' are actually filesystem paths.881 sql = ("CREATE DATABASE %s USER '%s' PASSWORD '%s';"882 % (self.qname, self.db.user, self.db.password))883 884 # Use the kinterbasdb helper methods for cleaner create and drop.885 # We also use dialect 3 *always* to help with quoted identifiers.886 # Note that DATE has no time in dialect 3 (use TIMESTAMP instead).887 conn = kinterbasdb.create_database(sql, 3)888 conn.close()889 890 self.clear()891 892 def drop_database(self):893 # Must shut down all connections to avoid894 # "being accessed by other users" error.895 self.db.connections.shutdown()896 897 conn = self.db.connections._get_conn()898 conn.drop_database()899 # For some reason, the conn is already closed...900 ## conn.close()901 self.clear()902 862 903 863 … … 1011 971 return ("KInterbasDB Version: %r\nServer Version: %r" 1012 972 % (kinterbasdb.__version__, svcCon.getServerVersion())) 1013 1014 973 974 def create(self): 975 # Firebird DB 'names' are actually filesystem paths. 976 sql = ("CREATE DATABASE %s USER '%s' PASSWORD '%s';" 977 % (self.qname, self.user, self.password)) 978 979 # Use the kinterbasdb helper methods for cleaner create and drop. 980 # We also use dialect 3 *always* to help with quoted identifiers. 981 # Note that DATE has no time in dialect 3 (use TIMESTAMP instead). 982 conn = kinterbasdb.create_database(sql, 3) 983 conn.close() 984 985 def drop(self): 986 # Must shut down all connections to avoid 987 # "being accessed by other users" error. 988 self.connections.shutdown() 989 990 conn = self.connections._get_conn() 991 conn.drop_database() 992 # For some reason, the conn is already closed... 993 ## conn.close() 994 995 trunk/geniusql/providers/msaccess.py
r145 r146 468 468 data, _ = self.db.fetch(ado.adSchemaIndexes, conn=conn, schema=True) 469 469 pknames = [row[17] for row in data 470 if (table.name == row[2]) and row[6]] 470 if (row[2] == table.name and 471 row[1] == self.name) and row[6]] 471 472 472 473 # columns will be … … 623 624 624 625 return '%s %s' % (column.qname, ddl) 625 626 def create_database(self):627 # By not providing an Engine Type, it defaults to 5 = Access 2000.628 cat = win32com.client.Dispatch(r'ADOX.Catalog')629 cat.Create(self.db.connections.Connect)630 cat.ActiveConnection.Close()631 self.clear()632 633 def drop_database(self):634 # Must shut down our only connection to avoid635 # "Permission denied" error on os.remove call below.636 self.db.connections.shutdown()637 638 import os639 # This should accept relative or absolute paths640 if os.path.exists(self.name):641 os.remove(self.name)642 643 self.clear()644 626 645 627 … … 686 668 del conn 687 669 return "ADO Version: %s" % v 688 670 671 def create(self): 672 # By not providing an Engine Type, it defaults to 5 = Access 2000. 673 cat = win32com.client.Dispatch(r'ADOX.Catalog') 674 cat.Create(self.connections.Connect) 675 cat.ActiveConnection.Close() 676 677 def drop(self): 678 # Must shut down our only connection to avoid 679 # "Permission denied" error on os.remove call below. 680 self.connections.shutdown() 681 682 import os 683 # This should accept relative or absolute paths 684 if os.path.exists(self.name): 685 os.remove(self.name) 686 trunk/geniusql/providers/mysql.py
r145 r146 477 477 478 478 def _get_tables(self, conn=None): 479 data, _ = self.db.fetch("SHOW TABLES FROM %s" % self. qname, conn=conn)479 data, _ = self.db.fetch("SHOW TABLES FROM %s" % self.db.qname, conn=conn) 480 480 return [self.tableclass(row[0], self.db.quote(row[0]), 481 481 self, created=True) … … 484 484 def _get_table(self, tablename, conn=None): 485 485 data, _ = self.db.fetch("SHOW TABLES FROM %s LIKE '%s'" 486 % (self. qname, tablename), conn=conn)486 % (self.db.qname, tablename), conn=conn) 487 487 for row in data: 488 488 name = row[0] … … 496 496 # See http://dev.mysql.com/doc/refman/4.1/en/describe.html 497 497 data, _ = self.db.fetch("SHOW COLUMNS FROM %s.%s" % 498 (self. qname, table.qname), conn=conn)498 (self.db.qname, table.qname), conn=conn) 499 499 cols = [] 500 500 for row in data: … … 533 533 # Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment 534 534 data, _ = self.db.fetch("SHOW INDEX FROM %s.%s" 535 % (self. qname, table.qname), conn=conn)535 % (self.db.qname, table.qname), conn=conn) 536 536 except _mysql.ProgrammingError, x: 537 537 if x.args[0] != 1146: … … 543 543 indices.append(i) 544 544 return indices 545 546 def create_database(self):547 # _mysql has create_db and drop_db commands, but they're deprecated.548 encoding = self.db.encoding549 if encoding:550 encoding = " CHARACTER SET %s" % encoding551 sql = 'CREATE DATABASE %s%s;' % (self.qname, encoding)552 conn = self.db.connections._get_conn(master=True)553 self.db.execute_ddl(sql, conn)554 conn.close()555 self.clear()556 557 def drop_database(self):558 conn = self.db.connections._get_conn(master=True)559 self.db.execute_ddl('DROP DATABASE %s;' % self.qname, conn)560 conn.close()561 self.clear()562 545 563 546 … … 577 560 578 561 def __init__(self, **kwargs): 562 kwargs['name'] = kwargs['db'] 579 563 geniusql.Database.__init__(self, **kwargs) 580 564 … … 652 636 return False 653 637 return exc.args[0] == 1205 654 638 639 def create(self): 640 # _mysql has create_db and drop_db commands, but they're deprecated. 641 encoding = self.encoding 642 if encoding: 643 encoding = " CHARACTER SET %s" % encoding 644 sql = 'CREATE DATABASE %s%s;' % (self.qname, encoding) 645 conn = self.connections._get_conn(master=True) 646 self.execute_ddl(sql, conn) 647 conn.close() 648 649 def drop(self): 650 conn = self.connections._get_conn(master=True) 651 self.execute_ddl('DROP DATABASE %s;' % self.qname, conn) 652 conn.close() 653 trunk/geniusql/providers/postgres.py
r145 r146 560 560 discover_pg_tables = False 561 561 562 def __init__(self, db, name=None): 563 if name is None: 564 name = 'public' 565 geniusql.Schema.__init__(self, db, name) 566 562 567 def _get_tables(self, conn=None): 568 data, _ = self.db.fetch("SELECT oid FROM pg_class WHERE " 569 "relname = 'pg_class' and relkind='r'", conn=conn) 570 pgclass_OID = data[0][0] 571 572 data, _ = self.db.fetch( 573 "SELECT c.relname, d.description FROM " 574 "(pg_class c LEFT JOIN pg_namespace n ON c.relnamespace = n.oid) " 575 "LEFT JOIN (SELECT description, objoid FROM pg_shdescription " 576 "WHERE classoid = %s) AS d ON c.oid = d.objoid WHERE n.nspname " 577 "= '%s' and c.relkind = 'r';" % (pgclass_OID, self.name), 578 conn=conn) 579 return [self.tableclass(name, self.db.quote(name), self, 580 created=True, description=description) 581 for name, description in data 582 if self.discover_pg_tables or not name.startswith("pg_")] 583 584 def _get_table(self, tablename, conn=None): 585 if (not self.discover_pg_tables) and tablename.startswith("pg_"): 586 raise errors.MappingError(tablename) 587 563 588 data, _ = self.db.fetch("SELECT oid FROM pg_class WHERE " 564 589 "relname = 'pg_class'", conn=conn) 565 590 pgclass_OID = data[0][0] 566 591 567 data, _ = self.db.fetch( 568 "SELECT c.relname, d.description, n.nspname FROM " 569 "(pg_class c LEFT JOIN pg_namespace n ON c.relnamespace = n.oid) " 570 "LEFT JOIN (SELECT description, objoid FROM pg_shdescription " 571 "WHERE classoid = %s) AS d ON c.oid = d.objoid WHERE n.nspname " 572 "!= 'information_schema' and n.nspname NOT LIKE 'pg\\_%%';" % 573 pgclass_OID, conn=conn) 574 tables = [] 575 for name, description, namespace in data: 576 if (not self.discover_pg_tables) and name.startswith("pg_"): 577 continue 578 t = self.tableclass(name, self.db.quote(name), 579 self, created=True, description=description) 580 t.namespace = namespace 581 tables.append(t) 582 return tables 583 584 def _get_table(self, tablename, conn=None): 585 if (not self.discover_pg_tables) and name.startswith("pg_"): 586 raise errors.MappingError(tablename) 587 588 data, _ = self.db.fetch("SELECT oid FROM pg_class WHERE " 589 "relname = 'pg_class'", conn=conn) 590 pgclass_OID = data[0][0] 591 592 data, _ = self.db.fetch("SELECT c.oid, c.relname, n.nspname FROM " 592 data, _ = self.db.fetch("SELECT c.oid, c.relname FROM " 593 593 "pg_class c LEFT JOIN pg_namespace n ON c.relnamespace " 594 "= n.oid WHERE c.relname = '%s'" % tablename, conn=conn) 595 for table_OID, name, namespace in data: 594 "= n.oid WHERE c.relname = '%s' AND c.relkind = 'r' " 595 "AND n.nspname = '%s'" % (tablename, self.name), 596 conn=conn) 597 for table_OID, name in data: 596 598 if name == tablename: 597 599 t = self.tableclass(name, self.db.quote(name), 598 600 self, created=True) 599 t.namespace = namespace600 601 601 602 # Get the description of the table, if any … … 614 615 data, _ = self.db.fetch("SELECT c.oid FROM pg_class c LEFT JOIN " 615 616 "pg_namespace n ON c.relnamespace = n.oid WHERE " 616 "c.relname = '%s' AND n.nspname = '%s'" % 617 (table.name, table.namespace), conn=conn) 617 "c.relname = '%s' AND c.relkind = 'r' " 618 "AND n.nspname = '%s'" % (table.name, self.name), 619 conn=conn) 618 620 table_OID = data[0][0] 619 621 … … 636 638 typeset = self.db.typeset 637 639 ## print 638 ## print table.name, table.namespace, ">>",640 ## print self.name, table.name, ">>", 639 641 for row in data: 640 642 name = row[0] … … 689 691 c.sequence_name = seq_name.search(default).group(1) 690 692 c.initial = self.db.fetch("SELECT min_value FROM %s.%s" % 691 ( table.namespace, c.sequence_name),693 (self.name, c.sequence_name), 692 694 conn=conn)[0][0][0] 693 695 c.default = None … … 715 717 data, _ = self.db.fetch("SELECT c.oid FROM pg_class c LEFT JOIN " 716 718 "pg_namespace n ON c.relnamespace = n.oid WHERE " 717 "c.relname = '%s' AND n.nspname = '%s'" % 718 (table.name, table.namespace), conn=conn) 719 if not data: 720 return [] 721 719 "c.relname = '%s' AND c.relkind = 'r' " 720 "AND n.nspname = '%s'" % (table.name, self.name), 721 conn=conn) 722 722 table_OID = data[0][0] 723 723 724 indices = [] 724 725 data, _ = self.db.fetch( … … 783 784 column.sequence_name = None 784 785 785 def create_database(self): 786 c = self.db.connections._get_conn(master=True) 787 encoding = self.db.encoding 788 if encoding: 789 encoding = " WITH ENCODING '%s'" % encoding 790 self.db.execute_ddl("CREATE DATABASE %s%s" % (self.qname, encoding), c) 791 self.db.connections._del_conn(c) 792 del c 786 def create(self): 787 if self.name != "public": 788 c = self.db.connections._get_conn(master=True) 789 self.db.execute_ddl("CREATE SCHEMA %s" % self.qname, c) 790 self.db.connections._del_conn(c) 791 del c 793 792 self.clear() 794 793 795 def drop_database(self): 796 c = self.db.connections._get_conn(master=True) 797 self.db.execute_ddl("DROP DATABASE %s;" % self.qname, c) 798 self.db.connections._del_conn(c) 799 del c 794 def drop(self): 795 if self.name != "public": 796 c = self.db.connections._get_conn(master=True) 797 self.db.execute_ddl("DROP SCHEMA %s;" % self.qname, c) 798 self.db.connections._del_conn(c) 799 del c 800 800 self.clear() 801 801 … … 822 822 name = name.lower() 823 823 return name 824 824 825 def schema(self, name="public"): 826 return self.schemaclass(self, name) 827 828 def create(self): 829 c = self.connections._get_conn(master=True) 830 encoding = self.encoding 831 if encoding: 832 encoding = " WITH ENCODING '%s'" % encoding 833 self.execute_ddl("CREATE DATABASE %s%s" % (self.qname, encoding), c) 834 self.connections._del_conn(c) 835 836 def drop(self): 837 c = self.connections._get_conn(master=True) 838 self.execute_ddl("DROP DATABASE %s;" % self.qname, c) 839 self.connections._del_conn(c) 840 841 def _get_schemas(self, conn=None): 842 """Return a list of schema names.""" 843 data, _ = self.fetch("SELECT nspname FROM pg_namespace;", conn=conn) 844 return [name for name, in data if name != 'information_schema' 845 and not name.startswith('pg_')] 846 trunk/geniusql/providers/pypgsql.py
r145 r146 36 36 37 37 38 class PyPgSchema(postgres.PgSchema): 38 class PyPgDatabase(postgres.PgDatabase): 39 40 connectionmanager = PyPgConnectionManager 41 42 def __init__(self, **opts): 43 postgres.PgDatabase.__init__(self, **opts) 44 connstr = opts.get('connections.Connect', None) 45 if connstr: 46 for atom in connstr.split(" "): 47 k, v = atom.split("=", 1) 48 if k == 'dbname': 49 self.name = v 50 self.qname = self.quote(v) 39 51 40 52 def _get_dbinfo(self, conn=None): 41 53 dbinfo = {} 42 54 try: 43 data, _ = self. db.fetch("SELECT pg_encoding_to_char(encoding) "44 "FROM pg_database;", conn=conn)55 data, _ = self.fetch("SELECT pg_encoding_to_char(encoding) " 56 "FROM pg_database;", conn=conn) 45 57 dbinfo['encoding'] = data[0][0] 46 58 except libpq.DatabaseError, x: … … 48 60 raise 49 61 return dbinfo 50 51 52 class PyPgDatabase(postgres.PgDatabase):53 54 connectionmanager = PyPgConnectionManager55 schemaclass = PyPgSchema56 62 57 63 def fetch(self, sql, conn=None): trunk/geniusql/providers/sqlite.py
r145 r146 653 653 tableclass = SQLiteTable 654 654 655 def __init__(self, db, name):656 if name != ':memory:':657 if not os.path.isabs(name):658 name = os.path.join(os.getcwd(), name)659 geniusql.Schema.__init__(self, db, name)660 self.db.name = self.name661 662 def get_pragma(self, name, conn=None):663 data, _ = self.db.fetch("PRAGMA %s;" % name, conn=conn)664 return data[0][0]665 ##666 ## def _get_dbinfo(self, conn=None):667 ## dbinfo = {}668 ## for pragma in ('encoding', 'case_sensitive_like', 'locking_mode',669 ## 'page_size', 'read_uncommitted'):670 ## dbinfo[pragma] = self.get_pragma(pragma, conn)671 ## return dbinfo672 673 655 def _get_tables(self, conn=None): 674 656 data, _ = self.db.fetch("SELECT name FROM sqlite_master " … … 834 816 raise NotImplementedError 835 817 836 def create_database(self): 837 self.db.connections.get() 838 839 def drop_database(self): 840 self.db.connections.shutdown() 841 if self.name != ":memory:": 842 # This should accept relative or absolute paths 843 os.remove(self.name) 844 self.clear() 818 def drop(self): 819 """Drop this schema from the database.""" 820 if self.db.name == ':memory:': 821 # Not much we can do, here. If we try to drop a table, we end 822 # up stuck in "database schema has changed"-land forever. 823 # Just assume for now we're going to drop the whole database. 824 self.db.drop() 825 self.db.create() 826 else: 827 # Must shut down all connections to avoid 828 # "being accessed by other users" error. 829 self.db.connections.shutdown() 830 831 seen = {} 832 for tkey, table in self.items(): 833 # We might have multiple keys pointing at the same table. 834 if table.name not in seen: 835 del self[tkey] 836 seen[table.name] = None 845 837 846 838 … … 865 857 def __init__(self, **kwargs): 866 858 kwargs['mode'] = int(kwargs.pop('mode', '0755'), 8) 859 860 if kwargs['name'] != ':memory:': 861 if not os.path.isabs(kwargs['name']): 862 kwargs['name'] = os.path.join(os.getcwd(), kwargs['name']) 863 867 864 geniusql.Database.__init__(self, **kwargs) 865 866 ## def _get_dbinfo(self, conn=None): 867 ## dbinfo = {} 868 ## for pragma in ('encoding', 'case_sensitive_like', 'locking_mode', 869 ## 'page_size', 'read_uncommitted'): 870 ## dbinfo[pragma] = self.get_pragma(pragma, conn) 871 ## return dbinfo 872 873 def get_pragma(self, name, conn=None): 874 data, _ = self.fetch("PRAGMA %s;" % name, conn=conn) 875 return data[0][0] 876 877 def create(self): 878 self.connections._set_factory() 879 self.connections.get() 880 881 def drop(self): 882 self.connections.shutdown() 883 if self.name != ":memory:": 884 # This should accept relative or absolute paths 885 os.remove(self.name) 868 886 869 887 def quote(self, name): … … 946 964 return "SQLite Version: %s" % _version 947 965 948 def schema(self, name ):966 def schema(self, name=None): 949 967 s = self.schemaclass(self, name) 950 self.name = name951 self.connections._set_factory()952 968 return s 953 969 trunk/geniusql/providers/sqlserver.py
r145 r146 364 364 # 132: USERDEFINED, 133: DBDATE, 134: DBTIME, 365 365 } 366 367 def __init__(self, db, name=None): 368 if name is None: 369 name = 'dbo' 370 geniusql.Schema.__init__(self, db, name) 366 371 367 372 def _get_columns(self, table, conn=None): … … 442 447 return cols 443 448 444 def create_database(self): 445 conn = self.db.connections._get_conn(master=True) 446 self.db.execute_ddl("CREATE DATABASE %s;" % self.qname, conn) 447 conn.Close() 449 def create(self): 448 450 self.clear() 449 451 450 def drop_database(self): 451 conn = self.db.connections._get_conn(master=True) 452 self.db.execute_ddl("DROP DATABASE %s;" % self.qname, conn) 453 conn.Close() 452 def drop(self): 454 453 self.clear() 455 454 … … 499 498 return "ADO Version: %s\n%s" % (adov, sqlv) 500 499 500 def create(self): 501 conn = self.connections._get_conn(master=True) 502 self.execute_ddl("CREATE DATABASE %s;" % self.qname, conn) 503 conn.Close() 504 505 def drop(self): 506 conn = self.connections._get_conn(master=True) 507 self.execute_ddl("DROP DATABASE %s;" % self.qname, conn) 508 conn.Close() 509 501 510 def is_timeout_error(self, exc): 502 511 """If the given exception instance is a lock timeout, return True. trunk/geniusql/test/benchmark.py
r145 r146 266 266 try: 267 267 db = geniusql.db(provider, **opts) 268 print db.version() 269 db.create() 268 270 schema = db.schema(name) 269 print db.version() 270 schema.create_database() 271 schema.create() 271 272 272 273 db.connections.implicit_trans = True trunk/geniusql/test/test_firebird.py
r145 r146 33 33 reload(zoo_fixture) 34 34 try: 35 zoo_fixture.run(DB_class, opts ['name'], opts)35 zoo_fixture.run(DB_class, opts) 36 36 except kinterbasdb.OperationalError, e: 37 37 if e.args[0] == -902 and 'Failed to establish a connection' in e.args[1]: trunk/geniusql/test/test_msaccess.py
r145 r146 19 19 opts = {'connections.Connect': 20 20 "PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=zoo.mdb;", 21 'name': 'zoo.mdb', 21 22 } 22 23 … … 44 45 print "Standard MSAccess test." 45 46 ## zoo_fixture.ZooTests.test_currency = test_currency_dbtypes 46 zoo_fixture.run(DB_class, "zoo.mdb",opts)47 zoo_fixture.run(DB_class, opts) 47 48 48 49 if currency: … … 56 57 # plugin the adapter for testing CURRENCY columns 57 58 opts['typeadapter'] = CurrencyAdapter() 58 zoo_fixture.run(DB_class, "zoo.mdb",opts)59 zoo_fixture.run(DB_class, opts) 59 60 del opts['typeadapter'] 60 61 … … 68 69 print "MSAccess test - CURRENCY returned as Decimal." 69 70 zoo_fixture.ZooTests.test_currency = test_currency_dbtypes 70 zoo_fixture.run(DB_class, "zoo.mdb",opts)71 zoo_fixture.run(DB_class, opts) 71 72 72 73 trunk/geniusql/test/test_mysql.py
r145 r146 24 24 opts['encoding'] = "latin1" 25 25 reload(zoo_fixture) 26 zoo_fixture.run(DB_class, 'geniusql_test',opts)26 zoo_fixture.run(DB_class, opts) 27 27 28 28 print … … 30 30 opts['encoding'] = "utf8" 31 31 reload(zoo_fixture) 32 zoo_fixture.run(DB_class, 'geniusql_test',opts)32 zoo_fixture.run(DB_class, opts) 33 33 34 34 if __name__ == "__main__": trunk/geniusql/test/test_pypgsql.py
r145 r146 17 17 ("host=localhost dbname=geniusql_test user=%s password=%s" 18 18 % (user, passwd)), 19 'name': 'geniusql_test', 19 20 } 20 21 DB_class = "postgres" … … 29 30 opts['encoding'] = "SQL_ASCII" 30 31 reload(zoo_fixture) 31 zoo_fixture.run(DB_class, 'geniusql_test',opts)32 zoo_fixture.run(DB_class, opts) 32 33 33 34 print … … 35 36 opts['encoding'] = "UNICODE" 36 37 reload(zoo_fixture) 37 zoo_fixture.run(DB_class, 'geniusql_test',opts)38 zoo_fixture.run(DB_class, opts) 38 39 39 40 if __name__ == "__main__": trunk/geniusql/test/test_sqlite.py
r145 r146 22 22 if _sqlite: 23 23 DB_class = "sqlite" 24 opts = {}25 24 26 25 def run(memonly=False): … … 30 29 print "Testing SQLite ':memory:' database..." 31 30 reload(zoo_fixture) 32 zoo_fixture.run(DB_class, ':memory:', opts)31 zoo_fixture.run(DB_class, {'name': ':memory:'}) 33 32 34 33 if not memonly: … … 37 36 print "Testing SQLite file database..." 38 37 reload(zoo_fixture) 39 zoo_fixture.run(DB_class, dbpath, opts)38 zoo_fixture.run(DB_class, {'name': dbpath}) 40 39 41 40 if __name__ == "__main__": trunk/geniusql/test/test_sqlserver.py
r145 r146 29 29 # Isolate schema changes from one test to the next. 30 30 reload(zoo_fixture) 31 zoo_fixture.run(DB_class, "geniusql_test",opts)31 zoo_fixture.run(DB_class, opts) 32 32 33 33 if __name__ == "__main__": trunk/geniusql/test/zoo_fixture.py
r145 r146 1349 1349 f.close() 1350 1350 1351 def setup(provider, name,opts):1351 def setup(provider, opts): 1352 1352 """Set up storage for Zoo classes.""" 1353 1353 global db, schema 1354 1354 db = geniusql.db(provider, **opts) 1355 schema = db.schema(name)1356 1355 db.log = _geniusqllog 1357 1356 print db.version() 1358 schema.create_database() 1357 db.create() 1358 1359 schema = db.schema() 1360 schema.create() 1359 1361 1360 1362 def teardown(): 1361 1363 """Tear down storage for Zoo classes.""" 1362 1364 try: 1363 schema.drop_database() 1365 schema.drop() 1366 except (AttributeError, NotImplementedError): 1367 pass 1368 try: 1369 db.drop() 1364 1370 except (AttributeError, NotImplementedError): 1365 1371 pass 1366 1372 db.connections.shutdown() 1367 1373 1368 def run(DB_class, name,opts):1374 def run(DB_class, opts): 1369 1375 """Run the zoo fixture.""" 1370 1376 skiptests = [x[7:] for x in sys.argv if x.startswith("--skip_")] … … 1372 1378 try: 1373 1379 try: 1374 setup(DB_class, name,opts)1380 setup(DB_class, opts) 1375 1381 loader = unittest.TestLoader().loadTestsFromTestCase 1376 1382 … … 1389 1395 # Each thread opens a new SQLite :memory: database, 1390 1396 # so the concept of "isolation" is pretty meaningless. 1391 if name!= ':memory:' and 'isolation' not in skiptests:1397 if opts.get('name') != ':memory:' and 'isolation' not in skiptests: 1392 1398 tools.TestRunner.run(loader(IsolationTests)) 1393 1399
