carton_db 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -4
- data/lib/carton_db/datum.rb +2 -0
- data/lib/carton_db/list_map_db.rb +56 -0
- data/lib/carton_db/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbf7e47a17f6d3f6f19bb40d4a13524cc2704cd0
|
4
|
+
data.tar.gz: 26098104742787b3bfa8bf0b01b8274a7cdb8e13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f00b6ad528b7ec75286244bffce56ee467eeaf2e8c470a6db680e1002c242a7130b0225c77e5a4d7e853d3e1ffbfa59cdedc554e95cab6095a6c25778bbd3632
|
7
|
+
data.tar.gz: 1b7c46564dae0037b6c12dfea983e4d780e2720e70a670b65ee174e08264689434ff37d7fb2c55856088375b05be1eb1e16bc8c448b2b2480d5bc3d213ebff73
|
data/README.md
CHANGED
@@ -21,13 +21,14 @@ for a relational database server, and I didn't want to add one
|
|
21
21
|
just for this requirement. A redis db with sufficient capacity
|
22
22
|
would have been expensive, and solutions such as SQLite are
|
23
23
|
specifically not supported by Heroku so people don't mistakenly
|
24
|
-
expect the data to be preserved. Ruby's `DBM` and
|
25
|
-
to be too unpredicatable and flakey to be
|
24
|
+
expect the data to be preserved. Ruby's `PStore`, `DBM` and
|
25
|
+
`SDMB` each proved to be too unpredicatable and flakey to be
|
26
|
+
practical solutions.
|
26
27
|
|
27
28
|
Although this tool was initially developed to store transient
|
28
29
|
data for use within a single process invocation and then
|
29
|
-
discarded, it is also
|
30
|
-
|
30
|
+
discarded, it is also well suited for long term data storage on a
|
31
|
+
system that retains filesystem contents.
|
31
32
|
|
32
33
|
## Installation
|
33
34
|
|
data/lib/carton_db/datum.rb
CHANGED
@@ -5,6 +5,7 @@ module CartonDb
|
|
5
5
|
module Datum
|
6
6
|
|
7
7
|
def self.for_plain(plain_text, auto_placeholder: false)
|
8
|
+
return plain_text if plain_text.is_a?(Datum::Base)
|
8
9
|
if auto_placeholder && plain_text.nil?
|
9
10
|
Datum::Placeholder
|
10
11
|
else
|
@@ -13,6 +14,7 @@ module CartonDb
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.for_escaped(escaped_text, auto_placeholder: false)
|
17
|
+
return escaped_text if escaped_text.is_a?(Datum::Base)
|
16
18
|
if auto_placeholder && escaped_text.nil?
|
17
19
|
Datum::Placeholder
|
18
20
|
else
|
@@ -27,6 +27,14 @@ module CartonDb
|
|
27
27
|
# The directory for the database will be created if it does
|
28
28
|
# not already exist.
|
29
29
|
#
|
30
|
+
# The parent directory is assumed to already exist, and an
|
31
|
+
# exception will be raised if it does not.
|
32
|
+
#
|
33
|
+
# Other instance methods assume that the directory exists but
|
34
|
+
# make no other assumptions about the state of the persisted
|
35
|
+
# data, and an empty directory is a valid representation of
|
36
|
+
# an empty database.
|
37
|
+
#
|
30
38
|
# This is a very fast operation.
|
31
39
|
#
|
32
40
|
# @param name [String] The full path of the directory in the
|
@@ -89,6 +97,17 @@ module CartonDb
|
|
89
97
|
false
|
90
98
|
end
|
91
99
|
|
100
|
+
def element?(key, element)
|
101
|
+
key_d = CartonDb::Datum.for_plain(key)
|
102
|
+
element_d = CartonDb::Datum.for_plain(element)
|
103
|
+
segment = segment_containing(key_d)
|
104
|
+
|
105
|
+
segment.each_entry_element_line do |kd, ed, _line|
|
106
|
+
return true if kd == key_d && ed == element_d
|
107
|
+
end
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
92
111
|
# Returns true if the map has no entries.
|
93
112
|
#
|
94
113
|
# This is a fairly fast operation.
|
@@ -270,6 +289,43 @@ module CartonDb
|
|
270
289
|
end
|
271
290
|
end
|
272
291
|
|
292
|
+
# Appends an element to the content of an entry if no
|
293
|
+
# element with the same value already exists in the content.
|
294
|
+
#
|
295
|
+
# @param key [String] The key identifying the entry.
|
296
|
+
# @param element [String] The element to be appended to the
|
297
|
+
# content of the entry if applicable.
|
298
|
+
def touch_element(key, element)
|
299
|
+
key_d = CartonDb::Datum.for_plain(key)
|
300
|
+
element_d = CartonDb::Datum.for_plain(element)
|
301
|
+
return if element?(key_d, element_d)
|
302
|
+
append_element key_d, element_d
|
303
|
+
end
|
304
|
+
|
305
|
+
# Performs a bag-wise merge of the given elements with the
|
306
|
+
# content of an entry. Appends whatever elements are
|
307
|
+
# necessary so the content has an element corresponding to
|
308
|
+
# each of the given elements.
|
309
|
+
#
|
310
|
+
# @param key [String] The key identifying the entry.
|
311
|
+
# @param elements [Array<String>] An array or other
|
312
|
+
# enumerable collection of elements to appended as
|
313
|
+
# applicable.
|
314
|
+
def merge_elements(key, elements)
|
315
|
+
key_d = CartonDb::Datum.for_plain(key)
|
316
|
+
element_ds = elements.map { |el|
|
317
|
+
CartonDb::Datum.for_plain(el)
|
318
|
+
}
|
319
|
+
segment = segment_containing(key_d)
|
320
|
+
segment.each_entry_element_line do |kd, ed, _line|
|
321
|
+
next unless kd == key_d
|
322
|
+
eds_idx = element_ds.index(ed)
|
323
|
+
element_ds.delete_at(eds_idx) if eds_idx
|
324
|
+
end
|
325
|
+
|
326
|
+
concat_elements key_d, element_ds
|
327
|
+
end
|
328
|
+
|
273
329
|
private
|
274
330
|
|
275
331
|
attr_accessor :name
|
data/lib/carton_db/version.rb
CHANGED