Skip to content

Commit

Permalink
Merge pull request terminusdb#491 from terminusdb/key_strategy_update
Browse files Browse the repository at this point in the history
changing key strategy now validates existing objects
  • Loading branch information
GavinMendelGleason committed Sep 1, 2021
2 parents 0d7a9e0 + b468abd commit 97f2457
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 12 deletions.
32 changes: 22 additions & 10 deletions src/core/document/instance.pl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
:- module('document/instance', [
refute_instance/2,
refute_instance_schema/2,
refute_existing_object_keys/3,
is_instance/3,
is_instance2/3,
instance_of/3
Expand Down Expand Up @@ -262,22 +263,33 @@

refute_key(Validation_Object, Subject,Predicate,Class,Witness) :-
key_descriptor(Validation_Object, Class,Desc),
refute_key_(Desc,Validation_Object,Subject,Predicate,Witness).

refute_key_(lexical(_,Fields),Validation_Object,Subject,Predicate,Witness) :-
subject_predicate_updated(Validation_Object,Subject,Predicate),
refute_key_(Desc,Subject,Predicate,Witness).

refute_key_(lexical(_,Fields),Subject,Predicate,Witness) :-
member(Predicate,Fields),
Witness = json{ '@type' : lexical_key_changed,
subject: Subject }.
refute_key_(value_hash(_),Validation_Object,Subject,Predicate,Witness) :-
subject_predicate_updated(Validation_Object,Subject,Predicate),
subject: Subject,
predicate: Predicate}.
refute_key_(value_hash(_),Subject,Predicate,Witness) :-
Witness = json{ '@type' : value_key_changed,
subject: Subject }.
refute_key_(hash(_,Fields),Validation_Object,Subject,Predicate,Witness) :-
subject_predicate_updated(Validation_Object,Subject,Predicate),
subject: Subject,
predicate: Predicate}.
refute_key_(hash(_,Fields),Subject,Predicate,Witness) :-
member(Predicate,Fields),
Witness = json{ '@type' : hash_key_changed,
subject: Subject }.
subject: Subject,
predicate: Predicate}.

refute_existing_object_keys(Validation_Object,Class,Witness) :-
key_descriptor(Validation_Object, Class,Desc),
database_instance(Validation_Object, Instance),
global_prefix_expand(rdf:type, Rdf_Type),
distinct(Subject-Predicate,
( xrdf(Instance, Subject, Rdf_Type, Class),
xrdf(Instance, Subject, Predicate, _))),
refute_key_(Desc,Subject,Predicate,Witness).


refute_subject_deletion(Validation_Object, Subject,Witness) :-
subject_deleted(Validation_Object, Subject),
Expand Down
123 changes: 123 additions & 0 deletions src/core/document/json.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5168,6 +5168,129 @@
write_schema(schema5,Desc),
print_all_documents(Desc, schema).

test(incompatible_key_change,
[
setup(
( setup_temp_store(State),
create_db_with_empty_schema("admin", "foo"),
resolve_absolute_string_descriptor("admin/foo", Desc)
)),
cleanup(
teardown_temp_store(State)
),
error(schema_check_failure([json{'@type':lexical_key_changed,predicate:'http://somewhere.for.now/schema#f2',subject:'http://somewhere.for.now/document/Thing_foo'}]))
]) :-

create_context(Desc, commit_info{author: "test", message: "test"}, Context1),
Schema = _{ '@type' : "Class",
'@id' : "Thing",
'@key' : _{ '@type': "Lexical",
'@fields': ["f1"] },
'f1' : "xsd:string",
'f2' : "xsd:string"},

with_transaction(Context1,
insert_schema_document(Context1, Schema),
_),

create_context(Desc, commit_info{author: "test", message: "test"}, Context2),
with_transaction(Context2,
insert_document(Context2, _{'@type': "Thing",
'f1' : "foo",
'f2' : "bar"},
_),
_),


New_Schema = (Schema.put('@key', _{ '@type': "Lexical",
'@fields': ["f2"]})),
create_context(Desc, commit_info{author: "test", message: "test"}, Context3),

with_transaction(Context3,
replace_schema_document(Context3, New_Schema),
_).

test(compatible_key_change_same_value,
[
setup(
( setup_temp_store(State),
create_db_with_empty_schema("admin", "foo"),
resolve_absolute_string_descriptor("admin/foo", Desc)
)),
cleanup(
teardown_temp_store(State)
),
error(schema_check_failure([json{'@type':lexical_key_changed,predicate:'http://somewhere.for.now/schema#f2',subject:'http://somewhere.for.now/document/Thing_foo'}]))
]) :-

create_context(Desc, commit_info{author: "test", message: "test"}, Context1),
Schema = _{ '@type' : "Class",
'@id' : "Thing",
'@key' : _{ '@type': "Lexical",
'@fields': ["f1"] },
'f1' : "xsd:string",
'f2' : "xsd:string"},

with_transaction(Context1,
insert_schema_document(Context1, Schema),
_),

create_context(Desc, commit_info{author: "test", message: "test"}, Context2),
with_transaction(Context2,
insert_document(Context2, _{'@type': "Thing",
'f1' : "foo",
'f2' : "foo"},
_),
_),


New_Schema = (Schema.put('@key', _{ '@type': "Lexical",
'@fields': ["f2"]})),
create_context(Desc, commit_info{author: "test", message: "test"}, Context3),

with_transaction(Context3,
replace_schema_document(Context3, New_Schema),
_).

test(compatible_key_change_to_random,
[
setup(
( setup_temp_store(State),
create_db_with_empty_schema("admin", "foo"),
resolve_absolute_string_descriptor("admin/foo", Desc)
)),
cleanup(
teardown_temp_store(State)
)
]) :-

create_context(Desc, commit_info{author: "test", message: "test"}, Context1),
Schema = _{ '@type' : "Class",
'@id' : "Thing",
'@key' : _{ '@type': "Lexical",
'@fields': ["f1"] },
'f1' : "xsd:string",
'f2' : "xsd:string"},

with_transaction(Context1,
insert_schema_document(Context1, Schema),
_),

create_context(Desc, commit_info{author: "test", message: "test"}, Context2),
with_transaction(Context2,
insert_document(Context2, _{'@type': "Thing",
'f1' : "foo",
'f2' : "bar"},
_),
_),


New_Schema = (Schema.put('@key', _{ '@type': "Random"})),
create_context(Desc, commit_info{author: "test", message: "test"}, Context3),

with_transaction(Context3,
replace_schema_document(Context3, New_Schema),
_).

:- end_tests(schema_checker).

Expand Down
7 changes: 5 additions & 2 deletions src/core/document/schema.pl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
:- use_module(core(query), [has_at/1, compress_dict_uri/3]).

:- use_module(json). % This feels very circular.
:- use_module(instance). % This is most definitely circular.

is_unit(Class) :-
global_prefix_expand(sys:'Unit', Class).
Expand Down Expand Up @@ -409,8 +410,10 @@

refute_class_key(Validation_Object,Class,Witness) :-
database_schema(Validation_Object,Schema),
xrdf(Schema, Class, sys:key, Key_Obj),
refute_key_obj(Validation_Object,Class,Key_Obj, Witness).
xrdf_added(Schema, Class, sys:key, Key_Obj),
( refute_key_obj(Validation_Object,Class,Key_Obj, Witness)
-> true
; refute_existing_object_keys(Validation_Object,Class,Witness)).

refute_key_obj(Validation_Object,Class,Obj,Witness) :-
database_schema(Validation_Object,Schema),
Expand Down

0 comments on commit 97f2457

Please sign in to comment.