473 # update the in-memory schema first |
473 # update the in-memory schema first |
474 rdefdef, rdef = self.init_rdef(**props) |
474 rdefdef, rdef = self.init_rdef(**props) |
475 # then make necessary changes to the system source database |
475 # then make necessary changes to the system source database |
476 syssource = cnx.repo.system_source |
476 syssource = cnx.repo.system_source |
477 attrtype = y2sql.type_from_rdef(syssource.dbhelper, rdef) |
477 attrtype = y2sql.type_from_rdef(syssource.dbhelper, rdef) |
478 # XXX should be moved somehow into lgdb: sqlite doesn't support to |
|
479 # add a new column with UNIQUE, it should be added after the ALTER TABLE |
|
480 # using ADD INDEX |
|
481 if syssource.dbdriver == 'sqlite' and 'UNIQUE' in attrtype: |
|
482 extra_unique_index = True |
|
483 attrtype = attrtype.replace(' UNIQUE', '') |
|
484 else: |
|
485 extra_unique_index = False |
|
486 # added some str() wrapping query since some backend (eg psycopg) don't |
478 # added some str() wrapping query since some backend (eg psycopg) don't |
487 # allow unicode queries |
479 # allow unicode queries |
488 table = SQL_PREFIX + rdefdef.subject |
480 table = SQL_PREFIX + rdefdef.subject |
489 column = SQL_PREFIX + rdefdef.name |
481 column = SQL_PREFIX + rdefdef.name |
490 try: |
482 try: |
495 except Exception as ex: |
487 except Exception as ex: |
496 # the column probably already exists. this occurs when |
488 # the column probably already exists. this occurs when |
497 # the entity's type has just been added or if the column |
489 # the entity's type has just been added or if the column |
498 # has not been previously dropped |
490 # has not been previously dropped |
499 self.error('error while altering table %s: %s', table, ex) |
491 self.error('error while altering table %s: %s', table, ex) |
500 if extra_unique_index or entity.indexed: |
492 if entity.indexed: |
501 try: |
493 try: |
502 syssource.create_index(cnx, table, column, |
494 syssource.create_index(cnx, table, column, unique=False) |
503 unique=extra_unique_index) |
|
504 except Exception as ex: |
495 except Exception as ex: |
505 self.error('error while creating index for %s.%s: %s', |
496 self.error('error while creating index for %s.%s: %s', |
506 table, column, ex) |
497 table, column, ex) |
507 # final relations are not infered, propagate |
498 # final relations are not infered, propagate |
508 schema = cnx.vreg.schema |
499 schema = cnx.vreg.schema |
652 rdef.name = str(rdef.rtype) |
643 rdef.name = str(rdef.rtype) |
653 if rdef.subject not in ETYPE_NAME_MAP and rdef.object not in ETYPE_NAME_MAP: |
644 if rdef.subject not in ETYPE_NAME_MAP and rdef.object not in ETYPE_NAME_MAP: |
654 self.cnx.vreg.schema.add_relation_def(rdef) |
645 self.cnx.vreg.schema.add_relation_def(rdef) |
655 |
646 |
656 |
647 |
657 |
|
658 class RDefUpdateOp(MemSchemaOperation): |
648 class RDefUpdateOp(MemSchemaOperation): |
659 """actually update some properties of a relation definition""" |
649 """actually update some properties of a relation definition""" |
660 rschema = rdefkey = values = None # make pylint happy |
650 rschema = rdefkey = values = None # make pylint happy |
661 rdef = oldvalues = None |
651 rdef = oldvalues = None |
662 indexed_changed = null_allowed_changed = False |
652 indexed_changed = null_allowed_changed = False |
764 entity = None # make pylint happy |
754 entity = None # make pylint happy |
765 |
755 |
766 def precommit_event(self): |
756 def precommit_event(self): |
767 cnx = self.cnx |
757 cnx = self.cnx |
768 rdefentity = self.entity.reverse_constrained_by[0] |
758 rdefentity = self.entity.reverse_constrained_by[0] |
769 # when the relation is added in the same transaction, the constraint |
|
770 # object is created by the operation adding the attribute or relation, |
|
771 # so there is nothing to do here |
|
772 if cnx.added_in_transaction(rdefentity.eid): |
|
773 return |
|
774 rdef = self.rdef = cnx.vreg.schema.schema_by_eid(rdefentity.eid) |
759 rdef = self.rdef = cnx.vreg.schema.schema_by_eid(rdefentity.eid) |
775 cstrtype = self.entity.type |
760 cstrtype = self.entity.type |
776 if cstrtype in UNIQUE_CONSTRAINTS: |
761 if cstrtype in UNIQUE_CONSTRAINTS: |
777 oldcstr = self.oldcstr = rdef.constraint_by_type(cstrtype) |
762 oldcstr = self.oldcstr = rdef.constraint_by_type(cstrtype) |
778 else: |
763 else: |