hooks/syncschema.py
changeset 5849 9db65b381028
parent 5811 e77cea9721e7
parent 5847 51636c991fb4
child 5877 0c7b7b76a84f
equal deleted inserted replaced
5840:60880c81e32e 5849:9db65b381028
   250         rschema = self.rschema
   250         rschema = self.rschema
   251         if rschema.final:
   251         if rschema.final:
   252             return
   252             return
   253         session = self.session
   253         session = self.session
   254         if 'fulltext_container' in self.values:
   254         if 'fulltext_container' in self.values:
   255             ftiupdates = session.transaction_data.setdefault(
       
   256                 'fti_update_etypes', set())
       
   257             for subjtype, objtype in rschema.rdefs:
   255             for subjtype, objtype in rschema.rdefs:
   258                 ftiupdates.add(subjtype)
   256                 hook.set_operation(session, 'fti_update_etypes', subjtype,
   259                 ftiupdates.add(objtype)
   257                                    UpdateFTIndexOp)
   260             UpdateFTIndexOp(session)
   258                 hook.set_operation(session, 'fti_update_etypes', objtype,
       
   259                                    UpdateFTIndexOp)
   261         if not 'inlined' in self.values:
   260         if not 'inlined' in self.values:
   262             return # nothing to do
   261             return # nothing to do
   263         inlined = self.values['inlined']
   262         inlined = self.values['inlined']
   264         # check in-lining is necessary / possible
   263         # check in-lining is necessary / possible
   265         if inlined:
   264         if inlined:
   365                  'internationalizable': entity.internationalizable}
   364                  'internationalizable': entity.internationalizable}
   366         rdef = self.init_rdef(**props)
   365         rdef = self.init_rdef(**props)
   367         sysource = session.pool.source('system')
   366         sysource = session.pool.source('system')
   368         attrtype = y2sql.type_from_constraints(
   367         attrtype = y2sql.type_from_constraints(
   369             sysource.dbhelper, rdef.object, rdef.constraints)
   368             sysource.dbhelper, rdef.object, rdef.constraints)
   370         # XXX should be moved somehow into lgc.adbh: sqlite doesn't support to
   369         # XXX should be moved somehow into lgdb: sqlite doesn't support to
   371         # add a new column with UNIQUE, it should be added after the ALTER TABLE
   370         # add a new column with UNIQUE, it should be added after the ALTER TABLE
   372         # using ADD INDEX
   371         # using ADD INDEX
   373         if sysource.dbdriver == 'sqlite' and 'UNIQUE' in attrtype:
   372         if sysource.dbdriver == 'sqlite' and 'UNIQUE' in attrtype:
   374             extra_unique_index = True
   373             extra_unique_index = True
   375             attrtype = attrtype.replace(' UNIQUE', '')
   374             attrtype = attrtype.replace(' UNIQUE', '')
   504             if self.values['indexed']:
   503             if self.values['indexed']:
   505                 sysource.create_index(session, table, column)
   504                 sysource.create_index(session, table, column)
   506             else:
   505             else:
   507                 sysource.drop_index(session, table, column)
   506                 sysource.drop_index(session, table, column)
   508         if 'cardinality' in self.values and self.rschema.final:
   507         if 'cardinality' in self.values and self.rschema.final:
   509             adbh = session.pool.source('system').dbhelper
   508             syssource = session.pool.source('system')
   510             if not adbh.alter_column_support:
   509             if not syssource.dbhelper.alter_column_support:
   511                 # not supported (and NOT NULL not set by yams in that case, so
   510                 # not supported (and NOT NULL not set by yams in that case, so
   512                 # no worry)
   511                 # no worry) XXX (syt) then should we set NOT NULL below ??
   513                 return
   512                 return
   514             atype = self.rschema.objects(etype)[0]
   513             atype = self.rschema.objects(etype)[0]
   515             constraints = self.rschema.rdef(etype, atype).constraints
   514             constraints = self.rschema.rdef(etype, atype).constraints
   516             coltype = y2sql.type_from_constraints(adbh, atype, constraints,
   515             coltype = y2sql.type_from_constraints(syssource.dbhelper, atype, constraints,
   517                                                   creating=False)
   516                                                   creating=False)
   518             # XXX check self.values['cardinality'][0] actually changed?
   517             # XXX check self.values['cardinality'][0] actually changed?
   519             notnull = self.values['cardinality'][0] != '1'
   518             syssource.set_null_allowed(self.session, table, column, coltype,
   520             sql = adbh.sql_set_null_allowed(table, column, coltype, notnull)
   519                                        self.values['cardinality'][0] != '1')
   521             session.system_sql(sql)
       
   522         if 'fulltextindexed' in self.values:
   520         if 'fulltextindexed' in self.values:
   523             UpdateFTIndexOp(session)
   521             hook.set_operation(session, 'fti_update_etypes', etype,
   524             session.transaction_data.setdefault(
   522                                UpdateFTIndexOp)
   525                 'fti_update_etypes', set()).add(etype)
       
   526 
   523 
   527 
   524 
   528 class SourceDbCWConstraintAdd(hook.Operation):
   525 class SourceDbCWConstraintAdd(hook.Operation):
   529     """actually update constraint of a relation definition"""
   526     """actually update constraint of a relation definition"""
   530     entity = None # make pylint happy
   527     entity = None # make pylint happy
   546         table = SQL_PREFIX + str(subjtype)
   543         table = SQL_PREFIX + str(subjtype)
   547         column = SQL_PREFIX + str(rtype)
   544         column = SQL_PREFIX + str(rtype)
   548         # alter the physical schema on size constraint changes
   545         # alter the physical schema on size constraint changes
   549         if newcstr.type() == 'SizeConstraint' and (
   546         if newcstr.type() == 'SizeConstraint' and (
   550             oldcstr is None or oldcstr.max != newcstr.max):
   547             oldcstr is None or oldcstr.max != newcstr.max):
   551             adbh = self.session.pool.source('system').dbhelper
   548             syssource = self.session.pool.source('system')
   552             card = rtype.rdef(subjtype, objtype).cardinality
   549             card = rtype.rdef(subjtype, objtype).cardinality
   553             coltype = y2sql.type_from_constraints(adbh, objtype, [newcstr],
   550             coltype = y2sql.type_from_constraints(syssource.dbhelper, objtype,
   554                                                   creating=False)
   551                                                   [newcstr], creating=False)
   555             sql = adbh.sql_change_col_type(table, column, coltype, card != '1')
       
   556             try:
   552             try:
   557                 session.system_sql(sql, rollback_on_failure=False)
   553                 syssource.change_col_type(session, table, column, coltype, card[0] != '1')
   558                 self.info('altered column %s of table %s: now %s',
   554                 self.info('altered column %s of table %s: now %s',
   559                           column, table, coltype)
   555                           column, table, coltype)
   560             except Exception, ex:
   556             except Exception, ex:
   561                 # not supported by sqlite for instance
   557                 # not supported by sqlite for instance
   562                 self.error('error while altering table %s: %s', table, ex)
   558                 self.error('error while altering table %s: %s', table, ex)
   573         cstrtype = self.cstr.type()
   569         cstrtype = self.cstr.type()
   574         table = SQL_PREFIX + str(self.rdef.subject)
   570         table = SQL_PREFIX + str(self.rdef.subject)
   575         column = SQL_PREFIX + str(self.rdef.rtype)
   571         column = SQL_PREFIX + str(self.rdef.rtype)
   576         # alter the physical schema on size/unique constraint changes
   572         # alter the physical schema on size/unique constraint changes
   577         if cstrtype == 'SizeConstraint':
   573         if cstrtype == 'SizeConstraint':
       
   574             syssource = self.session.pool.source('system')
       
   575             coltype = y2sql.type_from_constraints(syssource.dbhelper,
       
   576                                                   self.rdef.object, [],
       
   577                                                   creating=False)
   578             try:
   578             try:
   579                 adbh = self.session.pool.source('system').dbhelper
   579                 syssource.change_col_type(session, table, column, coltype,
   580                 coltype = y2sql.type_from_constraints(adbh, rdef.object, [],
   580                                           self.rdef.cardinality[0] != '1')
   581                                                       creating=False)
       
   582                 sql = adbh.sql_change_col_type(table, column, coltype,
       
   583                                                rdef.cardinality != '1')
       
   584                 self.session.system_sql(sql, rollback_on_failure=False)
       
   585                 self.info('altered column %s of table %s: now %s',
   581                 self.info('altered column %s of table %s: now %s',
   586                           column, table, coltype)
   582                           column, table, coltype)
   587             except Exception, ex:
   583             except Exception, ex:
   588                 # not supported by sqlite for instance
   584                 # not supported by sqlite for instance
   589                 self.error('error while altering table %s: %s', table, ex)
   585                 self.error('error while altering table %s: %s', table, ex)
  1172     """
  1168     """
  1173 
  1169 
  1174     def postcommit_event(self):
  1170     def postcommit_event(self):
  1175         session = self.session
  1171         session = self.session
  1176         source = session.repo.system_source
  1172         source = session.repo.system_source
  1177         to_reindex = session.transaction_data.get('fti_update_etypes', ())
  1173         to_reindex = session.transaction_data.pop('fti_update_etypes', ())
  1178         self.info('%i etypes need full text indexed reindexation',
  1174         self.info('%i etypes need full text indexed reindexation',
  1179                   len(to_reindex))
  1175                   len(to_reindex))
  1180         schema = self.session.repo.vreg.schema
  1176         schema = self.session.repo.vreg.schema
  1181         for etype in to_reindex:
  1177         for etype in to_reindex:
  1182             rset = session.execute('Any X WHERE X is %s' % etype)
  1178             rset = session.execute('Any X WHERE X is %s' % etype)