hooks/syncschema.py
changeset 9299 c5eed908117d
parent 8943 58b3b2d9c965
child 9365 71c12e778162
equal deleted inserted replaced
9296:8a4175557426 9299:c5eed908117d
    26 __docformat__ = "restructuredtext en"
    26 __docformat__ = "restructuredtext en"
    27 _ = unicode
    27 _ = unicode
    28 
    28 
    29 from copy import copy
    29 from copy import copy
    30 from yams.schema import BASE_TYPES, RelationSchema, RelationDefinitionSchema
    30 from yams.schema import BASE_TYPES, RelationSchema, RelationDefinitionSchema
    31 from yams import buildobjs as ybo, schema2sql as y2sql
    31 from yams import buildobjs as ybo, schema2sql as y2sql, convert_default_value
    32 
    32 
    33 from logilab.common.decorators import clear_cache
    33 from logilab.common.decorators import clear_cache
    34 
    34 
    35 from cubicweb import validation_error
    35 from cubicweb import validation_error
    36 from cubicweb.predicates import is_instance
    36 from cubicweb.predicates import is_instance
    37 from cubicweb.schema import (SCHEMA_TYPES, META_RTYPES, VIRTUAL_RTYPES,
    37 from cubicweb.schema import (SCHEMA_TYPES, META_RTYPES, VIRTUAL_RTYPES,
    38                              CONSTRAINTS, ETYPE_NAME_MAP, display_name)
    38                              CONSTRAINTS, ETYPE_NAME_MAP, display_name)
    39 from cubicweb.server import hook, schemaserial as ss
    39 from cubicweb.server import hook, schemaserial as ss
    40 from cubicweb.server.sqlutils import SQL_PREFIX
    40 from cubicweb.server.sqlutils import SQL_PREFIX
    41 
       
    42 
       
    43 TYPE_CONVERTER = { # XXX
       
    44     'Boolean': bool,
       
    45     'Int': int,
       
    46     'BigInt': int,
       
    47     'Float': float,
       
    48     'Password': str,
       
    49     'String': unicode,
       
    50     'Date' : unicode,
       
    51     'Datetime' : unicode,
       
    52     'Time' : unicode,
       
    53     'TZDatetime' : unicode,
       
    54     'TZTime' : unicode,
       
    55     }
       
    56 
    41 
    57 # core entity and relation types which can't be removed
    42 # core entity and relation types which can't be removed
    58 CORE_TYPES = BASE_TYPES | SCHEMA_TYPES | META_RTYPES | set(
    43 CORE_TYPES = BASE_TYPES | SCHEMA_TYPES | META_RTYPES | set(
    59     ('CWUser', 'CWGroup','login', 'upassword', 'name', 'in_group'))
    44     ('CWUser', 'CWGroup','login', 'upassword', 'name', 'in_group'))
    60 
    45 
   435         return rdefdef
   420         return rdefdef
   436 
   421 
   437     def precommit_event(self):
   422     def precommit_event(self):
   438         session = self.session
   423         session = self.session
   439         entity = self.entity
   424         entity = self.entity
   440         # entity.defaultval is a string or None, but we need a correctly typed
   425         # entity.defaultval is a Binary or None, but we need a correctly typed
   441         # value
   426         # value
   442         default = entity.defaultval
   427         default = entity.defaultval
   443         if default is not None:
   428         if default is not None:
   444             default = TYPE_CONVERTER[entity.otype.name](default)
   429             default = default.unzpickle()
   445         props = {'default': default,
   430         props = {'default': default,
   446                  'indexed': entity.indexed,
   431                  'indexed': entity.indexed,
   447                  'fulltextindexed': entity.fulltextindexed,
   432                  'fulltextindexed': entity.fulltextindexed,
   448                  'internationalizable': entity.internationalizable}
   433                  'internationalizable': entity.internationalizable}
   449         # update the in-memory schema first
   434         # update the in-memory schema first
   491         rschema = schema.rschema(rdefdef.name)
   476         rschema = schema.rschema(rdefdef.name)
   492         # if relation type has been inserted in the same transaction, its final
   477         # if relation type has been inserted in the same transaction, its final
   493         # attribute is still set to False, so we've to ensure it's False
   478         # attribute is still set to False, so we've to ensure it's False
   494         rschema.final = True
   479         rschema.final = True
   495         insert_rdef_on_subclasses(session, eschema, rschema, rdefdef, props)
   480         insert_rdef_on_subclasses(session, eschema, rschema, rdefdef, props)
   496         # set default value, using sql for performance and to avoid
   481         # update existing entities with the default value of newly added attribute
   497         # modification_date update
   482         if default is not None:
   498         if default:
   483             default = convert_default_value(self.rdefdef, default)
   499             if rdefdef.object in ('Date', 'Datetime', 'TZDatetime'):
   484             session.system_sql('UPDATE %s SET %s=%%(default)s' % (table, column),
   500                 # XXX may may want to use creation_date
   485                                {'default': default})
   501                 if default == 'TODAY':
       
   502                     default = syssource.dbhelper.sql_current_date()
       
   503                 elif default == 'NOW':
       
   504                     default = syssource.dbhelper.sql_current_timestamp()
       
   505                 session.system_sql('UPDATE %s SET %s=%s'
       
   506                                    % (table, column, default))
       
   507             else:
       
   508                 session.system_sql('UPDATE %s SET %s=%%(default)s' % (table, column),
       
   509                                    {'default': default})
       
   510 
   486 
   511     def revertprecommit_event(self):
   487     def revertprecommit_event(self):
   512         # revert changes on in memory schema
   488         # revert changes on in memory schema
   513         if getattr(self, 'rdefdef', None) is None:
   489         if getattr(self, 'rdefdef', None) is None:
   514             return
   490             return