]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Aug 2005 02:33:56 +0000 (02:33 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Aug 2005 02:33:56 +0000 (02:33 +0000)
doc/build/content/adv_datamapping.myt [new file with mode: 0644]
doc/build/content/datamapping.myt [new file with mode: 0644]
doc/build/content/dbengine.myt [new file with mode: 0644]
doc/build/content/document_base.myt
doc/build/content/metadata.myt [new file with mode: 0644]
doc/build/content/pooling.myt [new file with mode: 0644]
doc/build/content/roadmap.myt [new file with mode: 0644]
doc/build/content/sqlconstruction.myt [new file with mode: 0644]
doc/style.css
lib/sqlalchemy/mapper.py
lib/sqlalchemy/sql.py

diff --git a/doc/build/content/adv_datamapping.myt b/doc/build/content/adv_datamapping.myt
new file mode 100644 (file)
index 0000000..c3d5324
--- /dev/null
@@ -0,0 +1,3 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="adv_datamapping", description="Advanced Data Mapping" &>
+</&>
\ No newline at end of file
diff --git a/doc/build/content/datamapping.myt b/doc/build/content/datamapping.myt
new file mode 100644 (file)
index 0000000..56c1037
--- /dev/null
@@ -0,0 +1,3 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="datamapping", description="Basic Data Mapping" &>
+</&>
\ No newline at end of file
diff --git a/doc/build/content/dbengine.myt b/doc/build/content/dbengine.myt
new file mode 100644 (file)
index 0000000..929059e
--- /dev/null
@@ -0,0 +1,7 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="dbengine", description="Database Engines" &>
+    <&|doclib.myt:item, name="establishing", description="Establishing a Database Engine" &>
+    </&>
+    <&|doclib.myt:item, name="options", description="Database Engine Options" &>
+    </&>
+</&>
\ No newline at end of file
index 35c41d545f9c8b445c4a8e2689b4fefe0d7af5a5..6a692d623bf15b8e3fff08275f43fa5794d01b58 100644 (file)
@@ -3,7 +3,15 @@
 <%python scope="global">
 
        files = [
-               'coolthings'
+               'roadmap',
+               'pooling',
+               'dbengine',
+               'metadata',
+               'sqlconstruction',
+               'datamapping',
+               'adv_datamapping',
+               'activerecord',
+               
                ]
 
 </%python>
diff --git a/doc/build/content/metadata.myt b/doc/build/content/metadata.myt
new file mode 100644 (file)
index 0000000..4468c77
--- /dev/null
@@ -0,0 +1,7 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="metadata", description="Database Meta Data" &>
+    <&|doclib.myt:item, name="tables", description="Describing Tables with Database Meta Data" &>
+    </&>
+    <&|doclib.myt:item, name="building", description="Building and Dropping Database Tables" &>
+    </&>
+</&>
\ No newline at end of file
diff --git a/doc/build/content/pooling.myt b/doc/build/content/pooling.myt
new file mode 100644 (file)
index 0000000..e76c369
--- /dev/null
@@ -0,0 +1,3 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="pooling", description="Connection Pooling" &>
+</&>
\ No newline at end of file
diff --git a/doc/build/content/roadmap.myt b/doc/build/content/roadmap.myt
new file mode 100644 (file)
index 0000000..deed372
--- /dev/null
@@ -0,0 +1,39 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="roadmap", description="Roadmap" &>
+<p>SQLAlchemy includes several components, each of which are useful by themselves to give varying levels of assistance to a database-enabled application.  Below is a roadmap of the "knowledge dependencies" between these components indicating the order in which concepts may be learned.  
+</p>
+
+<pre>
+Start
+  |
+  |
+  |--- Establishing Transparent Connection Pooling
+  |              |
+  |              |
+  |              |------ Connection Pooling Configuration
+  |                                         |              
+  |                                         |
+  |--- <&formatting.myt:link, path="dbengine_establishing" &>       |
+                   |                        |
+                   |                        | 
+                   |--------- <&formatting.myt:link, path="dbengine_options" &>
+                   |
+                   |
+                   |---- <&formatting.myt:link, path="metadata_tables" &>
+                                   |
+                                   |
+                                   |---- <&formatting.myt:link, path="metadata_building" &>
+                                   | 
+                                   |    
+                                   |---- <&formatting.myt:link, path="sql" &>
+                                   |                                      |                
+                                   |                                      |                                  
+                                   |---- Basic Data Mapping               |                
+                                   |               |                      |  
+                                   |               |                      |              
+                                   |               |----------- Advanced Data Mapping
+                                   |                                        
+                                   |                
+                                   |----- Basic Active Record
+</pre>
+</&>
\ No newline at end of file
diff --git a/doc/build/content/sqlconstruction.myt b/doc/build/content/sqlconstruction.myt
new file mode 100644 (file)
index 0000000..8bd903f
--- /dev/null
@@ -0,0 +1,3 @@
+<%flags>inherit='document_base.myt'</%flags>
+<&|doclib.myt:item, name="sql", description="Constructing SQL Queries via Python Expressions" &>
+</&>
\ No newline at end of file
index 5471ead18e7f677a84a95d5a795308996c0a0a0f..64090d63953d81f69d29afc7feefd78477581d69 100644 (file)
@@ -1,4 +1,4 @@
-body, td {
+body, td, .normaltype {
        font-family: verdana, sans-serif;
        font-size: 12px;
 }
index 8e7b04473f1963a30d43635d5cea6a6216ccb16a..28d42792f834b18b50f42eeca37dd30bc9325ecb 100644 (file)
@@ -49,8 +49,14 @@ def relation_loader(mapper, secondary = None, primaryjoin = None, secondaryjoin
 def relation_mapper(class_, selectable, secondary = None, primaryjoin = None, secondaryjoin = None, table = None, properties = None, lazy = True, **options):
     return relation_loader(mapper(class_, selectable, table = table, properties = properties, isroot = False, **options), secondary, primaryjoin, secondaryjoin, lazy = lazy, **options)
 
+_mappers = {}
 def mapper(*args, **params):
-    return Mapper(*args, **params)
+    hashkey = mapper_hash_key(*args, **params)
+    print "HASHKEY: " + hashkey
+    try:
+        return _mappers[hashkey]
+    except KeyError:
+        return _mappers.setdefault(hashkey, Mapper(*args, **params))
 
 def identitymap():
     return IdentityMap()
@@ -84,6 +90,7 @@ class Mapper(object):
         else:
             self.identitymap = _global_identitymap
 
+        self.properties = properties
         if properties is not None:
             for key, value in properties.iteritems():
                 self.props[key] = value
@@ -91,6 +98,17 @@ class Mapper(object):
         if isroot:
             self.init(self)
     
+    def hash_key(self):
+        return mapper_hash_key(
+            self.class_,
+            self.selectable,
+            self.table,
+            self.properties,
+            self.identitymap,
+            self.use_smart_properties,
+            self.echo
+        )
+    
     def set_property(self, key, prop):
         self.props[key] = prop
         prop.init(key, self, self.root)
@@ -125,12 +143,17 @@ class Mapper(object):
     
     def options(self, *options):
         """uses this mapper as a prototype for a new mapper with different behavior.
-        
         *options is a list of options directives, which include eagerload() and lazyload()"""
-        mapper = copy.copy(self)
-        for option in options:
-            option.process(mapper)
-        return mapper
+        
+        hashkey = hash_key(self) + "->" + repr([hash_key(o) for o in options])
+        print "HASHKEY: " + hashkey
+        try:
+            return _mappers[hashkey]
+        except KeyError:
+            mapper = copy.copy(self)
+            for option in options:
+                option.process(mapper)
+            return _mappers.setdefault(hashkey, mapper)
         
     def select(self, arg = None, **params):
         """selects instances of the object from the database.  
@@ -253,6 +276,9 @@ class Mapper(object):
 class MapperOption:
     def process(self, mapper):
         raise NotImplementedError()
+    
+    def hash_key(self):
+        return repr(self)
 
 class MapperProperty:
     """an element attached to a Mapper that describes the loading and population
@@ -262,6 +288,11 @@ class MapperProperty:
         to the row. """
         raise NotImplementedError()
 
+    def hash_key(self):
+        """describes this property and its instantiated arguments in such a way
+        as to uniquely identify the concept this MapperProperty represents"""
+        raise NotImplementedError()
+
     def setup(self, key, primarytable, statement, **options):
         """called when a statement is being constructed.  """
         return self
@@ -281,6 +312,9 @@ class ColumnProperty(MapperProperty):
     def __init__(self, column):
         self.column = column
 
+    def hash_key(self):
+        return "ColumnProperty(%s)" % hash_key(self.column)
+        
     def init(self, key, parent, root):
         self.key = key
         if root.use_smart_properties:
@@ -298,14 +332,42 @@ class ColumnProperty(MapperProperty):
                 setattr(instance, self.key, row[self.column.label])
 
 
+def hash_key(obj):
+    if obj is None:
+        return 'None'
+    else:
+        return obj.hash_key()
+
+def mapper_hash_key(class_, selectable, table = None, properties = None, identitymap = None, use_smart_properties = True, isroot = True, echo = None):
+    if properties is None:
+        properties = {}
+    return (
+        "Mapper(%s, %s, table=%s, properties=%s, identitymap=%s, use_smart_properties=%s, echo=%s)" % (
+            repr(class_),
+            hash_key(selectable),
+            hash_key(table),
+            repr(dict([(k, hash_key(p)) for k,p in properties.iteritems()])),
+            hash_key(identitymap),
+            repr(use_smart_properties),
+            repr(echo)
+
+        )
+    )
+
+
+        
 class PropertyLoader(MapperProperty):
-    def __init__(self, mapper, secondary, primaryjoin, secondaryjoin, **options):
+    def __init__(self, mapper, secondary, primaryjoin, secondaryjoin):
         self.mapper = mapper
         self.target = self.mapper.selectable
         self.secondary = secondary
         self.primaryjoin = primaryjoin
         self.secondaryjoin = secondaryjoin
-
+        self._hash_key = "%s(%s, %s, %s, %s)" % (self.__class__.__name__, hash_key(mapper), hash_key(secondary), hash_key(primaryjoin), hash_key(secondaryjoin))
+        
+    def hash_key(self):
+        return self._hash_key
+        
     def init(self, key, parent, root):
         self.key = key
         self.mapper.init(root)
@@ -369,7 +431,8 @@ class EagerLoader(PropertyLoader):
         if self.secondaryjoin is not None:
             [self.to_alias.append(f) for f in self.secondaryjoin._get_from_objects()]
         del self.to_alias[parent.selectable]
-        
+    
+            
     def setup(self, key, primarytable, statement, **options):
         """add a left outer join to the statement thats being constructed"""
 
@@ -415,6 +478,9 @@ class EagerLazySwitcher(MapperOption):
         self.key = key
         self.toeager = toeager
 
+    def hash_key(self):
+        return "EagerLazySwitcher(%s, %s)" % (repr(self.key), repr(self.toeager))
+        
     def process(self, mapper):
         oldprop = mapper.props[self.key]
         if self.toeager:
@@ -492,6 +558,8 @@ def match_primaries(primary, secondary):
 class IdentityMap(dict):
     def get_key(self, row, class_, table, selectable):
         return (class_, table, tuple([row[column.label] for column in selectable.primary_keys]))
+    def hash_key(self):
+        return "IdentityMap(%s)" % id(self)
         
 _global_identitymap = IdentityMap()
 
index 062ae00149df28bf50362f75f874f321dac5f2a6..2c133f6c166375f987bd1e9c75030d63019a9274 100644 (file)
@@ -258,7 +258,7 @@ class CompoundClause(ClauseElement):
         return self.fromobj
         
     def hash_key(self):
-        return string.join(self.clauses.hash_key(), self.operator)
+        return string.join([c.hash_key() for c in self.clauses], self.operator)
         
 class ClauseList(ClauseElement):
     def __init__(self, *clauses):
@@ -361,7 +361,10 @@ class Alias(Selectable):
             co._make_proxy(self)
 
     primary_keys = property (lambda self: [c for c in self.columns if c.primary_key])
-    
+
+    def hash_key(self):
+        return "Alias(%s, %s)" % (repr(self.selectable.hash_key()), repr(self.name))
+
     def accept_visitor(self, visitor):
         self.selectable.accept_visitor(visitor)
         visitor.visit_alias(self)