Class: RDF::LMDB::Repository
- Inherits:
-
Repository
- Object
- Repository
- RDF::LMDB::Repository
- Defined in:
- lib/rdf/lmdb.rb
Overview
RDF::LMDB::Repository implements a lightweight, transactional, locally-attached data store using Symas LMDB.
Instance Attribute Summary collapse
-
#dir ⇒ Object
(also: #path)
readonly
Returns the value of attribute dir.
Instance Method Summary collapse
- #clear ⇒ Object
- #close ⇒ Object
- #count ⇒ Object
-
#delete_insert(deletes, inserts) ⇒ Object
def apply_changeset changeset @lmdb.transaction do |t| delete_insert(changeset.deletes, changeset.inserts) end end.
- #delete_statement(statement) ⇒ Object
- #delete_statements(statements) ⇒ Object
-
#each(&block) ⇒ Object
data retrieval.
- #each_graph(&block) ⇒ Object
- #each_object(&block) ⇒ Object
- #each_predicate(&block) ⇒ Object
- #each_subject(&block) ⇒ Object
- #each_term(&block) ⇒ Object
- #empty? ⇒ Boolean
- #env ⇒ Object
- #has_graph?(graph_name) ⇒ Boolean
- #has_object?(object) ⇒ Boolean
- #has_predicate?(predicate) ⇒ Boolean
- #has_quad?(quad) ⇒ Boolean
- #has_statement?(statement) ⇒ Boolean
- #has_subject?(subject) ⇒ Boolean
- #has_term?(term) ⇒ Boolean
- #has_triple?(triple) ⇒ Boolean
-
#initialize(dir = nil, uri: nil, title: nil, **options, &block) ⇒ Repository
constructor
A new instance of Repository.
-
#insert_statement(statement) ⇒ Object
data manipulation.
- #insert_statements(statements) ⇒ Object
- #isolation_level ⇒ Object
-
#mtime ⇒ Time
Return a Time object representing when the store was last written.
- #open(dir, **options) ⇒ Object
- #project_graph(graph_name, &block) ⇒ Object
-
#supports?(feature) ⇒ Boolean
housekeeping.
- #transaction(mutable: false, &block) ⇒ Object
Constructor Details
#initialize(dir = nil, uri: nil, title: nil, **options, &block) ⇒ Repository
Returns a new instance of Repository.
678 679 680 681 682 683 684 685 686 687 688 689 690 |
# File 'lib/rdf/lmdb.rb', line 678 def initialize dir = nil, uri: nil, title: nil, **, &block dir ||= .delete(:dir) if [:dir] # wtf no idea why this won't inherit @tx_class ||= .delete(:transaction_class) { DEFAULT_TX_CLASS } raise ArgumentError, "Invalid transaction class #{@tx_class}" unless @tx_class.is_a? Class and @tx_class <= DEFAULT_TX_CLASS @icache = {} init_lmdb dir, ** super uri: uri, title: title, **, &block end |
Instance Attribute Details
#dir ⇒ Object (readonly) Also known as: path
Returns the value of attribute dir.
702 703 704 |
# File 'lib/rdf/lmdb.rb', line 702 def dir @dir end |
Instance Method Details
#clear ⇒ Object
706 707 708 709 710 711 |
# File 'lib/rdf/lmdb.rb', line 706 def clear env.transaction? { env.databases.each { |db| env[db].clear } } # we do not clear the main database; that nukes the sub-databases # @lmdb.database.clear end |
#close ⇒ Object
717 718 719 |
# File 'lib/rdf/lmdb.rb', line 717 def close env.close end |
#count ⇒ Object
890 891 892 |
# File 'lib/rdf/lmdb.rb', line 890 def count env[:stmt2g].size end |
#delete_insert(deletes, inserts) ⇒ Object
def apply_changeset changeset
@lmdb.transaction do |t|
delete_insert(changeset.deletes, changeset.inserts)
end
end
904 905 906 907 908 909 |
# File 'lib/rdf/lmdb.rb', line 904 def delete_insert deletes, inserts ret = nil ret = env.transaction? { super(deletes, inserts) } commit_transaction # this is to satiate the test suite ret end |
#delete_statement(statement) ⇒ Object
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 |
# File 'lib/rdf/lmdb.rb', line 745 def delete_statement statement # note that this does not get called by `delete_statements`, # because we want the transaction on the outside. complete! statement # warn "WTF LOL #{statement.inspect}" env.transaction? do |t| if statement.variable? query(statement).each { |stmt| rm_one stmt } else rm_one statement end log_mtime end nil end |
#delete_statements(statements) ⇒ Object
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
# File 'lib/rdf/lmdb.rb', line 774 def delete_statements statements env.transaction? do hashes = [] # we don't know what's in here but it may contain statements # with variables, in which case we have to handle them enums = [statements] # also note that RDF::Util::Coercions#coerce_statements # which is called in advance of this is supposed to take # care of this situation but doesn't for some reason. until enums.empty? statements = enums.shift statements.each do |statement| if statement.variable? enums << query(statement) else hashes += rm_one statement, scan: false end end end clean_terms hashes.uniq log_mtime end nil end |
#each(&block) ⇒ Object
data retrieval
805 806 807 808 809 |
# File 'lib/rdf/lmdb.rb', line 805 def each &block return enum_for :each unless block each_maybe_with_graph(&block) end |
#each_graph(&block) ⇒ Object
845 846 847 848 849 850 851 852 853 854 855 |
# File 'lib/rdf/lmdb.rb', line 845 def each_graph &block return enum_for :each_graph unless block env.transaction? true do env[:g2stmt].cursor do |c| while (k, _ = c.next true) block.call RDF::Graph.new(graph_name: resolve_term(k), data: self) end end end end |
#each_object(&block) ⇒ Object
833 834 835 836 837 838 839 840 841 842 843 |
# File 'lib/rdf/lmdb.rb', line 833 def each_object &block return enum_for :each_object unless block env.transaction? true do env[:o2stmt].cursor do |c| while (k, _ = c.next true) block.call(resolve_term k) end end end end |
#each_predicate(&block) ⇒ Object
822 823 824 825 826 827 828 829 830 831 |
# File 'lib/rdf/lmdb.rb', line 822 def each_predicate &block return enum_for :each_predicate unless block env.transaction? true do env[:p2stmt].cursor do |c| while (k, _ = c.next true) block.call(resolve_term k) end end end end |
#each_subject(&block) ⇒ Object
811 812 813 814 815 816 817 818 819 820 |
# File 'lib/rdf/lmdb.rb', line 811 def each_subject &block return enum_for :each_subject unless block env.transaction? true do env[:s2stmt].cursor do |c| while (k, _ = c.next true) block.call(resolve_term k) end end end end |
#each_term(&block) ⇒ Object
857 858 859 860 861 862 863 864 865 866 867 868 869 |
# File 'lib/rdf/lmdb.rb', line 857 def each_term &block return enum_for :each_term unless block env.transaction? true do env[:int2term].cursor do |c| while (_, v = c.next) # yield RDF::NTriples::Reader.unserialize v v.force_encoding 'utf-8' block.call RDF::NTriples::Reader.parse_object(v, intern: true) end end end end |
#empty? ⇒ Boolean
894 895 896 |
# File 'lib/rdf/lmdb.rb', line 894 def empty? count == 0 end |
#env ⇒ Object
911 912 913 |
# File 'lib/rdf/lmdb.rb', line 911 def env (@lmdb ||= {})[Process.pid] ||= ::LMDB.new dir, @lmdb_opts end |
#has_graph?(graph_name) ⇒ Boolean
934 935 936 937 938 939 940 941 942 943 944 |
# File 'lib/rdf/lmdb.rb', line 934 def has_graph? graph_name raise ArgumentError, 'graph_name must be an RDF::Term' unless graph_name.is_a? RDF::Term env.transaction? true do if int = int_for(graph_name) pack = [int].pack ?J env[:g2stmt].has? pack end end end |
#has_object?(object) ⇒ Boolean
973 974 975 976 977 978 979 980 981 982 983 |
# File 'lib/rdf/lmdb.rb', line 973 def has_object? object raise ArgumentError, 'object must be an RDF::Term' unless object.is_a? RDF::Term env.transaction? true do if int = int_for(object) pack = [int].pack ?J env[:o2stmt].has? pack end end end |
#has_predicate?(predicate) ⇒ Boolean
961 962 963 964 965 966 967 968 969 970 971 |
# File 'lib/rdf/lmdb.rb', line 961 def has_predicate? predicate raise ArgumentError, 'predicate must be an RDF::Term' unless predicate.is_a? RDF::Term env.transaction? true do if int = int_for(predicate) pack = [int].pack ?J env[:p2stmt].has? pack end end end |
#has_quad?(quad) ⇒ Boolean
998 999 1000 |
# File 'lib/rdf/lmdb.rb', line 998 def has_quad? quad has_statement? check_triple_quad quad, quad: true end |
#has_statement?(statement) ⇒ Boolean
928 929 930 931 932 |
# File 'lib/rdf/lmdb.rb', line 928 def has_statement? statement raise ArgumentError, 'Argument must be an RDF::Statement' unless statement.is_a? RDF::Statement !query_pattern(statement.to_h).to_a.empty? end |
#has_subject?(subject) ⇒ Boolean
946 947 948 949 950 951 952 953 954 955 956 957 958 959 |
# File 'lib/rdf/lmdb.rb', line 946 def has_subject? subject raise ArgumentError, 'subject must be an RDF::Term' unless subject.is_a? RDF::Term env.transaction? true do if int = int_for(subject) pack = [int].pack ?J # XXX fix this upstream !!env[:s2stmt].has?(pack) else false end end end |
#has_term?(term) ⇒ Boolean
985 986 987 988 989 990 991 992 |
# File 'lib/rdf/lmdb.rb', line 985 def has_term? term raise ArgumentError, 'term must be an RDF::Term' unless term.is_a? RDF::Term env.transaction? true do env[:hash2term].has? hash_term(term) end end |
#has_triple?(triple) ⇒ Boolean
994 995 996 |
# File 'lib/rdf/lmdb.rb', line 994 def has_triple? triple has_statement? check_triple_quad triple end |
#insert_statement(statement) ⇒ Object
data manipulation
736 737 738 739 740 741 742 743 |
# File 'lib/rdf/lmdb.rb', line 736 def insert_statement statement complete! statement env.transaction? do |t| add_one statement log_mtime end nil end |
#insert_statements(statements) ⇒ Object
762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/rdf/lmdb.rb', line 762 def insert_statements statements env.transaction? do statements.each do |statement| complete! statement add_one statement end log_mtime end nil end |
#isolation_level ⇒ Object
698 699 700 |
# File 'lib/rdf/lmdb.rb', line 698 def isolation_level :serializable end |
#mtime ⇒ Time
Return a Time object representing when the store was last written.
725 726 727 728 729 730 731 732 |
# File 'lib/rdf/lmdb.rb', line 725 def mtime if packed = env[:control]['mtime'] nsecs = Rational(packed.unpack1(?q), 10 ** 9) Time.at nsecs, in: ?Z else log_mtime end end |
#open(dir, **options) ⇒ Object
713 714 715 |
# File 'lib/rdf/lmdb.rb', line 713 def open dir, ** init_lmdb dir, ** end |
#project_graph(graph_name, &block) ⇒ Object
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 |
# File 'lib/rdf/lmdb.rb', line 871 def project_graph graph_name, &block return enum_for :project_graph, graph_name unless block op = -> _ = nil do gint = graph_name ? int_for(graph_name) : 0 return unless gint gpack = [gint].pack ?J cache = {} env[:statement].each do |spack, spo| next unless env[:stmt2g].has? spack, gpack spo = resolve_terms spo, cache: cache, write: true block.call RDF::Statement(*spo, graph_name: graph_name) end end env.transaction? true, &op end |
#supports?(feature) ⇒ Boolean
housekeeping
694 695 696 |
# File 'lib/rdf/lmdb.rb', line 694 def supports? feature !!SUPPORTS[feature.to_s.to_sym] end |
#transaction(mutable: false, &block) ⇒ Object
915 916 917 918 919 920 921 922 923 924 925 926 |
# File 'lib/rdf/lmdb.rb', line 915 def transaction mutable: false, &block return begin_transaction mutable: mutable unless block begin begin_transaction mutable: mutable, &block rescue => error rollback_transaction # to sate the test suite raise error end #commit_transaction # to sate the test suite self end |