1:- module(terminus_store, [ 2 open_memory_store/1, 3 open_directory_store/2, 4 5 create_named_graph/3, 6 open_named_graph/3, 7 delete_named_graph/2, 8 9 head/2, 10 head/3, 11 nb_set_head/2, 12 nb_force_set_head/2, 13 nb_force_set_head/3, 14 15 open_write/2, 16 17 nb_add_triple/4, 18 nb_remove_triple/4, 19 nb_commit/2, 20 builder_committed/1, 21 nb_apply_delta/2, 22 nb_apply_diff/2, 23 24 node_and_value_count/2, 25 predicate_count/2, 26 subject_id/3, 27 predicate_id/3, 28 object_id/3, 29 30 id_triple/4, 31 triple/4, 32 33 id_triple_addition/4, 34 triple_addition/4, 35 36 id_triple_removal/4, 37 triple_removal/4, 38 39 sp_card/4, 40 41 parent/2, 42 squash/2, 43 44 layer_addition_count/2, 45 layer_removal_count/2, 46 layer_total_addition_count/2, 47 layer_total_removal_count/2, 48 layer_total_triple_count/2, 49 50 layer_to_id/2, 51 store_id_layer/3, 52 53 pack_export/3, 54 pack_layerids_and_parents/2, 55 pack_import/3, 56 57 csv_builder/3, 58 csv_builder/4, 59 csv_builder/5, 60 csv_iri/3, 61 62 count_layer_stack_size/2, 63 64 rollup/1, 65 rollup_upto/2, 66 imprecise_rollup_upto/2, 67 68 layer_stack_names/2, 69 layer_equals/2 70 ]). 71 72% There is two ways that this library is used. 73% 1. Standalone - in this case we need to load the internal foreign library. 74% 2. As part of TerminusDB - in this case we expect all the foreign 75% predicates to have been preloaded into the module '$terminus_store'. 76% 77% The reason for this is that TerminusDB builds its own rust module 78% which bundles the internal foreign library. This is necessary cause 79% otherwise TerminusDB is unable to make use of the types defined in 80% this library, as these are not exposed through ordinarly shared 81% objects. TerminusDB needs these types in order to build 82% TerminusDB-specific native logic that works with store, graph, 83% layer, and builder blobs. 84% 85% In order to switch between the two kinds of behavior, TerminusDB 86% defines a special prolog flag, 'terminusdb_monolithic_module'. This 87% suppresses loading of the internal library, and instead imports 88% foreign predicates which are expected to have been preloaded into 89% '$terminus_store'. 90:- if(current_prolog_flag(terminusdb_monolithic_module, true)). 91:- add_import_module('terminus_store', '$terminus_store', start). 92:- else. 93:- use_foreign_library(foreign(libterminus_store)). 94:- endif. 95 96:- use_module(library(lists)). 97:- use_module(library(option)). 98:- use_module(library(plunit)). 99:- use_module(library(random)). 100 101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 102%%% pldocs for the foreign predicates %%% 103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This predicate does not check if the directory actually exists, but other store-related predicates will error when used with a store backed by a non-existent directory.
Fails if no graph with that name exists.
Fails if no graph with that name exists.
Fails if the given graph has no head yet.
Fails if the given graph has no head yet.
Fails if the new layer is not a proper child of the current head.
This predicate does not support backtracking.
Fails if the new layer is not a proper child of the current head.
This predicate does not support backtracking.
When Store_Or_Layer is a store, the resulting builder will create a base layer.
When Store_Or_Layer is a layer, the resulting builder will create a child layer whose parent is the given layer.
This fails if any of the Ids is out of range, or if the triple already exists, either in this builder or in a parent layer.
This fails if the triple already exists in this builder object or a parent layer.
This fails if the triple already exists in this builder object or a parent layer.
This fails if any of the Ids is out of range, or if the triple does not exist in a parent layer, or if the removal has already been registered in this builder.
This fails if the triple does not exist in a parent layer, or if the removal has already been registered in this builder.
This fails if the triple does not exist in a parent layer, or if the removal has already been registered in this builder.
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451%%% End of foreign predicate pldocs %%%
452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457nb_add_triple(Builder, Subject, Predicate, Object) :- 458 integer(Subject), 459 integer(Predicate), 460 integer(Object), 461 !, 462 nb_add_id_triple(Builder, Subject, Predicate, Object). 463 464nb_add_triple(Builder, Subject, Predicate, Object) :- 465 !, 466 nb_add_string_triple(Builder, Subject, Predicate, Object). 467 468/* 469 * nb_add_triple(+Builder, +Subject, +Predicate, +Object) is semidet 470 * 471 * Remove a trible from the builder 472 */ 473nb_remove_triple(Builder, Subject, Predicate, Object) :- 474 integer(Subject), 475 integer(Predicate), 476 integer(Object), 477 !, 478 nb_remove_id_triple(Builder, Subject, Predicate, Object). 479 480nb_remove_triple(Builder, Subject, Predicate, Object) :- 481 !, 482 nb_remove_string_triple(Builder, Subject, Predicate, Object). 483 484/* 485 * subject_id(+Layer, +Subject, -Id) is semidet 486 * 487 * Get the ID from a subject 488 */ 489subject_id(Layer, Subject, Id) :- 490 ground(Id), 491 !, 492 id_to_subject(Layer, Id, Subject). 493 494subject_id(Layer, Subject, Id) :- 495 ground(Subject), 496 !, 497 subject_to_id(Layer, Subject, Id). 498 499subject_id(Layer, Subject, Id) :- 500 node_and_value_count(Layer, Count), 501 between(1, Count, Id), 502 id_to_subject(Layer, Id, Subject). 503 504 505/* 506 * predicate_id(+Layer, +Predicate, -Id) is semidet 507 * 508 * Get the ID from a predicate 509 */ 510predicate_id(Layer, Predicate, Id) :- 511 ground(Id), 512 !, 513 id_to_predicate(Layer, Id, Predicate). 514 515predicate_id(Layer, Predicate, Id) :- 516 ground(Predicate), 517 !, 518 predicate_to_id(Layer, Predicate, Id). 519 520predicate_id(Layer, Predicate, Id) :- 521 node_and_value_count(Layer, Count), 522 between(1, Count, Id), 523 id_to_predicate(Layer, Id, Predicate). 524 525 526/* 527 * object_id(+Layer, +Predicate, -Id) is semidet 528 * 529 * Get the ID from an object 530 */ 531object_id(Layer, Object, Id) :- 532 ground(Id), 533 !, 534 id_to_object(Layer, Id, Object). 535 536object_id(Layer, node(Object), Id) :- 537 ground(Object), 538 !, 539 object_to_id(Layer, node(Object), Id). 540 541object_id(Layer, value(Object), Id) :- 542 ground(Object), 543 !, 544 object_to_id(Layer, value(Object), Id). 545 546object_id(Layer, Object, Id) :- 547 node_and_value_count(Layer, Count), 548 between(1, Count, Id), 549 id_to_object(Layer, Id, Object). 550 551triple(Layer, Subject, Predicate, Object) :- 552 ( ground(Subject) 553 -> subject_id(Layer, Subject, S_Id) 554 ; true), 555 556 ( ground(Predicate) 557 -> predicate_id(Layer, Predicate, P_Id) 558 ; true), 559 560 ( ground(Object) 561 -> object_id(Layer, Object, O_Id) 562 ; true), 563 564 id_triple(Layer, S_Id, P_Id, O_Id), 565 566 ( ground(Subject) 567 -> true 568 ; subject_id(Layer, Subject, S_Id)), 569 570 571 ( ground(Predicate) 572 -> true 573 ; predicate_id(Layer, Predicate, P_Id)), 574 575 576 ( ground(Object) 577 -> true 578 ; object_id(Layer,Object, O_Id)). 579 580csv_builder(Name, Csv, Builder) :- 581 csv_builder(Name, Csv,Builder,[]). 582 583csv_builder(Name, Csv, Builder, Options) :- 584 option(data_prefix(Data), Options, 'csv:///data/'), 585 option(schema_prefix(Schema), Options, 'csv:///schema#'), 586 option(header(Header), Options, true), 587 option(skip_header(Skip), Options, false), 588 csv_builder(Name, Csv, Builder, Data, Schema, Header, Skip). 589 590csv_builder(Name, Csv, Builder, Schema_Builder, Options) :- 591 option(data_prefix(Data), Options, 'csv:///data/'), 592 option(schema_prefix(Schema), Options, 'csv:///schema#'), 593 option(header(Header), Options, true), 594 option(skip_header(Skip), Options, false), 595 csv_builder(Name, Csv, Builder, Schema_Builder, Data, Schema, Header, Skip). 596 597triple_addition(Layer, Subject, Predicate, Object) :- 598 ( ground(Subject) 599 -> subject_id(Layer, Subject, S_Id) 600 ; true), 601 602 ( ground(Predicate) 603 -> predicate_id(Layer, Predicate, P_Id) 604 ; true), 605 606 ( ground(Object) 607 -> object_id(Layer, Object, O_Id) 608 ; true), 609 610 id_triple_addition(Layer, S_Id, P_Id, O_Id), 611 612 ( ground(Subject) 613 -> true 614 ; subject_id(Layer, Subject, S_Id)), 615 616 617 ( ground(Predicate) 618 -> true 619 ; predicate_id(Layer, Predicate, P_Id)), 620 621 622 ( ground(Object) 623 -> true 624 ; object_id(Layer,Object, O_Id)). 625 626triple_removal(Layer, Subject, Predicate, Object) :- 627 ( ground(Subject) 628 -> subject_id(Layer, Subject, S_Id) 629 ; true), 630 631 ( ground(Predicate) 632 -> predicate_id(Layer, Predicate, P_Id) 633 ; true), 634 635 ( ground(Object) 636 -> object_id(Layer, Object, O_Id) 637 ; true), 638 639 id_triple_removal(Layer, S_Id, P_Id, O_Id), 640 641 ( ground(Subject) 642 -> true 643 ; subject_id(Layer, Subject, S_Id)), 644 645 646 ( ground(Predicate) 647 -> true 648 ; predicate_id(Layer, Predicate, P_Id)), 649 650 651 ( ground(Object) 652 -> true 653 ; object_id(Layer,Object, O_Id)). 654 655count_layer_stack_size(Layer, Acc, Count) :- 656 parent(Layer, Parent), 657 !, 658 NextAcc is Acc + 1, 659 count_layer_stack_size(Parent, NextAcc, Count). 660count_layer_stack_size(_Layer, Acc, Count) :- 661 Count is Acc + 1. 662 663count_layer_stack_size(Layer, Count) :- 664 count_layer_stack_size(Layer, 0, Count). 665 666 667layer_stack_names(Layer, Stack) :- 668 ground(Layer), 669 !, 670 retrieve_layer_stack_names(Layer, Stack). 671layer_stack_names(_Layer, _Stack) :- 672 throw(error(domain_error('Layer not bound in layer_stack_names/2'),_)). 673 674:- begin_tests(terminus_store). 675 676:- use_module(library(filesex)). 677 678 /******************************* 679 * Developer Utilities * 680 *******************************/
685random_string(String) :- 686 Size is 2 ** (20 * 8), 687 random(0, Size, Num), 688 format(string(String), '~36r', [Num]). 689 690clean(TestDir) :- 691 delete_directory_and_contents(TestDir). 692 693createng(TestDir) :- 694 random_string(RandomString), 695 atomic_list_concat(["testdir", RandomString], TestDir), 696 make_directory(TestDir), 697 open_directory_store(TestDir, X), 698 create_named_graph(X, "sometestdb", _). 699 700create_memory_ng(DB) :- 701 open_memory_store(X), 702 create_named_graph(X, "sometestdb", DB). 703 704test(open_memory_store) :- 705 open_memory_store(_). 706 707test(open_directory_store_atom) :- 708 open_directory_store(this_is_an_atom, _), 709 open_directory_store("this is a string", _). 710 711test(open_directory_store_atom_exception, [ 712 throws(error(type_error(text,234), _)) 713 ]) :- 714 open_directory_store(234, _). 715 716test(create_db, [cleanup(clean(TestDir))]) :- 717 make_directory("testdir"), 718 TestDir = 'testdir', 719 open_directory_store("testdir", X), 720 create_named_graph(X, "sometestdb", _). 721 722 723test(create_db_on_memory) :- 724 open_memory_store(X), 725 create_named_graph(X, "sometestdb", _). 726 727test(open_named_graph, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 728 open_directory_store(TestDir, X), 729 open_named_graph(X, "sometestdb", _). 730 731test(open_named_graph_memory) :- 732 open_memory_store(X), 733 create_named_graph(X, "sometestdb", _), 734 open_named_graph(X, "sometestdb", _). 735 736test(delete_named_graph_memory) :- 737 open_memory_store(X), 738 create_named_graph(X, "sometestdb", _), 739 delete_named_graph(X, "sometestdb"), 740 \+ open_named_graph(X, "sometestdb", _). 741 742test(delete_named_graph_directory, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 743 open_directory_store(TestDir, X), 744 \+ delete_named_graph(X, "unknowndb"). 745 746test(head_from_empty_db, [fail, cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 747 open_directory_store(TestDir, X), 748 open_named_graph(X, "sometestdb", DB), 749 head(DB, _). % should be false because we have no HEAD yet 750 751test(head_from_empty_db_memory, [fail, setup(create_memory_ng(DB))]) :- 752 head(DB, _). 753 754test(open_write_from_db_without_head, [ 755 cleanup(clean(TestDir)), 756 setup(createng(TestDir)), 757 throws( 758 error(cannot_open_named_graph_without_base_layer, _) 759 )]) :- 760 open_directory_store(TestDir, X), 761 open_named_graph(X, "sometestdb", DB), 762 open_write(DB, _). 763 764test(open_write_from_db_with_head, [ 765 cleanup(clean(TestDir)), 766 setup(createng(TestDir)) 767 ]) :- 768 open_directory_store(TestDir, Store), 769 open_write(Store, Builder), 770 nb_commit(Builder, Layer), 771 open_named_graph(Store, "sometestdb", DB), 772 nb_set_head(DB, Layer), 773 open_write(DB, _). 774 775 776test(open_write_from_memory_ng_without_head, [ 777 setup(create_memory_ng(DB)), 778 throws( 779 error(cannot_open_named_graph_without_base_layer, _) 780 )]) :- 781 open_write(DB, _). 782 783test(create_base_layer, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 784 open_directory_store(TestDir, Store), 785 open_write(Store, _). 786 787 788test(create_base_layer_memory) :- 789 open_memory_store(Store), 790 open_write(Store, _). 791 792test(write_value_triple, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 793 open_directory_store(TestDir, Store), 794 open_write(Store, Builder), 795 nb_add_string_triple(Builder, "Subject", "Predicate", value("Object")). 796 797test(write_value_triple_memory) :- 798 open_memory_store(Store), 799 open_write(Store, Builder), 800 nb_add_string_triple(Builder, "Subject", "Predicate", value("Object")). 801 802test(commit_and_set_header, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 803 open_directory_store(TestDir, Store), 804 open_write(Store, Builder), 805 open_named_graph(Store, "sometestdb", DB), 806 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 807 nb_commit(Builder, Layer), 808 nb_set_head(DB, Layer). 809 810 811test(commit_and_set_header_version_first, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 812 open_directory_store(TestDir, Store), 813 open_write(Store, Builder), 814 open_named_graph(Store, "sometestdb", DB), 815 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 816 nb_commit(Builder, Layer), 817 nb_force_set_head(DB, Layer, 0). 818 819 820test(commit_and_set_header_version_first_wrong_version, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 821 open_directory_store(TestDir, Store), 822 open_write(Store, Builder), 823 open_named_graph(Store, "sometestdb", DB), 824 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 825 nb_commit(Builder, Layer), 826 \+ nb_force_set_head(DB, Layer, 1). 827 828test(commit_and_set_header_version_multiple_commits, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 829 open_directory_store(TestDir, Store), 830 open_write(Store, Builder), 831 open_named_graph(Store, "sometestdb", DB), 832 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 833 nb_commit(Builder, Layer), 834 nb_force_set_head(DB, Layer, 0), 835 836 head(DB, _, 1), 837 838 open_write(Store, Builder2), 839 nb_add_triple(Builder2, "Subject2", "Predicate2", value("Object2")), 840 nb_commit(Builder2, Layer2), 841 nb_force_set_head(DB, Layer2, 1), 842 843 head(DB, _, 2), 844 \+ head(DB, _, 3). 845 846 847test(commit_and_set_header_version_incorrect, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 848 open_directory_store(TestDir, Store), 849 open_write(Store, Builder), 850 open_named_graph(Store, "sometestdb", DB), 851 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 852 nb_commit(Builder, Layer), 853 \+ nb_force_set_head(DB, Layer, 1). 854 855 856test(commit_and_set_header_version_multiples_incorrect, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 857 open_directory_store(TestDir, Store), 858 open_write(Store, Builder), 859 open_named_graph(Store, "sometestdb", DB), 860 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 861 nb_commit(Builder, Layer), 862 nb_force_set_head(DB, Layer, 0), 863 864 head(DB, _, 1), 865 866 open_write(Store, Builder2), 867 nb_add_triple(Builder2, "Subject2", "Predicate2", value("Object2")), 868 nb_commit(Builder2, Layer2), 869 \+ nb_force_set_head(DB, Layer2, 0). 870 871 872test(commit_and_set_header_memory) :- 873 open_memory_store(Store), 874 open_write(Store, Builder), 875 create_named_graph(Store, "sometestdb", DB), 876 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 877 nb_commit(Builder, Layer), 878 nb_set_head(DB, Layer). 879 880test(head_after_first_commit, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 881 open_directory_store(TestDir, Store), 882 open_named_graph(Store, "sometestdb", DB), 883 open_write(Store, Builder), 884 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 885 nb_commit(Builder, Layer), 886 nb_set_head(DB, Layer), 887 head(DB, _). 888 889test(predicate_count, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 890 open_directory_store(TestDir, Store), 891 open_named_graph(Store, "sometestdb", DB), 892 open_write(Store, Builder), 893 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 894 nb_commit(Builder, Layer), 895 nb_set_head(DB, Layer), 896 head(DB, LayerHead), 897 predicate_count(LayerHead, Count), 898 Count == 1. 899 900test(node_and_value_count, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 901 open_directory_store(TestDir, Store), 902 open_write(Store, Builder), 903 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 904 nb_commit(Builder, Layer), 905 node_and_value_count(Layer, Count), 906 Count == 2. 907 908test(predicate_count_2, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 909 open_directory_store(TestDir, Store), 910 open_named_graph(Store, "sometestdb", DB), 911 open_write(Store, Builder), 912 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 913 nb_add_triple(Builder, "Subject2", "Predicate2", value("Object2")), 914 nb_commit(Builder, Layer), 915 nb_set_head(DB, Layer), 916 predicate_count(Layer, Count), 917 Count == 2. 918 919test(remove_triple, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 920 open_directory_store(TestDir, Store), 921 open_write(Store, Builder), 922 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 923 nb_commit(Builder, Layer), 924 open_write(Layer, LayerBuilder), 925 nb_remove_triple(LayerBuilder, "Subject", "Predicate", value("Object")). 926 927test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 928 open_directory_store(TestDir, Store), 929 open_write(Store, Builder), 930 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 931 nb_commit(Builder, Layer), 932 setof(X, triple(Layer, "Subject", "Predicate", value(X)), Bag), 933 Bag == ["Object"]. 934 935 936test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 937 open_directory_store(TestDir, Store), 938 open_write(Store, Builder), 939 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 940 nb_commit(Builder, Layer), 941 setof(Y-X, triple(Layer, "Subject", Y, value(X)), Bag), 942 Bag == ["Predicate"-"Object"]. 943 944 945test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 946 open_directory_store(TestDir, Store), 947 open_write(Store, Builder), 948 nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 949 nb_commit(Builder, Layer), 950 setof(X-Y-Z, triple(Layer, X, Y, value(Z)), Bag), 951 Bag == ["Subject"-"Predicate"-"Object"]. 952 953test(backtracking_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 954 open_directory_store(TestDir, Store), 955 open_write(Store, Builder), 956 create_named_graph(Store, "testdb", DB), 957 nb_add_triple(Builder, "A", "B", node("C")), 958 nb_add_triple(Builder, "A", "D", node("C")), 959 nb_add_triple(Builder, "A", "E", node("C")), 960 nb_add_triple(Builder, "A", "E", node("O")), 961 nb_add_triple(Builder, "A", "D", node("O")), 962 nb_commit(Builder, Layer), 963 nb_set_head(DB, Layer), 964 965 findall(P, triple(Layer, "A", P, node("O")), Ps), 966 Ps = ["D", "E"]. 967 968test(query_builder_for_committed, [cleanup(clean(TestDir)),setup(createng(TestDir))]) :- 969 open_directory_store(TestDir, Store), 970 open_write(Store, Builder), 971 972 \+ builder_committed(Builder), 973 974 nb_commit(Builder, _Layer), 975 976 builder_committed(Builder). 977 978test(squash_a_tower,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 979 open_directory_store(TestDir, Store), 980 open_write(Store, Builder), 981 create_named_graph(Store, "testdb", DB), 982 nb_add_triple(Builder, "joe", "eats", node("urchin")), 983 nb_commit(Builder, Layer), 984 985 open_write(Layer,Builder2), 986 nb_add_triple(Builder2, "jill", "eats", node("caviar")), 987 nb_commit(Builder2, Layer2), 988 989 squash(Layer2,Squashed_Layer), 990 991 nb_set_head(DB, Squashed_Layer), 992 993 open_named_graph(Store, "testdb", DB2), 994 head(DB2,Squash), 995 996 findall(X-P-Y, triple(Squash, X, P, Y), Triples), 997 998 Triples = ["jill"-"eats"-node("caviar"), 999 "joe"-"eats"-node("urchin") 1000 ], 1001 \+ parent(Squash,_). 1002 1003 1004test(force_set_head,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1005 open_directory_store(TestDir, Store), 1006 open_write(Store, Builder1), 1007 create_named_graph(Store, "testdb", DB1), 1008 nb_add_triple(Builder1, "joe", "eats", node("urchin")), 1009 nb_commit(Builder1, _Layer1), 1010 1011 open_write(Store, Builder2), 1012 nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1013 nb_commit(Builder2, Layer2), 1014 1015 nb_force_set_head(DB1,Layer2), 1016 1017 head(DB1,Layer3), 1018 findall(X-P-Y, triple(Layer3, X, P, Y), Triples), 1019 1020 Triples = ["jill"-"eats"-node("caviar")], 1021 1022 \+ parent(Layer3,_). 1023 1024test(apply_a_delta,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1025 open_directory_store(TestDir, Store), 1026 open_write(Store, Builder), 1027 nb_add_triple(Builder, "joe", "eats", node("urchin")), 1028 nb_commit(Builder, Layer), 1029 1030 open_write(Layer,Builder2), 1031 nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1032 nb_commit(Builder2, Delta), 1033 1034 open_write(Store, Builder_Base), 1035 nb_add_triple(Builder_Base, "cathie", "eats", node("seaweed")), 1036 nb_commit(Builder_Base, Base), 1037 1038 open_write(Base, Builder_New), 1039 nb_apply_delta(Builder_New,Delta), 1040 nb_commit(Builder_New,Final_Layer), 1041 1042 findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1043 1044 Triples = ["cathie"-"eats"-node("seaweed"), 1045 "jill"-"eats"-node("caviar") 1046 ]. 1047 1048test(apply_a_diff,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1049 open_directory_store(TestDir, Store), 1050 open_write(Store, Builder), 1051 nb_add_triple(Builder, "joe", "eats", node("urchin")), 1052 nb_add_triple(Builder, "jill", "eats", node("caviar")), 1053 nb_add_triple(Builder, "cathie", "eats", node("seaweed")), 1054 nb_commit(Builder, Layer), 1055 1056 open_write(Store, Builder2), 1057 nb_add_triple(Builder2, "joe", "eats", node("seals")), 1058 nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1059 nb_commit(Builder2, Prototype), 1060 1061 open_write(Layer, Diff_Builder), 1062 nb_apply_diff(Diff_Builder,Prototype), 1063 nb_commit(Diff_Builder,Final_Layer), 1064 1065 findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1066 Triples = [ 1067 "jill"-"eats"-node("caviar"), 1068 "joe"-"eats"-node("seals") 1069 ], 1070 1071 findall(X-P-Y, triple_addition(Final_Layer, X, P, Y), Triple_Additions), 1072 Triple_Additions = [ 1073 "joe"-"eats"-node("seals") 1074 ], 1075 1076 findall(X-P-Y, triple_removal(Final_Layer, X, P, Y), Triple_Removals), 1077 Triple_Removals = [ 1078 "cathie"-"eats"-node("seaweed"), 1079 "joe"-"eats"-node("urchin") 1080 ]. 1081 1082test(apply_empty_diff,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1083 open_directory_store(TestDir, Store), 1084 open_write(Store, Builder), 1085 nb_add_triple(Builder, "joe", "eats", node("urchin")), 1086 nb_add_triple(Builder, "jill", "eats", node("caviar")), 1087 nb_add_triple(Builder, "cathie", "eats", node("seaweed")), 1088 nb_commit(Builder, Prototype), 1089 1090 open_write(Store, Diff_Builder), 1091 nb_apply_diff(Diff_Builder,Prototype), 1092 nb_commit(Diff_Builder,Final_Layer), 1093 1094 findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1095 1096 Triples = [ 1097 "cathie"-"eats"-node("seaweed"), 1098 "jill"-"eats"-node("caviar"), 1099 "joe"-"eats"-node("urchin") 1100 ], 1101 1102 findall(X-P-Y, triple_addition(Final_Layer, X, P, Y), Triple_Additions), 1103 Triple_Additions = Triples, 1104 findall(X-P-Y, triple_removal(Final_Layer, X, P, Y), Triple_Removals), 1105 Triple_Removals = []. 1106 1107test(add_csv,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1108 open_directory_store(TestDir, Store), 1109 open_write(Store, Builder), 1110 tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1111 format(Stream, "some,header~n", []), 1112 format(Stream, "1,2~n", []), 1113 format(Stream, "3,4~n", []), 1114 close(Stream), 1115 csv_builder("csv",Filename, Builder, []), 1116 nb_commit(Builder, Layer), 1117 findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1118 1119 Triples = [ 1120 X-"csv:///schema#csv_column_header"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1121 X-"csv:///schema#csv_column_some"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1122 X-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row1), 1123 Y-"csv:///schema#csv_column_header"-value("\"4\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1124 Y-"csv:///schema#csv_column_some"-value("\"3\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1125 Y-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row1), 1126 "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_header"), 1127 "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_some"), 1128 "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(X), 1129 "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Y), 1130 "csv:///data/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#CSV"), 1131 "csv:///data/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1132 "csv:///data/ColumnObject_csv_header"-"csv:///schema#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1133 "csv:///data/ColumnObject_csv_header"-"csv:///schema#csv_column_name"-value("\"header\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1134 "csv:///data/ColumnObject_csv_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column"), 1135 "csv:///data/ColumnObject_csv_some"-"csv:///schema#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1136 "csv:///data/ColumnObject_csv_some"-"csv:///schema#csv_column_name"-value("\"some\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1137 "csv:///data/ColumnObject_csv_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column") 1138 ]. 1139 1140test(add_csv_skip_header,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1141 open_directory_store(TestDir, Store), 1142 open_write(Store, Builder), 1143 tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1144 format(Stream, "1,2~n", []), 1145 format(Stream, "3,4~n", []), 1146 close(Stream), 1147 csv_builder("csv",Filename, Builder, [skip_header(true)]), 1148 nb_commit(Builder, Layer), 1149 findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1150 Triples = [ 1151 Row1-"csv:///schema#csv_column_0"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1152 Row1-"csv:///schema#csv_column_1"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1153 Row1-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row_Type), 1154 Row2-"csv:///schema#csv_column_0"-value("\"3\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1155 Row2-"csv:///schema#csv_column_1"-value("\"4\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1156 Row2-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row_Type), 1157 "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_0"), 1158 "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_1"), 1159 "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Row1), 1160 "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Row2), 1161 "csv:///data/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#CSV"), 1162 "csv:///data/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1163 "csv:///data/ColumnObject_csv_0"-"csv:///schema#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1164 "csv:///data/ColumnObject_csv_0"-"csv:///schema#csv_column_name"-value("\"0\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1165 "csv:///data/ColumnObject_csv_0"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column"), 1166 "csv:///data/ColumnObject_csv_1"-"csv:///schema#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1167 "csv:///data/ColumnObject_csv_1"-"csv:///schema#csv_column_name"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1168 "csv:///data/ColumnObject_csv_1"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column") 1169 ]. 1170 1171test(csv_prefixes,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1172 open_directory_store(TestDir, Store), 1173 open_write(Store, Builder), 1174 1175 tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1176 format(Stream, "some,header~n", []), 1177 format(Stream, "1,2~n", []), 1178 close(Stream), 1179 1180 csv_builder("csv",Filename, Builder, [data_prefix('that/'), 1181 schema_prefix('this#')]), 1182 nb_commit(Builder, Layer), 1183 findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1184 1185 Triples = [ 1186 Row1-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(_), 1187 Row1-"this#csv_column_header"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1188 Row1-"this#csv_column_some"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1189 "that/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#CSV"), 1190 "that/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1191 "that/CSV_csv"-"this#csv_column"-node("that/ColumnObject_csv_header"), 1192 "that/CSV_csv"-"this#csv_column"-node("that/ColumnObject_csv_some"), 1193 "that/CSV_csv"-"this#csv_row"-node(Row1), 1194 "that/ColumnObject_csv_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#Column"), 1195 "that/ColumnObject_csv_header"-"this#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1196 "that/ColumnObject_csv_header"-"this#csv_column_name"-value("\"header\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1197 "that/ColumnObject_csv_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#Column"), 1198 "that/ColumnObject_csv_some"-"this#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1199 "that/ColumnObject_csv_some"-"this#csv_column_name"-value("\"some\"^^'http://www.w3.org/2001/XMLSchema#string'") 1200 ]. 1201 1202test(csv_with_schema,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1203 open_directory_store(TestDir, Store), 1204 open_write(Store, Builder), 1205 open_write(Store, Schema_Builder), 1206 tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1207 format(Stream, "some,header~n", []), 1208 format(Stream, "1,2~n", []), 1209 format(Stream, "3,4~n", []), 1210 close(Stream), 1211 csv_builder("csv",Filename, Builder, Schema_Builder, 1212 [data_prefix('data/'), 1213 schema_prefix('')]), 1214 nb_commit(Schema_Builder, Schema_Layer), 1215 findall(X-P-Y, triple(Schema_Layer, X, P, Y), Schema_Triples), 1216 1217 Schema_Expected = [ 1218 "CSV"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1219 "CSV"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV object\"@en"), 1220 "CSV"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV\"@en"), 1221 "CSV"-"http://www.w3.org/2000/01/rdf-schema#subClassOf"-node("http://terminusdb.com/schema/system#Document"), 1222 "CSVRow"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1223 "CSVRow"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Generic Row of a CSV file\"@en"), 1224 "CSVRow"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV Row\"@en"), 1225 Row_Type-"http://terminusdb.com/schema/system#csv_name"-value("\"csv\"@en"), 1226 Row_Type-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1227 Row_Type-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Row object for columns [\\\"header\\\", \\\"some\\\"]\"@en"), 1228 Row_Type-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV Row from csv\"@en"), 1229 Row_Type-"http://www.w3.org/2000/01/rdf-schema#subClassOf"-node("CSVRow"), 1230 "Column"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1231 "Column"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Column information object for a CSV\"@en"), 1232 "Column"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column\"@en"), 1233 "csv_column_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1234 "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Column for header name header\"@en"), 1235 "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#domain"-node(Row_Type), 1236 "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column header\"@en"), 1237 "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1238 "csv_column_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1239 "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Column for header name some\"@en"), 1240 "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#domain"-node(Row_Type), 1241 "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column some\"@en"), 1242 "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1243 "csv_column"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#ObjectProperty"), 1244 "csv_column"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Associates a CSV with a column object\"@en"), 1245 "csv_column"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("CSV"), 1246 "csv_column"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column\"@en"), 1247 "csv_column"-"http://www.w3.org/2000/01/rdf-schema#range"-node("Column"), 1248 "csv_column_index"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1249 "csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"The ordering index for a column in a csv\"@en"),"csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("Column"), 1250 "csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column index\"@en"),"csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#integer"), 1251 "csv_column_name"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1252 "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"The name of the column as it was verbatim in the CSV\"@en"), 1253 "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("Column"), 1254 "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column name\"@en"), 1255 "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1256 "csv_row"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#ObjectProperty"), 1257 "csv_row"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Connects a CSV to its rows\"@en"), 1258 "csv_row"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("CSV"), 1259 "csv_row"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv row\"@en"), 1260 "csv_row"-"http://www.w3.org/2000/01/rdf-schema#range"-node("CSVRow") 1261 ], 1262 1263 forall(member(Triple,Schema_Triples), 1264 ( member(Triple,Schema_Expected))). 1265 1266test(so_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1267 open_directory_store(TestDir, Store), 1268 open_write(Store, Builder), 1269 nb_add_triple(Builder, "A", "B", node("C")), 1270 nb_add_triple(Builder, "A", "B", node("D")), 1271 nb_commit(Builder, Layer), 1272 findall(X-C, triple(Layer, X, "B", C), Ps), 1273 Ps = ["A"-node("C"), 1274 "A"-node("D")]. 1275 1276test(sp_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1277 open_directory_store(TestDir, Store), 1278 open_write(Store, Builder), 1279 nb_add_triple(Builder, "A", "B", node("D")), 1280 nb_add_triple(Builder, "C", "B", node("D")), 1281 nb_commit(Builder, Layer), 1282 findall(X-C, triple(Layer, X, C, node("D")), Ps), 1283 Ps = ["A"-"B", 1284 "C"-"B"]. 1285 1286test(op_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1287 open_directory_store(TestDir, Store), 1288 open_write(Store, Builder), 1289 nb_add_triple(Builder, "A", "B", node("D")), 1290 nb_add_triple(Builder, "C", "B", node("D")), 1291 nb_commit(Builder, Layer), 1292 findall(X, triple(Layer, X, "B", node("D")), Ps), 1293 Ps = ["A","C"]. 1294 1295test(p_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1296 open_directory_store(TestDir, Store), 1297 open_write(Store, Builder), 1298 nb_add_triple(Builder, "A", "B", node("D")), 1299 nb_add_triple(Builder, "C", "B", node("D")), 1300 nb_commit(Builder, Layer), 1301 findall(X, triple(Layer, "A", X, node("D")), Ps), 1302 Ps = ["B"]. 1303 1304test(rollup,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1305 open_directory_store(TestDir, Store), 1306 open_write(Store, Builder), 1307 nb_add_triple(Builder, "A", "B", node("D")), 1308 nb_add_triple(Builder, "C", "B", node("D")), 1309 nb_commit(Builder, Layer), 1310 1311 open_write(Layer, New_Builder), 1312 nb_add_triple(New_Builder, "E", "F", node("G")), 1313 nb_remove_triple(New_Builder, "C", "B", node("D")), 1314 nb_commit(New_Builder, New_Layer), 1315 rollup(New_Layer), 1316 layer_to_id(New_Layer, Id), 1317 store_id_layer(Store, Id, Rollup), 1318 findall(X-P-Y, triple(Rollup, X, P, node(Y)), Triples), 1319 1320 Triples = ["A"-"B"-"D","E"-"F"-"G"]. 1321 1322test(rollup_upto,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1323 open_directory_store(TestDir, Store), 1324 open_write(Store, Builder), 1325 nb_add_triple(Builder, "A", "B", node("D")), 1326 nb_add_triple(Builder, "C", "B", node("D")), 1327 nb_commit(Builder, Layer), 1328 1329 open_write(Layer, New_Builder), 1330 nb_add_triple(New_Builder, "E", "F", node("G")), 1331 nb_remove_triple(New_Builder, "C", "B", node("D")), 1332 nb_commit(New_Builder, New_Layer), 1333 1334 open_write(New_Layer, New_Builder_2), 1335 nb_add_triple(New_Builder_2, "G", "H", node("I")), 1336 nb_remove_triple(New_Builder_2, "A", "B", node("D")), 1337 nb_commit(New_Builder_2, New_Layer_2), 1338 1339 rollup_upto(New_Layer_2, Layer), 1340 layer_to_id(New_Layer_2, Id), 1341 1342 store_id_layer(Store, Id, Rollup), 1343 findall(X-P-Y, triple(Rollup, X, P, node(Y)), Triples), 1344 1345 Triples = ["E"-"F"-"G","G"-"H"-"I"]. 1346 1347test(layer_stack_names,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1348 open_directory_store(TestDir, Store), 1349 open_write(Store, Builder), 1350 nb_add_triple(Builder, "A", "B", node("D")), 1351 nb_add_triple(Builder, "C", "B", node("D")), 1352 nb_commit(Builder, Layer), 1353 layer_to_id(Layer, Layer_Id), 1354 1355 open_write(Layer, New_Builder), 1356 nb_add_triple(New_Builder, "E", "F", node("G")), 1357 nb_remove_triple(New_Builder, "C", "B", node("D")), 1358 nb_commit(New_Builder, New_Layer), 1359 layer_to_id(New_Layer, New_Layer_Id), 1360 1361 open_write(New_Layer, New_Builder_2), 1362 nb_add_triple(New_Builder_2, "G", "H", node("I")), 1363 nb_remove_triple(New_Builder_2, "A", "B", node("D")), 1364 nb_commit(New_Builder_2, New_Layer_2), 1365 layer_to_id(New_Layer_2, New_Layer_2_Id), 1366 1367 layer_stack_names(New_Layer_2, Layers), 1368 1369 Expected = [Layer_Id,New_Layer_Id,New_Layer_2_Id], 1370 1371 Expected = Layers. 1372 1373test(precise_rollup_rolls_up_precisely,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1374 open_directory_store(TestDir, Store), 1375 open_write(Store, Builder), 1376 nb_add_triple(Builder, "a", "a", value("a")), 1377 nb_add_triple(Builder, "a", "b", value("a")), 1378 nb_add_triple(Builder, "c", "c", node("a")), 1379 nb_commit(Builder, Layer), 1380 1381 open_write(Layer, Builder2), 1382 nb_remove_triple(Builder2, "a", "a", value("a")), 1383 nb_add_triple(Builder2, "c", "b", node("d")), 1384 nb_commit(Builder2, Layer2), 1385 1386 open_write(Layer2, Builder3), 1387 nb_add_triple(Builder3, "c", "c", node("c")), 1388 nb_remove_triple(Builder3, "c", "b", node("d")), 1389 nb_commit(Builder3, Layer3), 1390 1391 open_write(Layer3, Builder4), 1392 nb_add_triple(Builder4, "a", "a", value("a")), 1393 nb_add_triple(Builder4, "x", "y", node("z")), 1394 nb_commit(Builder4, Layer4), 1395 1396 rollup_upto(Layer3, Layer), 1397 1398 % lets reload the top layer 1399 layer_to_id(Layer4, Layer4_Id), 1400 store_id_layer(Store, Layer4_Id, Layer4_Reloaded), 1401 1402 % and rollup again 1403 rollup_upto(Layer4_Reloaded, Layer2), 1404 1405 % and reload again! 1406 store_id_layer(Store, Layer4_Id, Layer4_Reloaded_Again), 1407 1408 findall(t(S,P,O), triple(Layer4_Reloaded_Again, S, P, O), Triples), 1409 1410 Expected = [ 1411 t("a", "a", value("a")), 1412 t("a", "b", value("a")), 1413 t("c", "c", node("a")), 1414 t("c", "c", node("c")), 1415 t("x", "y", node("z")) 1416 ], 1417 1418 Triples = Expected. 1419 1420test(imprecise_rollup_rolls_up_imprecisely,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1421 open_directory_store(TestDir, Store), 1422 open_write(Store, Builder), 1423 nb_add_triple(Builder, "a", "a", value("a")), 1424 nb_add_triple(Builder, "a", "b", value("a")), 1425 nb_add_triple(Builder, "c", "c", node("a")), 1426 nb_commit(Builder, Layer), 1427 1428 open_write(Layer, Builder2), 1429 nb_remove_triple(Builder2, "a", "a", value("a")), 1430 nb_add_triple(Builder2, "c", "b", node("d")), 1431 nb_commit(Builder2, Layer2), 1432 1433 open_write(Layer2, Builder3), 1434 nb_add_triple(Builder3, "c", "c", node("c")), 1435 nb_remove_triple(Builder3, "c", "b", node("d")), 1436 nb_commit(Builder3, Layer3), 1437 1438 open_write(Layer3, Builder4), 1439 nb_add_triple(Builder4, "a", "a", value("a")), 1440 nb_add_triple(Builder4, "x", "y", node("z")), 1441 nb_commit(Builder4, Layer4), 1442 1443 rollup_upto(Layer3, Layer), 1444 1445 % lets reload the top layer 1446 layer_to_id(Layer4, Layer4_Id), 1447 store_id_layer(Store, Layer4_Id, Layer4_Reloaded), 1448 1449 % and rollup again 1450 imprecise_rollup_upto(Layer4_Reloaded, Layer2), 1451 1452 % and reload again! 1453 store_id_layer(Store, Layer4_Id, Layer4_Reloaded_Again), 1454 1455 findall(t(S,P,O), triple(Layer4_Reloaded_Again, S, P, O), Triples), 1456 1457 Expected = [ 1458 t("a", "a", value("a")), 1459 t("a", "b", value("a")), 1460 t("c", "c", node("a")), 1461 t("c", "c", node("c")), 1462 t("x", "y", node("z")) 1463 ], 1464 1465 Triples = Expected. 1466 1467test(sp_card,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1468 open_directory_store(TestDir, Store), 1469 open_write(Store, Builder), 1470 nb_add_triple(Builder, "A", "B", node("C")), 1471 nb_add_triple(Builder, "A", "B", node("D")), 1472 nb_commit(Builder, Layer), 1473 subject_id(Layer, "A", A_Id), 1474 predicate_id(Layer, "B", B_Id), 1475 sp_card(Layer, A_Id, B_Id, Count), 1476 Count = 2. 1477 1478:- end_tests(terminus_store).