]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- add "identifier", can differentiate between "name" rendered and "identifier" in...
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 26 Aug 2012 22:01:21 +0000 (18:01 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 26 Aug 2012 22:01:21 +0000 (18:01 -0400)
CHANGES
lib/sqlalchemy/sql/functions.py
test/sql/test_functions.py

diff --git a/CHANGES b/CHANGES
index 39102110c75b744bba2903ff3f56964b67f7c147..ee75177563d74bad5d248c90923bf09232975ad3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -424,7 +424,10 @@ underneath "0.7.xx".
     to allow for user-defined GenericFunction
     subclasses to be available via the func.*
     namespace automatically by classname,
-    optionally using a package name as well.
+    optionally using a package name, as well
+    as with the ability to have the rendered
+    name different from the identified name
+    in func.*.
 
   - [changed] Most classes in expression.sql
     are no longer preceded with an underscore,
index 24f7e81b4132f24b5799eda6488a6237c12ced1b..b24f8cbecc877c686184b40e4899eb44b2e9a358 100644 (file)
@@ -17,12 +17,13 @@ _registry = util.defaultdict(dict)
 class _GenericMeta(VisitableType):
     def __init__(cls, clsname, bases, clsdict):
         cls.name = name = clsdict.get('name', clsname)
+        cls.identifier = identifier = clsdict.get('identifier', name)
         package = clsdict.pop('package', '_default')
         # legacy
         if '__return_type__' in clsdict:
             cls.type = clsdict['__return_type__']
         reg = _registry[package]
-        reg[name] = cls
+        reg[identifier] = cls
         super(_GenericMeta, cls).__init__(clsname, bases, clsdict)
 
 class GenericFunction(Function):
@@ -69,9 +70,26 @@ class GenericFunction(Function):
 
         print select([func.time.as_utc()])
 
+    A final option is to allow the function to be accessed
+    from one name in :data:`.func` but to render as a different name.
+    The ``identifier`` attribute will override the name used to
+    access the function as loaded from :data:`.func`, but will retain
+    the usage of ``name`` as the rendered name::
+
+        class GeoBuffer(GenericFunction):
+            type = Geometry
+            package = "geo"
+            name = "ST_Buffer"
+            identifier = "buffer"
+
+    The above function will render as follows::
+
+        >>> print func.geo.buffer()
+        ST_Buffer()
+
     .. versionadded:: 0.8 :class:`.GenericFunction` now supports
        automatic registration of new functions as well as package
-       support.
+       and custom naming support.
 
     .. versionchanged:: 0.8 The attribute name ``type`` is used
        to specify the function's return type at the class level.
index fc227f37533405561317d72e97ffb46c3f4ed603..f0fcd4b7277d272da585462270a5a371af510789 100644 (file)
@@ -127,6 +127,35 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "my_func(:param_1, :param_2, :param_3)"
         )
 
+    def test_custom_registered_identifier(self):
+        class GeoBuffer(GenericFunction):
+            type = Integer
+            package = "geo"
+            name = "BufferOne"
+            identifier = "buf1"
+
+        class GeoBuffer2(GenericFunction):
+            type = Integer
+            name = "BufferTwo"
+            identifier = "buf2"
+
+        class BufferThree(GenericFunction):
+            type = Integer
+            identifier = "buf3"
+
+        self.assert_compile(
+            func.geo.buf1(),
+            "BufferOne()"
+        )
+        self.assert_compile(
+            func.buf2(),
+            "BufferTwo()"
+        )
+        self.assert_compile(
+            func.buf3(),
+            "BufferThree()"
+        )
+
     def test_custom_args(self):
         class myfunc(GenericFunction):
             pass