]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 27 Oct 2005 05:12:52 +0000 (05:12 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 27 Oct 2005 05:12:52 +0000 (05:12 +0000)
doc/style.css
lib/sqlalchemy/ansisql.py
lib/sqlalchemy/databases/oracle.py
lib/sqlalchemy/engine.py
lib/sqlalchemy/sql.py
test/select.py

index ddef5196d81cd1a2d458117206c4c86e42f87715..858a5571903d5bac863de935bc3ea3dee4ff7504 100644 (file)
@@ -114,8 +114,9 @@ a:hover {color:#700000;}
 .codepoplink {
        font-weight:bold;
        font-family: verdana, sans-serif;
-       font-size:12px;
+       font-size:11px;
        color:#000000;
        border:1px solid;
-       padding:2px 8px 2px 8px;
+       padding:1px 2px 1px 2px;
+       margin:0px 0px 0px 15px;
 }
index 963e52a1f463577e7770207161c7713ecb7895ee..22ea7e61d307048250d8dd8b5938343fddf7c49c 100644 (file)
@@ -37,8 +37,8 @@ class ANSISQLEngine(sqlalchemy.engine.SQLEngine):
     def schemadropper(self, proxy, **params):
         return ANSISchemaDropper(proxy, **params)
 
-    def compiler(self, statement, bindparams):
-        return ANSICompiler(self, statement, bindparams)
+    def compiler(self, statement, bindparams, **kwargs):
+        return ANSICompiler(self, statement, bindparams, **kwargs)
     
     def connect_args(self):
         return ([],{})
index ff5178a0f479430a5e27a46dd846868c386076e3..696c59dda861fbcf9a43633b0efa0ed640e8c3b5 100644 (file)
@@ -94,7 +94,7 @@ class OracleSQLEngine(ansisql.ANSISQLEngine):
         return "rowid"
 
     def compiler(self, statement, bindparams, **kwargs):
-        return OracleCompiler(self, statement, bindparams, **kwargs)
+        return OracleCompiler(self, statement, bindparams, use_ansi=self._use_ansi, **kwargs)
 
     def schemagenerator(self, proxy, **params):
         return OracleSchemaGenerator(proxy, **params)
@@ -153,8 +153,10 @@ class OracleCompiler(ansisql.ANSICompiler):
             
         self.froms[join] = self.get_from_text(join.left) + ", " + self.get_from_text(join.right)
         self.wheres[join] = join.onclause
-        
+
+        print "check1"
         if join.isouter:
+            print "check2"
             # if outer join, push on the right side table as the current "outertable"
             outertable = self._outertable
             self._outertable = join.right
index c9bdf893b444728c329c47cce326afe00a17e2c4..0175a1c7bb864ddac349f8edd2fe27263eb5c9d7 100644 (file)
@@ -15,8 +15,7 @@
 # along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-"""builds upon the schema and sql packages to provide a central object for tying schema objects
-and sql constructs to database-specific query compilation and execution"""
+"""builds upon the schema and sql packages to provide a central object for tying schema objects and sql constructs to database-specific query compilation and execution"""
 
 import sqlalchemy.schema as schema
 import sqlalchemy.pool
@@ -26,30 +25,37 @@ import StringIO, sys
 import sqlalchemy.types as types
 
 def create_engine(name, *args ,**kwargs):
+    """creates a new SQLEngine instance.
+    
+    name - the type of engine to load, i.e. 'sqlite', 'postgres', 'oracle'
+    *args, **kwargs - sent directly to the specific engine instance as connect arguments, options.
+    """
     module = getattr(__import__('sqlalchemy.databases.%s' % name).databases, name)
     return module.engine(*args, **kwargs)
 
 class SchemaIterator(schema.SchemaVisitor):
     """a visitor that can gather text into a buffer and execute the contents of the buffer."""
     def __init__(self, sqlproxy, **params):
+        """initializes this SchemaIterator and initializes its buffer.
+        
+        sqlproxy - a callable function returned by SQLEngine.proxy(), which executes a statement plus optional parameters.
+        """
         self.sqlproxy = sqlproxy
         self.buffer = StringIO.StringIO()
 
-    def run(self):
-        raise NotImplementedError()
-
     def append(self, s):
+        """appends content to the SchemaIterator's query buffer."""
         self.buffer.write(s)
         
     def execute(self):
+        """executes the contents of the SchemaIterator's buffer using its sql proxy and clears out the buffer."""
         try:
             return self.sqlproxy(self.buffer.getvalue())
         finally:
             self.buffer.truncate(0)
 
 class SQLEngine(schema.SchemaEngine):
-    """base class for a series of database-specific engines.  serves as an abstract factory for
-    implementation objects as well as database connections, transactions, SQL generators, etc."""
+    """base class for a series of database-specific engines.  serves as an abstract factory for implementation objects as well as database connections, transactions, SQL generators, etc."""
     
     def __init__(self, pool = None, echo = False, logger = None, **params):
         # get a handle on the connection pool via the connect arguments
@@ -89,30 +95,34 @@ class SQLEngine(schema.SchemaEngine):
         return "oid"
 
     def create(self, table, **params):
+        """creates a table given a schema.Table object."""
         table.accept_visitor(self.schemagenerator(self.proxy(), **params))
 
     def drop(self, table, **params):
+        """drops a table given a schema.Table object."""
         table.accept_visitor(self.schemadropper(self.proxy(), **params))
 
     def compile(self, statement, bindparams, **kwargs):
+        """given a sql.ClauseElement statement plus optional bind parameters, creates a new instance of this engine's SQLCompiler, compiles the ClauseElement, and returns the newly compiled object."""
         compiler = self.compiler(statement, bindparams, **kwargs)
         statement.accept_visitor(compiler)
         return compiler
 
     def reflecttable(self, table):
+        """given a Table object, reflects its columns and properties from the database."""
         raise NotImplementedError()
 
     def tableimpl(self, table):
+        """returns a new sql.TableImpl object to correspond to the given Table object."""
         return sql.TableImpl(table)
 
     def columnimpl(self, column):
-        return sql.ColumnSelectable(column)
+        """returns a new sql.ColumnImpl object to correspond to the given Column object."""
+        return sql.ColumnImpl(column)
 
     def last_inserted_ids(self):
         """returns a thread-local list of the primary keys for the last insert statement executed.
-        This does not apply to straight textual clauses; only to sql.Insert objects compiled against 
-        a schema.Table object, which are executed via statement.execute().  The order of items in the list
-        is the same as that of the Table's 'primary_keys' attribute."""
+        This does not apply to straight textual clauses; only to sql.Insert objects compiled against a schema.Table object, which are executed via statement.execute().  The order of items in the list is the same as that of the Table's 'primary_keys' attribute."""
         raise NotImplementedError()
 
     def connect_args(self):
index a56beeb3e707383c7f7e8bbe8679f7236580ad94..e7f8a8ae17eae4422a0d1e1e9dc89d2caff39de3 100644 (file)
@@ -301,7 +301,7 @@ class CompareMixin(object):
     def in_(self, *other):
         if len(other) == 0:
             return self.__eq__(None)
-        elif len(other) == 1:
+        elif len(other) == 1 and not isinstance(other[0], Selectable):
             return self.__eq__(other[0])
         elif _is_literal(other[0]):
             return self._compare('IN', CompoundClause(',', other))
@@ -321,7 +321,7 @@ class ColumnClause(ClauseElement, CompareMixin):
     def __init__(self, text, selectable):
         self.text = text
         self.table = selectable
-        self._impl = ColumnSelectable(self)
+        self._impl = ColumnImpl(self)
         self.type = types.NullTypeEngine()
         
     columns = property(lambda self: [self])
@@ -355,7 +355,7 @@ class ColumnClause(ClauseElement, CompareMixin):
     def _make_proxy(self, selectable, name = None):
         c = ColumnClause(self.text or name, selectable)
         selectable.columns[c.key] = c
-        c._impl = ColumnSelectable(c)
+        c._impl = ColumnImpl(c)
         return c
 
 class FromClause(ClauseElement):
@@ -494,8 +494,7 @@ class BinaryClause(ClauseElement):
         self.right = c
         
 class Selectable(FromClause):
-    """represents a column list-holding object, like a table or subquery.  can be used anywhere
-    a Table is used."""
+    """represents a column list-holding object, like a table, alias or subquery.  can be used anywhere a Table is used."""
     
     c = property(lambda self: self.columns)
 
@@ -503,7 +502,7 @@ class Selectable(FromClause):
         raise NotImplementedError()
     
     def select(self, whereclauses = None, **params):
-        raise NotImplementedError()
+        return select([self], whereclauses, **params)
 
     def join(self, right, *args, **kwargs):
         return Join(self, right, *args, **kwargs)
@@ -534,10 +533,9 @@ class Join(Selectable):
         
     primary_keys = property (lambda self: [c for c in self.left.columns if c.primary_key] + [c for c in self.right.columns if c.primary_key])
 
-
     def group_parenthesized(self):
         """indicates if this Selectable requires parenthesis when grouped into a compound statement"""
-        return False
+        return True
 
     def hash_key(self):
         return "Join(%s, %s, %s, %s)" % (repr(self.left.hash_key()), repr(self.right.hash_key()), repr(self.onclause.hash_key()), repr(self.isouter))
@@ -593,12 +591,10 @@ class Alias(Selectable):
         
     engine = property(lambda s: s.selectable.engine)
 
-    def select(self, whereclauses = None, **params):
-        return select([self], whereclauses, **params)
 
 
 
-class ColumnSelectable(Selectable, CompareMixin):
+class ColumnImpl(Selectable, CompareMixin):
     """Selectable implementation that gets attached to a schema.Column object."""
     
     def __init__(self, column):
@@ -613,6 +609,8 @@ class ColumnSelectable(Selectable, CompareMixin):
             self.label = self.column.name
             self.fullname = self.column.name
 
+    engine = property(lambda s: s.column.engine)
+    
     def copy_container(self):
         return self.column
 
@@ -696,6 +694,7 @@ class Select(Selectable):
         self.name = None
         self.whereclause = whereclause
         self._engine = engine
+        self.rowid_column = None
         
         # indicates if this select statement is a subquery inside of a WHERE clause
         # note this is different from a subquery inside the FROM list
@@ -728,6 +727,8 @@ class Select(Selectable):
 
         for f in column._get_from_objects():
             self.froms.setdefault(f.id, f)
+            if self.rowid_column is None and hasattr(f, 'rowid_column'):
+                self.rowid_column = f.rowid_column._make_proxy(self)
 
         for co in column.columns:
             if self.use_labels:
index 0549d209306375fac6e8a2acf4b0d28039a0ef14..4db9447454cfbe61a57feaf0847154e2f6b9cf39 100644 (file)
@@ -35,7 +35,7 @@ class SQLTest(PersistTest):
         c = clause.compile(engine, params)
         self.echo("\n" + str(c) + repr(c.get_params()))
         cc = re.sub(r'\n', '', str(c))
-        self.assert_(cc == result)
+        self.assert_(cc == result, str(c) + "\n does not match \n" + result)
 
 class SelectTest(SQLTest):
 
@@ -271,10 +271,10 @@ FROM myothertable UNION SELECT thirdtable.userid, thirdtable.otherstuff FROM thi
         self.runtest(query, 
             "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername \
 FROM mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid \
-WHERE mytable.name = :mytable_name AND mytable.myid = :mytable_myid AND \
-myothertable.othername != :myothertable_othername AND \
+WHERE mytable.name = %(mytable_name)s AND mytable.myid = %(mytable_myid)s AND \
+myothertable.othername != %(myothertable_othername)s AND \
 EXISTS (select yay from foo where boo = lar)",
-            engine = postgres.engine())
+            engine = postgres.engine({}))
 
 
         self.runtest(query, 
@@ -282,7 +282,7 @@ EXISTS (select yay from foo where boo = lar)",
 FROM mytable, myothertable WHERE mytable.myid = myothertable.otherid(+) AND \
 mytable.name = :mytable_name AND mytable.myid = :mytable_myid AND \
 myothertable.othername != :myothertable_othername AND EXISTS (select yay from foo where boo = lar)",
-            engine = oracle.engine(use_ansi = False))
+            engine = oracle.engine({}, use_ansi = False))
 
     def testbindparam(self):
         self.runtest(select(