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 |