server/schemahooks.py
branchstable
changeset 2101 08003e0354a7
parent 2056 57d287a2132a
child 2195 58bef4f707ce
equal deleted inserted replaced
2100:89b825cdec74 2101:08003e0354a7
    35                'delete_permission', 'updated_permission',
    35                'delete_permission', 'updated_permission',
    36                ]
    36                ]
    37 
    37 
    38 def get_constraints(session, entity):
    38 def get_constraints(session, entity):
    39     constraints = []
    39     constraints = []
    40     for cstreid in session.query_data(entity.eid, ()):
    40     for cstreid in session.transaction_data.get(entity.eid, ()):
    41         cstrent = session.entity(cstreid)
    41         cstrent = session.entity(cstreid)
    42         cstr = CONSTRAINTS[cstrent.type].deserialize(cstrent.value)
    42         cstr = CONSTRAINTS[cstrent.type].deserialize(cstrent.value)
    43         cstr.eid = cstreid
    43         cstr.eid = cstreid
    44         constraints.append(cstr)
    44         constraints.append(cstr)
    45     return constraints
    45     return constraints
    60     # create index before alter table which may expectingly fail during test
    60     # create index before alter table which may expectingly fail during test
    61     # (sqlite) while index creation should never fail (test for index existence
    61     # (sqlite) while index creation should never fail (test for index existence
    62     # is done by the dbhelper)
    62     # is done by the dbhelper)
    63     session.pool.source('system').create_index(session, table, column)
    63     session.pool.source('system').create_index(session, table, column)
    64     session.info('added index on %s(%s)', table, column)
    64     session.info('added index on %s(%s)', table, column)
    65     session.add_query_data('createdattrs', '%s.%s' % (etype, rtype))
    65     session.transaction_data.setdefault('createdattrs', []).append(
       
    66         '%s.%s' % (etype, rtype))
    66 
    67 
    67 
    68 
    68 class SchemaOperation(Operation):
    69 class SchemaOperation(Operation):
    69     """base class for schema operations"""
    70     """base class for schema operations"""
    70     def __init__(self, session, kobj=None, **kwargs):
    71     def __init__(self, session, kobj=None, **kwargs):
   105 
   106 
   106 class DropTableOp(PreCommitOperation):
   107 class DropTableOp(PreCommitOperation):
   107     """actually remove a database from the application's schema"""
   108     """actually remove a database from the application's schema"""
   108     table = None # make pylint happy
   109     table = None # make pylint happy
   109     def precommit_event(self):
   110     def precommit_event(self):
   110         dropped = self.session.query_data('droppedtables',
   111         dropped = self.session.transaction_data.setdefault('droppedtables',
   111                                           default=set(), setdefault=True)
   112                                                            set())
   112         if self.table in dropped:
   113         if self.table in dropped:
   113             return # already processed
   114             return # already processed
   114         dropped.add(self.table)
   115         dropped.add(self.table)
   115         self.session.system_sql('DROP TABLE %s' % self.table)
   116         self.session.system_sql('DROP TABLE %s' % self.table)
   116         self.info('dropped table %s', self.table)
   117         self.info('dropped table %s', self.table)
   206       table
   207       table
   207     * instantiate an operation to delete the relation definition on commit
   208     * instantiate an operation to delete the relation definition on commit
   208     * delete the associated relation type when necessary
   209     * delete the associated relation type when necessary
   209     """
   210     """
   210     subjschema, rschema, objschema = session.repo.schema.schema_by_eid(rdefeid)
   211     subjschema, rschema, objschema = session.repo.schema.schema_by_eid(rdefeid)
   211     pendings = session.query_data('pendingeids', ())
   212     pendings = session.transaction_data.get('pendingeids', ())
   212     # first delete existing relation if necessary
   213     # first delete existing relation if necessary
   213     if rschema.is_final():
   214     if rschema.is_final():
   214         rdeftype = 'CWAttribute'
   215         rdeftype = 'CWAttribute'
   215     else:
   216     else:
   216         rdeftype = 'CWRelation'
   217         rdeftype = 'CWRelation'
   470             try:
   471             try:
   471                 alreadythere = bool(rschema.objects(subj))
   472                 alreadythere = bool(rschema.objects(subj))
   472             except KeyError:
   473             except KeyError:
   473                 alreadythere = False
   474                 alreadythere = False
   474             if not (alreadythere or
   475             if not (alreadythere or
   475                     key in session.query_data('createdattrs', ())):
   476                     key in session.transaction_data.get('createdattrs', ())):
   476                 add_inline_relation_column(session, subj, rtype)
   477                 add_inline_relation_column(session, subj, rtype)
   477         else:
   478         else:
   478             # need to create the relation if no relation definition in the
   479             # need to create the relation if no relation definition in the
   479             # schema and if it has not been added during other event of the same
   480             # schema and if it has not been added during other event of the same
   480             # transaction
   481             # transaction
   481             if not (rschema.subjects() or
   482             if not (rschema.subjects() or
   482                     rtype in session.query_data('createdtables', ())):
   483                     rtype in session.transaction_data.get('createdtables', ())):
   483                 try:
   484                 try:
   484                     rschema = schema[rtype]
   485                     rschema = schema[rtype]
   485                     tablesql = rschema2sql(rschema)
   486                     tablesql = rschema2sql(rschema)
   486                 except KeyError:
   487                 except KeyError:
   487                     # fake we add it to the schema now to get a correctly
   488                     # fake we add it to the schema now to get a correctly
   492                     schema.del_relation_type(rtype)
   493                     schema.del_relation_type(rtype)
   493                 # create the necessary table
   494                 # create the necessary table
   494                 for sql in tablesql.split(';'):
   495                 for sql in tablesql.split(';'):
   495                     if sql.strip():
   496                     if sql.strip():
   496                         self.session.system_sql(sql)
   497                         self.session.system_sql(sql)
   497                 session.add_query_data('createdtables', rtype)
   498                 session.transaction_data.setdefault('createdtables', []).append(
       
   499                     rtype)
   498 
   500 
   499 def after_add_enfrdef(session, entity):
   501 def after_add_enfrdef(session, entity):
   500     AddCWRelationPreCommitOp(session, entity=entity)
   502     AddCWRelationPreCommitOp(session, entity=entity)
   501 
   503 
   502 
   504 
   618         rtype = rschema.type
   620         rtype = rschema.type
   619         eidcolumn = SQL_PREFIX + 'eid'
   621         eidcolumn = SQL_PREFIX + 'eid'
   620         if not inlined:
   622         if not inlined:
   621             # need to create the relation if it has not been already done by another
   623             # need to create the relation if it has not been already done by another
   622             # event of the same transaction
   624             # event of the same transaction
   623             if not rschema.type in session.query_data('createdtables', ()):
   625             if not rschema.type in session.transaction_data.get('createdtables', ()):
   624                 tablesql = rschema2sql(rschema)
   626                 tablesql = rschema2sql(rschema)
   625                 # create the necessary table
   627                 # create the necessary table
   626                 for sql in tablesql.split(';'):
   628                 for sql in tablesql.split(';'):
   627                     if sql.strip():
   629                     if sql.strip():
   628                         sqlexec(sql)
   630                         sqlexec(sql)
   629                 session.add_query_data('createdtables', rschema.type)
   631                 session.transaction_data.setdefault('createdtables', []).append(
       
   632                     rschema.type)
   630             # copy existant data
   633             # copy existant data
   631             column = SQL_PREFIX + rtype
   634             column = SQL_PREFIX + rtype
   632             for etype in rschema.subjects():
   635             for etype in rschema.subjects():
   633                 table = SQL_PREFIX + str(etype)
   636                 table = SQL_PREFIX + str(etype)
   634                 sqlexec('INSERT INTO %s_relation SELECT %s, %s FROM %s WHERE NOT %s IS NULL'
   637                 sqlexec('INSERT INTO %s_relation SELECT %s, %s FROM %s WHERE NOT %s IS NULL'
   695     def precommit_event(self):
   698     def precommit_event(self):
   696         rdef = self.entity.reverse_constrained_by[0]
   699         rdef = self.entity.reverse_constrained_by[0]
   697         session = self.session
   700         session = self.session
   698         # when the relation is added in the same transaction, the constraint object
   701         # when the relation is added in the same transaction, the constraint object
   699         # is created by AddEN?FRDefPreCommitOp, there is nothing to do here
   702         # is created by AddEN?FRDefPreCommitOp, there is nothing to do here
   700         if rdef.eid in session.query_data('neweids', ()):
   703         if rdef.eid in session.transaction_data.get('neweids', ()):
   701             self.cancelled = True
   704             self.cancelled = True
   702             return
   705             return
   703         self.cancelled = False
   706         self.cancelled = False
   704         schema = session.repo.schema
   707         schema = session.repo.schema
   705         subjtype, rtype, objtype = schema.schema_by_eid(rdef.eid)
   708         subjtype, rtype, objtype = schema.schema_by_eid(rdef.eid)
   771     def commit_event(self):
   774     def commit_event(self):
   772         self.constraints.remove(self.cstr)
   775         self.constraints.remove(self.cstr)
   773 
   776 
   774 
   777 
   775 def before_delete_constrained_by(session, fromeid, rtype, toeid):
   778 def before_delete_constrained_by(session, fromeid, rtype, toeid):
   776     if not fromeid in session.query_data('pendingeids', ()):
   779     if not fromeid in session.transaction_data.get('pendingeids', ()):
   777         schema = session.repo.schema
   780         schema = session.repo.schema
   778         entity = session.eid_rset(toeid).get_entity(0, 0)
   781         entity = session.eid_rset(toeid).get_entity(0, 0)
   779         subjtype, rtype, objtype = schema.schema_by_eid(fromeid)
   782         subjtype, rtype, objtype = schema.schema_by_eid(fromeid)
   780         try:
   783         try:
   781             cstr = rtype.constraint_by_type(subjtype, objtype, entity.cstrtype[0].name)
   784             cstr = rtype.constraint_by_type(subjtype, objtype, entity.cstrtype[0].name)
   784         except IndexError:
   787         except IndexError:
   785             session.critical('constraint type no more accessible')
   788             session.critical('constraint type no more accessible')
   786 
   789 
   787 
   790 
   788 def after_add_constrained_by(session, fromeid, rtype, toeid):
   791 def after_add_constrained_by(session, fromeid, rtype, toeid):
   789     if fromeid in session.query_data('neweids', ()):
   792     if fromeid in session.transaction_data.get('neweids', ()):
   790         session.add_query_data(fromeid, toeid)
   793         session.transaction_data.setdefault(fromeid, []).append(toeid)
   791 
   794 
   792 
   795 
   793 # schema permissions synchronization ##########################################
   796 # schema permissions synchronization ##########################################
   794 
   797 
   795 class PermissionOp(Operation):
   798 class PermissionOp(Operation):
   906 def before_del_permission(session, subject, rtype, object):
   909 def before_del_permission(session, subject, rtype, object):
   907     """delete entity/relation *_permission, need to update schema
   910     """delete entity/relation *_permission, need to update schema
   908 
   911 
   909     skip the operation if the related type is being deleted
   912     skip the operation if the related type is being deleted
   910     """
   913     """
   911     if subject in session.query_data('pendingeids', ()):
   914     if subject in session.transaction_data.get('pendingeids', ()):
   912         return
   915         return
   913     perm = rtype.split('_', 1)[0]
   916     perm = rtype.split('_', 1)[0]
   914     if session.describe(object)[0] == 'CWGroup':
   917     if session.describe(object)[0] == 'CWGroup':
   915         DelGroupPermissionOp(session, perm, subject, object)
   918         DelGroupPermissionOp(session, perm, subject, object)
   916     else: # RQLExpression
   919     else: # RQLExpression