server/schema2sql.py
changeset 10444 fb7c1013189e
parent 10443 2d3834df64ab
child 10481 6ac4b1726e9f
equal deleted inserted replaced
10443:2d3834df64ab 10444:fb7c1013189e
    22 from hashlib import md5
    22 from hashlib import md5
    23 
    23 
    24 from six import string_types
    24 from six import string_types
    25 from six.moves import range
    25 from six.moves import range
    26 
    26 
    27 from yams.constraints import SizeConstraint, UniqueConstraint, Attribute
    27 from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute,
       
    28                               NOW, TODAY)
    28 
    29 
    29 # default are usually not handled at the sql level. If you want them, set
    30 # default are usually not handled at the sql level. If you want them, set
    30 # SET_DEFAULT to True
    31 # SET_DEFAULT to True
    31 SET_DEFAULT = False
    32 SET_DEFAULT = False
    32 
    33 
   127         if aschema is None:  # inline relation
   128         if aschema is None:  # inline relation
   128             continue
   129             continue
   129         attr = rschema.type
   130         attr = rschema.type
   130         rdef = rschema.rdef(eschema.type, aschema.type)
   131         rdef = rschema.rdef(eschema.type, aschema.type)
   131         for constraint in rdef.constraints:
   132         for constraint in rdef.constraints:
   132             cstrname, check = check_constraint(eschema, aschema, attr, constraint, prefix=prefix)
   133             cstrname, check = check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=prefix)
   133             if cstrname is not None:
   134             if cstrname is not None:
   134                 w(', CONSTRAINT %s CHECK(%s)' % (cstrname, check))
   135                 w(', CONSTRAINT %s CHECK(%s)' % (cstrname, check))
   135     w(');')
   136     w(');')
   136     # create indexes
   137     # create indexes
   137     for i in range(len(attrs)):
   138     for i in range(len(attrs)):
   144         for sql in sqls:
   145         for sql in sqls:
   145             w(sql)
   146             w(sql)
   146     w('')
   147     w('')
   147     return '\n'.join(output)
   148     return '\n'.join(output)
   148 
   149 
   149 def check_constraint(eschema, aschema, attr, constraint, prefix=''):
   150 def as_sql(value, dbhelper, prefix):
       
   151     if isinstance(value, Attribute):
       
   152         return prefix + value.attr
       
   153     elif isinstance(value, TODAY):
       
   154         return dbhelper.sql_current_date()
       
   155     elif isinstance(value, NOW):
       
   156         return dbhelper.sql_current_timestamp()
       
   157     else:
       
   158         # XXX more quoting for literals?
       
   159         return value
       
   160 
       
   161 def check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=''):
   150     # XXX should find a better name
   162     # XXX should find a better name
   151     cstrname = 'cstr' + md5(eschema.type + attr + constraint.type() +
   163     cstrname = 'cstr' + md5(eschema.type + attr + constraint.type() +
   152                             (constraint.serialize() or '')).hexdigest()
   164                             (constraint.serialize() or '')).hexdigest()
   153     if constraint.type() == 'BoundaryConstraint':
   165     if constraint.type() == 'BoundaryConstraint':
   154         if isinstance(constraint.boundary, Attribute):
   166         value = as_sql(constraint.boundary, dbhelper, prefix)
   155             value = prefix + constraint.boundary.attr
       
   156         else:
       
   157             value = constraint.boundary
       
   158         return cstrname, '%s%s %s %s' % (prefix, attr, constraint.operator, value)
   167         return cstrname, '%s%s %s %s' % (prefix, attr, constraint.operator, value)
   159     elif constraint.type() == 'IntervalBoundConstraint':
   168     elif constraint.type() == 'IntervalBoundConstraint':
   160         condition = []
   169         condition = []
   161         if constraint.minvalue is not None:
   170         if constraint.minvalue is not None:
   162             if isinstance(constraint.minvalue, Attribute):
   171             value = as_sql(constraint.minvalue, dbhelper, prefix)
   163                 value = prefix + constraint.minvalue.attr
       
   164             else:
       
   165                 value = constraint.minvalue
       
   166             condition.append('%s%s >= %s' % (prefix, attr, value))
   172             condition.append('%s%s >= %s' % (prefix, attr, value))
   167         if constraint.maxvalue is not None:
   173         if constraint.maxvalue is not None:
   168             if isinstance(constraint.maxvalue, Attribute):
   174             value = as_sql(constraint.maxvalue, dbhelper, prefix)
   169                 value = prefix + constraint.maxvalue.attr
       
   170             else:
       
   171                 value = constraint.maxvalue
       
   172             condition.append('%s%s <= %s' % (prefix, attr, value))
   175             condition.append('%s%s <= %s' % (prefix, attr, value))
   173         return cstrname, ' AND '.join(condition)
   176         return cstrname, ' AND '.join(condition)
   174     elif constraint.type() == 'StaticVocabularyConstraint':
   177     elif constraint.type() == 'StaticVocabularyConstraint':
   175         sample = next(iter(constraint.vocabulary()))
   178         sample = next(iter(constraint.vocabulary()))
   176         if not isinstance(sample, string_types):
   179         if not isinstance(sample, string_types):