Class: SlugDB
- Inherits:
-
Object
- Object
- SlugDB
- Defined in:
- lib/slugdb.rb,
lib/slugdb/version.rb
Overview
Zero dependecy NoSQL, file based database
Constant Summary collapse
- VERSION =
'0.1.0'
Instance Method Summary collapse
-
#add_index(name:, pk:, sk:) ⇒ Object
rubocop:disable Naming/MethodParameterName.
-
#delete_item(pk:, sk:, **_) ⇒ Object
rubocop:disable Naming/MethodParameterName,Metrics/AbcSize.
-
#get_item(pk:, sk:) ⇒ Object
rubocop:disable Naming/MethodParameterName.
-
#initialize(file, thread_safe: false, ultra_safe: false) ⇒ SlugDB
constructor
A new instance of SlugDB.
- #list_indexes ⇒ Object
- #list_partitions ⇒ Object
-
#put_item(pk:, sk:, **attributes) ⇒ Object
rubocop:disable Naming/MethodParameterName.
-
#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,.
- #reindex! ⇒ Object
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,Metrics/AbcSize
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/slugdb.rb', line 72 def delete_item(pk:, sk:, **_) item = get_item(pk: pk, sk: sk) return if item.nil? indexes = list_indexes @pstore.transaction do |db| db[:main][pk].delete(sk) db[:main].delete(pk) if db[:main][pk].empty? indexes.each do |name, schema| next unless item.key?(schema[:pk]) && item.key?(schema[:sk]) db[name][item[schema[:pk]]][item[schema[:sk]]][item[:pk]].delete(item[:sk]) delete_if_empty?(db[name][item[schema[:pk]]][item[schema[:sk]]], item[:pk]) delete_if_empty?(db[name][item[schema[:pk]]], item[schema[:sk]]) delete_if_empty?(db[name], item[schema[:pk]]) end end 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_indexes ⇒ Object
42 43 44 |
# File 'lib/slugdb.rb', line 42 def list_indexes @pstore.transaction { |db| db[:indexes] } end |
#list_partitions ⇒ Object
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 |
# File 'lib/slugdb.rb', line 58 def put_item(pk:, sk:, **attributes) # rubocop:disable Naming/MethodParameterName item = attributes.merge(pk: pk, sk: sk) indexes = list_indexes @pstore.transaction do |db| db[:main][pk] ||= {} db[:main][pk][sk] = item indexes.each { |name, schema| index_item(db, item, name, schema) } end 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,
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/slugdb.rb', line 98 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 |