Class: SlugDB

Inherits:
Object
  • Object
show all
Defined in:
lib/slugdb.rb,
lib/slugdb/version.rb

Overview

Zero dependecy NoSQL, file based database

Constant Summary collapse

VERSION =
'0.1.1'

Instance Method Summary collapse

Constructor Details

#initialize(file, thread_safe: false, ultra_safe: false) ⇒ SlugDB

Returns a new instance of SlugDB.



9
10
11
12
13
14
15
# File 'lib/slugdb.rb', line 9

def initialize(file, thread_safe: false, ultra_safe: false)
  @pstore = PStore.new(file, thread_safe).tap { |s| s.ultra_safe = ultra_safe }
  @pstore.transaction do |db|
    db[:main] ||= {}
    db[:indexes] ||= {}
  end
end

Instance Method Details

#add_index(name:, pk:, sk:) ⇒ Object

rubocop:disable Naming/MethodParameterName



32
33
34
35
36
37
38
39
40
# File 'lib/slugdb.rb', line 32

def add_index(name:, pk:, sk:) # rubocop:disable Naming/MethodParameterName
  @pstore.transaction do |db|
    db[:indexes] ||= {}
    db[:indexes][name] = { pk: pk, sk: sk }
  end
  reindex!

  { name => { pk: pk, sk: sk } }
end

#delete_item(pk:, sk:, **_) ⇒ Object

rubocop:disable Naming/MethodParameterName



75
76
77
78
79
80
81
82
83
# File 'lib/slugdb.rb', line 75

def delete_item(pk:, sk:, **_)
  item = get_item(pk: pk, sk: sk)
  return if item.nil?

  indexes = list_indexes
  @pstore.transaction { |db| perform_delete(db, indexes, pk, sk, item) }

  item
end

#get_item(pk:, sk:, **_) ⇒ Object

rubocop:disable Naming/MethodParameterName



50
51
52
53
54
55
56
# File 'lib/slugdb.rb', line 50

def get_item(pk:, sk:, **_) # rubocop:disable Naming/MethodParameterName
  @pstore.transaction do |db|
    next if db[:main][pk].nil? || db[:main][pk][sk].nil?

    db[:main][pk][sk]
  end
end

#list_indexesObject



42
43
44
# File 'lib/slugdb.rb', line 42

def list_indexes
  @pstore.transaction { |db| db[:indexes] }
end

#list_partitionsObject



46
47
48
# File 'lib/slugdb.rb', line 46

def list_partitions
  @pstore.transaction { |db| db[:main].keys }
end

#put_item(pk:, sk:, **attributes) ⇒ Object

rubocop:disable Naming/MethodParameterName



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/slugdb.rb', line 58

def put_item(pk:, sk:, **attributes) # rubocop:disable Naming/MethodParameterName
  old_item = get_item(pk: pk, sk: sk)
  new_item = attributes.merge(pk: pk, sk: sk)
  indexes = list_indexes

  @pstore.transaction do |db|
    perform_delete(db, indexes, pk, sk, old_item)

    db[:main][pk] ||= {}
    db[:main][pk][sk] = new_item
    indexes.each { |name, schema| index_item(db, new_item, name, schema) }
  end

  new_item
end

#query(pk:, index: :main, select: ->(sk) { true }, filter: ->(item) { true }) ⇒ Object

rubocop:disable Lint/UnusedBlockArgument,Naming/MethodParameterName rubocop:disable Metrics/PerceivedComplexity,Metrics/MethodLength rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/slugdb.rb', line 89

def query(pk:, index: :main, select: ->(sk) { true }, filter: ->(item) { true })
  if index == :main
    @pstore.transaction do |db|
      db[index]
        .fetch(pk, {})
        .map { |_, records| records }
        .select { |item| select[item[:sk]] }
        .filter { |item| filter[item] }
    end
  else
    name, schema = list_indexes.find { |name,| name == index }
    @pstore.transaction do |db|
      db[name]
        .fetch(pk, {})
        .map do |_, isk_records|
          isk_records.map do |_, pk_records|
            pk_records.map { |_, sk_records| sk_records }
          end
        end # rubocop:disable Style/MultilineBlockChain
        .flatten(2)
        .select { |item| select[item[schema[:sk]]] }
        .filter { |item| filter[item] }
    end
  end
end

#reindex!Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/slugdb.rb', line 17

def reindex!
  indexes = list_indexes
  @pstore.transaction { |db| db[:main] }.each do |pk, records|
    records.each do |sk, record|
      @pstore.transaction do |db|
        indexes.each do |name, schema|
          index_item(db, record.merge(pk: pk, sk: sk), name, schema)
        end
      end
    end
  end

  nil
end