# HG changeset patch # User Julien Cristau # Date 1427049569 -3600 # Node ID fb7c1013189eb390a6ccd38bd77f9bdf7308cb94 # Parent 2d3834df64ab1250b764966fca0fd69a2dd7ec6c [schema2sql] support NOW and TODAY in check constraints Related to #5154406. diff -r 2d3834df64ab -r fb7c1013189e server/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': diff -r 2d3834df64ab -r fb7c1013189e server/test/data-schema2sql/schema/Dates.py --- 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 . 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)) diff -r 2d3834df64ab -r fb7c1013189e server/test/unittest_schema2sql.py --- 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(