[schema2sql] support NOW and TODAY in check constraints
Related to #5154406.
--- 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(