389 'WHERE T eid %%(x)s' % perm, |
389 'WHERE T eid %%(x)s' % perm, |
390 {'expr': expr, 'exprtype': exprtype, |
390 {'expr': expr, 'exprtype': exprtype, |
391 'vars': expression.mainvars, 'x': teid}, 'x', |
391 'vars': expression.mainvars, 'x': teid}, 'x', |
392 ask_confirm=False) |
392 ask_confirm=False) |
393 |
393 |
394 def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True): |
394 def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True, syncprops=True): |
395 """synchronize properties of the persistent relation schema against its |
395 """synchronize properties of the persistent relation schema against its |
396 current definition: |
396 current definition: |
397 |
397 |
398 * description |
398 * description |
399 * symetric, meta |
399 * symetric, meta |
406 rtype = str(rtype) |
406 rtype = str(rtype) |
407 if rtype in self._synchronized: |
407 if rtype in self._synchronized: |
408 return |
408 return |
409 self._synchronized.add(rtype) |
409 self._synchronized.add(rtype) |
410 rschema = self.fs_schema.rschema(rtype) |
410 rschema = self.fs_schema.rschema(rtype) |
411 self.rqlexecall(ss.updaterschema2rql(rschema), |
411 if syncprops: |
412 ask_confirm=self.verbosity>=2) |
412 self.rqlexecall(ss.updaterschema2rql(rschema), |
413 reporschema = self.repo.schema.rschema(rtype) |
413 ask_confirm=self.verbosity>=2) |
414 if syncrdefs: |
414 if syncrdefs: |
415 for subj, obj in rschema.iter_rdefs(): |
415 reporschema = self.repo.schema.rschema(rtype) |
416 if not reporschema.has_rdef(subj, obj): |
416 for subj, obj in rschema.rdefs: |
|
417 if (subj, obj) not in reporschema.rdefs: |
417 continue |
418 continue |
418 self._synchronize_rdef_schema(subj, rschema, obj, syncperms=syncperms) |
419 self._synchronize_rdef_schema(subj, rschema, obj, |
|
420 syncprops=syncprops, |
|
421 syncperms=syncperms) |
419 |
422 |
420 def _synchronize_eschema(self, etype, syncperms=True): |
423 def _synchronize_eschema(self, etype, syncperms=True): |
421 """synchronize properties of the persistent entity schema against |
424 """synchronize properties of the persistent entity schema against |
422 its current definition: |
425 its current definition: |
423 |
426 |
465 continue |
468 continue |
466 self._synchronize_rdef_schema(subj, rschema, obj) |
469 self._synchronize_rdef_schema(subj, rschema, obj) |
467 if syncperms: |
470 if syncperms: |
468 self._synchronize_permissions(eschema, repoeschema.eid) |
471 self._synchronize_permissions(eschema, repoeschema.eid) |
469 |
472 |
470 def _synchronize_rdef_schema(self, subjtype, rtype, objtype, syncperms=True): |
473 def _synchronize_rdef_schema(self, subjtype, rtype, objtype, |
|
474 syncperms=True, syncprops=True): |
471 """synchronize properties of the persistent relation definition schema |
475 """synchronize properties of the persistent relation definition schema |
472 against its current definition: |
476 against its current definition: |
473 * order and other properties |
477 * order and other properties |
474 * constraints |
478 * constraints |
475 """ |
479 """ |
480 return |
484 return |
481 self._synchronized.add((subjtype, rschema, objtype)) |
485 self._synchronized.add((subjtype, rschema, objtype)) |
482 if rschema.symetric: |
486 if rschema.symetric: |
483 self._synchronized.add((objtype, rschema, subjtype)) |
487 self._synchronized.add((objtype, rschema, subjtype)) |
484 confirm = self.verbosity >= 2 |
488 confirm = self.verbosity >= 2 |
485 # properties |
489 if syncprops: |
486 self.rqlexecall(ss.updaterdef2rql(rschema, subjtype, objtype), |
490 # properties |
487 ask_confirm=confirm) |
491 self.rqlexecall(ss.updaterdef2rql(rschema, subjtype, objtype), |
488 # constraints |
492 ask_confirm=confirm) |
489 rdef = rschema.rdef(subjtype, objtype) |
493 # constraints |
490 repordef = reporschema.rdef(subjtype, objtype) |
494 rdef = rschema.rdef(subjtype, objtype) |
491 newconstraints = list(rdef.constraints) |
495 repordef = reporschema.rdef(subjtype, objtype) |
492 # 1. remove old constraints and update constraints of the same type |
496 newconstraints = list(rdef.constraints) |
493 # NOTE: don't use rschema.constraint_by_type because it may be |
497 # 1. remove old constraints and update constraints of the same type |
494 # out of sync with newconstraints when multiple |
498 # NOTE: don't use rschema.constraint_by_type because it may be |
495 # constraints of the same type are used |
499 # out of sync with newconstraints when multiple |
496 for cstr in repordef.constraints: |
500 # constraints of the same type are used |
|
501 for cstr in repordef.constraints: |
|
502 for newcstr in newconstraints: |
|
503 if newcstr.type() == cstr.type(): |
|
504 break |
|
505 else: |
|
506 newcstr = None |
|
507 if newcstr is None: |
|
508 self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s', |
|
509 {'x': cstr.eid}, 'x', |
|
510 ask_confirm=confirm) |
|
511 self.rqlexec('DELETE CWConstraint C WHERE C eid %(x)s', |
|
512 {'x': cstr.eid}, 'x', |
|
513 ask_confirm=confirm) |
|
514 else: |
|
515 newconstraints.remove(newcstr) |
|
516 values = {'x': cstr.eid, |
|
517 'v': unicode(newcstr.serialize())} |
|
518 self.rqlexec('SET X value %(v)s WHERE X eid %(x)s', |
|
519 values, 'x', ask_confirm=confirm) |
|
520 # 2. add new constraints |
497 for newcstr in newconstraints: |
521 for newcstr in newconstraints: |
498 if newcstr.type() == cstr.type(): |
522 self.rqlexecall(ss.constraint2rql(rschema, subjtype, objtype, |
499 break |
523 newcstr), |
500 else: |
524 ask_confirm=confirm) |
501 newcstr = None |
|
502 if newcstr is None: |
|
503 self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s', |
|
504 {'x': cstr.eid}, 'x', |
|
505 ask_confirm=confirm) |
|
506 self.rqlexec('DELETE CWConstraint C WHERE C eid %(x)s', |
|
507 {'x': cstr.eid}, 'x', |
|
508 ask_confirm=confirm) |
|
509 else: |
|
510 newconstraints.remove(newcstr) |
|
511 values = {'x': cstr.eid, |
|
512 'v': unicode(newcstr.serialize())} |
|
513 self.rqlexec('SET X value %(v)s WHERE X eid %(x)s', |
|
514 values, 'x', ask_confirm=confirm) |
|
515 # 2. add new constraints |
|
516 for newcstr in newconstraints: |
|
517 self.rqlexecall(ss.constraint2rql(rschema, subjtype, objtype, |
|
518 newcstr), |
|
519 ask_confirm=confirm) |
|
520 if syncperms: |
525 if syncperms: |
521 self._synchronize_permissions(rdef, repordef.eid) |
526 self._synchronize_permissions(rdef, repordef.eid) |
522 |
527 |
523 # base actions ############################################################ |
528 # base actions ############################################################ |
524 |
529 |
907 if ertype is not None: |
912 if ertype is not None: |
908 if isinstance(ertype, (tuple, list)): |
913 if isinstance(ertype, (tuple, list)): |
909 assert len(ertype) == 3, 'not a relation definition' |
914 assert len(ertype) == 3, 'not a relation definition' |
910 assert syncprops, 'can\'t update permission for a relation definition' |
915 assert syncprops, 'can\'t update permission for a relation definition' |
911 self._synchronize_rdef_schema(ertype[0], ertype[1], ertype[2], |
916 self._synchronize_rdef_schema(ertype[0], ertype[1], ertype[2], |
912 syncperms=syncperms) |
917 syncperms=syncperms, |
913 elif syncprops: |
918 syncprops=syncprops) |
|
919 else: |
914 erschema = self.repo.schema[ertype] |
920 erschema = self.repo.schema[ertype] |
915 if isinstance(erschema, CubicWebRelationSchema): |
921 if isinstance(erschema, CubicWebRelationSchema): |
916 self._synchronize_rschema(erschema, syncperms=syncperms, |
922 self._synchronize_rschema(erschema, syncperms=syncperms, |
|
923 syncprops=syncprops, |
917 syncrdefs=syncrdefs) |
924 syncrdefs=syncrdefs) |
|
925 elif syncprops: |
|
926 self._synchronize_eschema(erschema, syncperms=syncperms) |
918 else: |
927 else: |
919 self._synchronize_eschema(erschema, syncperms=syncperms) |
928 self._synchronize_permissions(self.fs_schema[ertype], erschema.eid) |
920 else: |
|
921 erschema = self.repo.schema[ertype] |
|
922 self._synchronize_permissions(self.fs_schema[ertype], erschema.eid) |
|
923 else: |
929 else: |
924 for etype in self.repo.schema.entities(): |
930 for etype in self.repo.schema.entities(): |
925 if syncprops: |
931 if syncprops: |
926 self._synchronize_eschema(etype, syncperms=syncperms) |
932 self._synchronize_eschema(etype, syncperms=syncperms) |
927 else: |
933 else: |