]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added _with_options() to Connection. not publicizing this yet.
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 18 Dec 2009 20:41:34 +0000 (20:41 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 18 Dec 2009 20:41:34 +0000 (20:41 +0000)
- updated oursql driver with latest fixes using options. [ticket:1613]
- all the MySQL drivers get a shoutout in the docs
- marked tests that OurSQL has problems with (only three), passes 100% now

doc/build/reference/dialects/mysql.rst
lib/sqlalchemy/dialects/mysql/oursql.py
lib/sqlalchemy/dialects/mysql/pyodbc.py
lib/sqlalchemy/engine/base.py
test/engine/test_transaction.py
test/orm/test_unitofwork.py

index 839b8cae075f2f9828423259f229ec5bb797bf2b..c310f6c52419f0c51a6a2756259ae9db1d661827 100644 (file)
@@ -138,11 +138,26 @@ MySQL Column Types
    :members: __init__
    :show-inheritance:
 
-MySQLdb Notes
+MySQL-Python Notes
 --------------
 
 .. automodule:: sqlalchemy.dialects.mysql.mysqldb
 
+OurSQL Notes
+--------------
+
+.. automodule:: sqlalchemy.dialects.mysql.oursql
+
+MyConnPY Notes
+--------------
+
+.. automodule:: sqlalchemy.dialects.mysql.myconnpy
+
+pyodbc Notes
+--------------
+
+.. automodule:: sqlalchemy.dialects.mysql.pyodbc
+
 zxjdbc Notes
 --------------
 
index 79a36f535bf60cd5f613b13e9eba35afce4dd60b..70bec53a3c08481c563135a5e407185fe76e2137 100644 (file)
@@ -31,10 +31,6 @@ from sqlalchemy.sql import operators as sql_operators
 from sqlalchemy import exc, log, schema, sql, types as sqltypes, util
 
 
-class _PlainQuery(unicode): 
-    pass
-
-
 class _oursqlNumeric(NUMERIC):
     def result_processor(self, dialect, coltype):
         if self.asdecimal:
@@ -53,12 +49,21 @@ class _oursqlBIT(BIT):
 
         return None
 
+
+class MySQL_oursqlExecutionContext(MySQLExecutionContext):
+    
+    @property
+    def plain_query(self):
+        return self._connection.options.get('plain_query', False)
+
+
 class MySQL_oursql(MySQLDialect):
     driver = 'oursql'
     supports_unicode_statements = True
     supports_unicode_binds = True
     supports_sane_rowcount = True
     supports_sane_multi_rowcount = True
+    execution_ctx_cls = MySQL_oursqlExecutionContext
     
     colspecs = util.update_copy(
         MySQLDialect.colspecs,
@@ -76,7 +81,7 @@ class MySQL_oursql(MySQLDialect):
     def do_execute(self, cursor, statement, parameters, context=None):
         """Provide an implementation of *cursor.execute(statement, parameters)*."""
         
-        if context and not context.compiled and isinstance(context.statement, _PlainQuery):
+        if context and context.plain_query:
             cursor.execute(statement, plain_query=True)
         else:
             cursor.execute(statement, parameters)
@@ -85,7 +90,7 @@ class MySQL_oursql(MySQLDialect):
         connection.cursor().execute('BEGIN', plain_query=True)
 
     def _xa_query(self, connection, query, xid):
-        connection.execute(_PlainQuery(query % connection.connection._escape_string(xid)))
+        connection._with_options(plain_query=True).execute(query % connection.connection._escape_string(xid))
 
     # Because mysql is bad, these methods have to be reimplemented to use _PlainQuery. Basically, some queries
     # refuse to return any data if they're run through the parameterized query API, or refuse to be parameterized
@@ -110,49 +115,13 @@ class MySQL_oursql(MySQLDialect):
         self._xa_query(connection, 'XA COMMIT "%s"', xid)
 
     def has_table(self, connection, table_name, schema=None):
-        full_name = '.'.join(self.identifier_preparer._quote_free_identifiers(
-            schema, table_name))
-
-        st = "DESCRIBE %s" % full_name
-        rs = None
-        try:
-            try:
-                rs = connection.execute(_PlainQuery(st))
-                have = rs.rowcount > 0
-                rs.close()
-                return have
-            except exc.SQLError, e:
-                if self._extract_error_code(e) == 1146:
-                    return False
-                raise
-        finally:
-            if rs:
-                rs.close()
+        return MySQLDialect.has_table(self, connection._with_options(plain_query=True), table_name, schema)
 
     def _show_create_table(self, connection, table, charset=None,
                            full_name=None):
-        """Run SHOW CREATE TABLE for a ``Table``."""
-
-        if full_name is None:
-            full_name = self.identifier_preparer.format_table(table)
-        st = "SHOW CREATE TABLE %s" % full_name
-
-        rp = None
-        try:
-            try:
-                rp = connection.execute(_PlainQuery(st))
-            except exc.SQLError, e:
-                if self._extract_error_code(e) == 1146:
-                    raise exc.NoSuchTableError(full_name)
-                else:
-                    raise
-            row = rp.fetchone()
-            if not row:
-                raise exc.NoSuchTableError(full_name)
-            return row[1].strip()
-        finally:
-            if rp:
-                rp.close()
+        return MySQLDialect._show_create_table(self, 
+            connection.contextual_connect(close_with_result=True)._with_options(plain_query=True), 
+            table, charset, full_name)
 
     def is_disconnect(self, e):
         if isinstance(e, self.dbapi.ProgrammingError):  # if underlying connection is closed, this is the error you get
index 96171ee0b5888fa4f75f7bc8faa2db0ae039e1da..7cb2f36428b3e348d3e912f3a84d4d39685eebfd 100644 (file)
@@ -1,3 +1,7 @@
+"""Support for the MySQL database via the pyodbc adapter.
+
+"""
+
 from sqlalchemy.dialects.mysql.base import MySQLDialect, MySQLExecutionContext
 from sqlalchemy.connectors.pyodbc import PyODBCConnector
 from sqlalchemy.engine import base as engine_base
index ddf2602c2d13c39a4724f3e637262ed62402b73f..3fbc23312b9528ae264dcd3fa9f58dfc939907f0 100644 (file)
@@ -706,9 +706,10 @@ class Connection(Connectable):
     .. index::
       single: thread safety; Connection
     """
-
+    options = {}
+    
     def __init__(self, engine, connection=None, close_with_result=False,
-                 _branch=False):
+                 _branch=False, _options=None):
         """Construct a new Connection.
 
         Connection objects are typically constructed by an
@@ -723,6 +724,8 @@ class Connection(Connectable):
         self.__savepoint_seq = 0
         self.__branch = _branch
         self.__invalid = False
+        if _options:
+            self.options = _options
 
     def _branch(self):
         """Return a new Connection which references this Connection's
@@ -734,7 +737,22 @@ class Connection(Connectable):
         """
 
         return self.engine.Connection(self.engine, self.__connection, _branch=True)
-
+    
+    def _with_options(self, **opt):
+        """Add keyword options to a Connection generatively.
+        
+        Experimental.  May change the name/signature at 
+        some point.
+        
+        If made public, strongly consider the name
+        "options()" so as to be consistent with
+        orm.Query.options().
+        
+        """
+        return self.engine.Connection(
+                    self.engine, self.__connection,
+                     _branch=self.__branch, _options=opt)
+        
     @property
     def dialect(self):
         "Dialect used by this Connection."
index 82b767b0eb79d0f9d8cf79f83005c100cc758cf5..c51623f2cd921ebbf78d06d71fb924c04703d65d 100644 (file)
@@ -279,6 +279,7 @@ class TransactionTest(TestBase):
         connection.close()
 
     @testing.requires.two_phase_transactions
+    @testing.crashes('mysql+oursql', 'Times out in full test runs only, causing subsequent tests to fail')
     @testing.crashes('mysql+zxjdbc', 'Deadlocks, causing subsequent tests to fail')
     @testing.fails_on('mysql', 'FIXME: unknown')
     def test_two_phase_recover(self):
index 6b628d8264ad964f4f072eb299891c78f3b03258..85a0eae82137e901e2ee03736b576aa855086e6a 100644 (file)
@@ -200,6 +200,7 @@ class UnicodeTest(_base.MappedTest):
         class Test2(_base.BasicEntity):
             pass
 
+    @testing.fails_on('mysql+oursql', 'raises a warning')
     @testing.resolve_artifact_names
     def test_basic(self):
         mapper(Test, uni_t1)
@@ -213,7 +214,8 @@ class UnicodeTest(_base.MappedTest):
         session.commit()
 
         self.assert_(t1.txt == txt)
-
+    
+    @testing.fails_on('mysql+oursql', 'raises a warning')
     @testing.resolve_artifact_names
     def test_relation(self):
         mapper(Test, uni_t1, properties={