[schema2sql] support NOW and TODAY in check constraints
authorJulien Cristau <julien.cristau@logilab.fr>
Sun, 22 Mar 2015 19:39:29 +0100
changeset 10444 fb7c1013189e
parent 10443 2d3834df64ab
child 10445 f1773842077d
[schema2sql] support NOW and TODAY in check constraints Related to #5154406.
server/schema2sql.py
server/test/data-schema2sql/schema/Dates.py
server/test/unittest_schema2sql.py
--- a/server/schema2sql.py	Mon May 18 11:36:07 2015 +0200
+++ b/server/schema2sql.py	Sun Mar 22 19:39:29 2015 +0100
@@ -24,7 +24,8 @@
 from six import string_types
 from six.moves import range
 
-from yams.constraints import SizeConstraint, UniqueConstraint, Attribute
+from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute,
+                              NOW, TODAY)
 
 # default are usually not handled at the sql level. If you want them, set
 # SET_DEFAULT to True
@@ -129,7 +130,7 @@
         attr = rschema.type
         rdef = rschema.rdef(eschema.type, aschema.type)
         for constraint in rdef.constraints:
-            cstrname, check = check_constraint(eschema, aschema, attr, constraint, prefix=prefix)
+            cstrname, check = check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=prefix)
             if cstrname is not None:
                 w(', CONSTRAINT %s CHECK(%s)' % (cstrname, check))
     w(');')
@@ -146,29 +147,31 @@
     w('')
     return '\n'.join(output)
 
-def check_constraint(eschema, aschema, attr, constraint, prefix=''):
+def as_sql(value, dbhelper, prefix):
+    if isinstance(value, Attribute):
+        return prefix + value.attr
+    elif isinstance(value, TODAY):
+        return dbhelper.sql_current_date()
+    elif isinstance(value, NOW):
+        return dbhelper.sql_current_timestamp()
+    else:
+        # XXX more quoting for literals?
+        return value
+
+def check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=''):
     # XXX should find a better name
     cstrname = 'cstr' + md5(eschema.type + attr + constraint.type() +
                             (constraint.serialize() or '')).hexdigest()
     if constraint.type() == 'BoundaryConstraint':
-        if isinstance(constraint.boundary, Attribute):
-            value = prefix + constraint.boundary.attr
-        else:
-            value = constraint.boundary
+        value = as_sql(constraint.boundary, dbhelper, prefix)
         return cstrname, '%s%s %s %s' % (prefix, attr, constraint.operator, value)
     elif constraint.type() == 'IntervalBoundConstraint':
         condition = []
         if constraint.minvalue is not None:
-            if isinstance(constraint.minvalue, Attribute):
-                value = prefix + constraint.minvalue.attr
-            else:
-                value = constraint.minvalue
+            value = as_sql(constraint.minvalue, dbhelper, prefix)
             condition.append('%s%s >= %s' % (prefix, attr, value))
         if constraint.maxvalue is not None:
-            if isinstance(constraint.maxvalue, Attribute):
-                value = prefix + constraint.maxvalue.attr
-            else:
-                value = constraint.maxvalue
+            value = as_sql(constraint.maxvalue, dbhelper, prefix)
             condition.append('%s%s <= %s' % (prefix, attr, value))
         return cstrname, ' AND '.join(condition)
     elif constraint.type() == 'StaticVocabularyConstraint':
--- a/server/test/data-schema2sql/schema/Dates.py	Mon May 18 11:36:07 2015 +0200
+++ b/server/test/data-schema2sql/schema/Dates.py	Sun Mar 22 19:39:29 2015 +0100
@@ -17,11 +17,12 @@
 # with yams. If not, see <http://www.gnu.org/licenses/>.
 from datetime import time, date
 from yams.buildobjs import EntityType, Datetime, Date, Time
+from yams.constraints import TODAY, BoundaryConstraint
 
 class Datetest(EntityType):
     dt1 = Datetime(default=u'now')
     dt2 = Datetime(default=u'today')
-    d1  = Date(default=u'today')
+    d1  = Date(default=u'today', constraints=[BoundaryConstraint('<=', TODAY())])
     d2  = Date(default=date(2007, 12, 11))
     t1  = Time(default=time(8, 40))
     t2  = Time(default=time(9, 45))
--- a/server/test/unittest_schema2sql.py	Mon May 18 11:36:07 2015 +0200
+++ b/server/test/unittest_schema2sql.py	Sun Mar 22 19:39:29 2015 +0100
@@ -52,6 +52,7 @@
  d2 date,
  t1 time,
  t2 time
+, CONSTRAINT cstredd407706bdfbd2285714dd689e8fcc0 CHECK(d1 <= CAST(clock_timestamp() AS DATE))
 );
 
 CREATE TABLE Division(