Class: RDF::LMDB::Repository

Inherits:
Repository
  • Object
show all
Defined in:
lib/rdf/lmdb.rb

Overview

RDF::LMDB::Repository implements a lightweight, transactional, locally-attached data store using Symax LMDB.

Instance Method Summary collapse

Constructor Details

#initialize(dir = nil, uri: nil, title: nil, **options, &block) ⇒ Repository

Returns a new instance of Repository.

Raises:

  • (ArgumentError)


621
622
623
624
625
626
627
628
629
630
631
# File 'lib/rdf/lmdb.rb', line 621

def initialize dir = nil, uri: nil, title: nil, **options, &block
  dir ||= options.delete(:dir) if options[:dir]

  # wtf no idea why this won't inherit
  @tx_class ||= options.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

  init_lmdb dir, **options
  super uri: uri, title: title, **options, &block
end

Instance Method Details

#clearObject



647
648
649
650
651
652
653
# File 'lib/rdf/lmdb.rb', line 647

def clear
  @lmdb.transaction do
    @dbs.each_value { |db| db.clear }
  end
  # we do not clear the main database; that nukes the sub-databases
  # @lmdb.database.clear
end

#closeObject



659
660
661
# File 'lib/rdf/lmdb.rb', line 659

def close
  @lmdb.close
end

#countObject



780
781
782
# File 'lib/rdf/lmdb.rb', line 780

def count
  @dbs[:stmt2g].size
end

#delete_insert(deletes, inserts) ⇒ Object

def apply_changeset changeset

@lmdb.transaction do |t|
  delete_insert(changeset.deletes, changeset.inserts)
end

end



794
795
796
797
798
# File 'lib/rdf/lmdb.rb', line 794

def delete_insert deletes, inserts
  ret = super(deletes, inserts)
  commit_transaction # this is to satiate the test suite
  ret
end

#delete_statement(statement) ⇒ Object



671
672
673
674
675
# File 'lib/rdf/lmdb.rb', line 671

def delete_statement statement
  complete! statement
  @lmdb.transaction { |t| rm_one statement; t.commit }
  nil
end

#delete_statements(statements) ⇒ Object



688
689
690
691
692
693
694
695
696
697
698
699
700
701
# File 'lib/rdf/lmdb.rb', line 688

def delete_statements statements
  @lmdb.transaction do |t|
    hashes = []
    statements.each do |statement|
      complete! statement
      hashes += rm_one statement, scan: false
    end

    clean_terms hashes
    t.commit
  end

  nil
end

#each(&block) ⇒ Object

data retrieval



705
706
707
708
709
# File 'lib/rdf/lmdb.rb', line 705

def each &block
  return enum_for :each unless block_given?

  each_maybe_with_graph(&block)
end

#each_graph(&block) ⇒ Object



738
739
740
741
742
743
744
745
# File 'lib/rdf/lmdb.rb', line 738

def each_graph &block
  return enum_for :each_graph unless block_given?
  @dbs[:g2stmt].cursor do |c|
    while (k, _ = c.next true)
      yield RDF::Graph.new(graph_name: resolve_term(k), data: self)
    end
  end
end

#each_object(&block) ⇒ Object



729
730
731
732
733
734
735
736
# File 'lib/rdf/lmdb.rb', line 729

def each_object &block
  return enum_for :each_object unless block_given?
  @dbs[:o2stmt].cursor do |c|
    while (k, _ = c.next true)
      yield resolve_term k
    end
  end
end

#each_predicate(&block) ⇒ Object



720
721
722
723
724
725
726
727
# File 'lib/rdf/lmdb.rb', line 720

def each_predicate &block
  return enum_for :each_predicate unless block_given?
  @dbs[:p2stmt].cursor do |c|
    while (k, _ = c.next true)
      yield resolve_term k
    end
  end
end

#each_subject(&block) ⇒ Object



711
712
713
714
715
716
717
718
# File 'lib/rdf/lmdb.rb', line 711

def each_subject &block
  return enum_for :each_subject unless block_given?
  @dbs[:s2stmt].cursor do |c|
    while (k, _ = c.next true)
      yield resolve_term k
    end
  end
end

#each_term(&block) ⇒ Object



747
748
749
750
751
752
753
754
755
756
# File 'lib/rdf/lmdb.rb', line 747

def each_term &block
  return enum_for :each_term unless block_given?
  @dbs[:int2term].cursor do |c|
    while (_, v = c.next)
      # yield RDF::NTriples::Reader.unserialize v
      v.force_encoding 'utf-8'
      yield RDF::NTriples::Reader.parse_object(v, intern: true)
    end
  end
end

#empty?Boolean

Returns:

  • (Boolean)


784
785
786
# File 'lib/rdf/lmdb.rb', line 784

