Commits

Mike Bayer committed 4143d68

- add "identifier", can differentiate between "name" rendered and "identifier" in func.

Comments (0)

Files changed (3)

     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,

lib/sqlalchemy/sql/functions.py

 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):
 
         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.

test/sql/test_functions.py

             "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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.