def empty?
  count == 0
end

#envObject



800
801
802
# File 'lib/rdf/lmdb.rb', line 800

def env
  @lmdb
end

#has_graph?(graph_name) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


823
824
825
826
827
828
829
# File 'lib/rdf/lmdb.rb', line 823

def has_graph? graph_name
  raise ArgumentError, 'graph_name must be an RDF::Term' unless
    graph_name.is_a? RDF::Term
  int  = int_for(graph_name) or return
  pack = [int].pack ?J
  @dbs[:g2stmt].has? pack
end

#has_object?(object) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


847
848
849
850
851
852
853
# File 'lib/rdf/lmdb.rb', line 847

def has_object? object
  raise ArgumentError, 'object must be an RDF::Term' unless
    object.is_a? RDF::Term
  int  = int_for(object) or return
  pack = [int].pack ?J
  @dbs[:o2stmt].has? pack
end

#has_predicate?(predicate) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


839
840
841
842
843
844
845
# File 'lib/rdf/lmdb.rb', line 839

def has_predicate? predicate
  raise ArgumentError, 'predicate must be an RDF::Term' unless
    predicate.is_a? RDF::Term
  int  = int_for(predicate) or return
  pack = [int].pack ?J
  @dbs[:p2stmt].has? pack
end

#has_quad?(quad) ⇒ Boolean

Returns:

  • (Boolean)


865
866
867
# File 'lib/rdf/lmdb.rb', line 865

def has_quad? quad
  has_statement? check_triple_quad quad, quad: true
end

#has_statement?(statement) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


817
818
819
820
821
# File 'lib/rdf/lmdb.rb', line 817

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

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


831
832
833
834
835
836
837
# File 'lib/rdf/lmdb.rb', line 831

def has_subject? subject
  raise ArgumentError, 'subject must be an RDF::Term' unless
    subject.is_a? RDF::Term
  int  = int_for(subject) or return
  pack = [int].pack ?J
  @dbs[:s2stmt].has? pack
end

#has_term?(term) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


855
856
857
858
859
# File 'lib/rdf/lmdb.rb', line 855

def has_term? term
  raise ArgumentError, 'term must be an RDF::Term' unless
    term.is_a? RDF::Term
  @dbs[:hash2term].has? hash_term(term)
end

#has_triple?(triple) ⇒ Boolean

Returns:

  • (Boolean)


861
862
863
# File 'lib/rdf/lmdb.rb', line 861

def has_triple? triple
  has_statement? check_triple_quad triple
end

#insert_statement(statement) ⇒ Object

data manipulation



665
666
667
668
669
# File 'lib/rdf/lmdb.rb', line 665

def insert_statement statement
  complete! statement
  @lmdb.transaction { |t| add_one statement; t.commit }
  nil
end

#insert_statements(statements) ⇒ Object



677
678
679
680
681
682
683
684
685
686
# File 'lib/rdf/lmdb.rb', line 677

def insert_statements statements
  @lmdb.transaction do
    statements.each do |statement|
      complete! statement
      add_one statement
    end
  end

  nil
end

#isolation_levelObject



639
640
641
# File 'lib/rdf/lmdb.rb', line 639

def isolation_level
  :serializable
end

#open(dir, **options) ⇒ Object



655
656
657
# File 'lib/rdf/lmdb.rb', line 655

def open dir, **options
  init_lmdb dir, **options
end

#pathObject



643
644
645
# File 'lib/rdf/lmdb.rb', line 643

def path
  Pathname(@lmdb.path)
end

#project_graph(graph_name, &block) ⇒ Object



758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
# File 'lib/rdf/lmdb.rb', line 758

def project_graph graph_name, &block
  return enum_for :project_graph, graph_name unless block_given?
  body = -> do
    gint  = graph_name ? int_for(graph_name) : 0
    return unless gint
    gpack = [gint].pack ?J
    cache = {}
    @dbs[:statement].each do |spack, spo|
      next unless @dbs[:stmt2g].has? spack, gpack
      spo = resolve_terms spo, cache: cache, write: true

      block.call RDF::Statement(*spo, graph_name: graph_name)
    end
  end

  @lmdb.transaction do
    body.call
  end

  #@lmdb.active_txn ? body.call : @lmdb.transaction(true, &body)
end

#supports?(feature) ⇒ Boolean

housekeeping

Returns:

  • (Boolean)


635
636
637
# File 'lib/rdf/lmdb.rb', line 635

def supports? feature
  !!SUPPORTS[feature.to_s.to_sym]
end

#transaction(mutable: false, &block) ⇒ Object



804
805
806
807
808
809
810
811
812
813
814
815
# File 'lib/rdf/lmdb.rb', line 804

def transaction mutable: false, &block
  return begin_transaction mutable: mutable unless block_given?

  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