hypostasis 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hypostasis.rb +6 -0
- data/lib/hypostasis/connection.rb +28 -0
- data/lib/hypostasis/data_model/document.rb +3 -0
- data/lib/hypostasis/data_model/key_value.rb +3 -0
- data/lib/hypostasis/data_models.rb +4 -0
- data/lib/hypostasis/errors.rb +8 -0
- data/lib/hypostasis/key_path.rb +29 -0
- data/lib/hypostasis/namespace.rb +6 -7
- data/lib/hypostasis/tuple.rb +50 -0
- data/lib/hypostasis/version.rb +1 -1
- data/test/connection_spec.rb +51 -6
- data/test/data_models/document/document_spec.rb +5 -0
- data/test/data_models/key_value/key_value_spec.rb +5 -0
- data/test/key_path_spec.rb +31 -0
- data/test/minitest_helper.rb +19 -0
- data/test/namespace_spec.rb +7 -2
- data/test/tuple_spec.rb +35 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dbac3fb199bc4d6edf4065159d9ec92e41b071b
|
4
|
+
data.tar.gz: 06a5045d627c2b6a0e3e9d95f14ca106c0b95ce7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e378bc61f2ffd706f4a3824292cdc55b14712beab90a7e4bfd5210ca1623047599e34643039edf9700dd4b96bf2e56dd61fcb0c3f59ec16318be10fa477000f
|
7
|
+
data.tar.gz: e6d76b2b7160982607a608a75ab966d59575d3bd53422d142a78145988752f1fbe06f645e2b5c97b01c6762557f22c3503f70bc7a73ba7ac9e344cbb215a854d
|
data/lib/hypostasis.rb
CHANGED
@@ -5,10 +5,16 @@ FDB.api_version 100
|
|
5
5
|
class Hypostasis::Connection
|
6
6
|
attr_reader :database
|
7
7
|
|
8
|
+
@@config_key = Hypostasis::KeyPath.new('hypostasis', 'config', 'namespaces')
|
9
|
+
|
8
10
|
def initialize
|
9
11
|
@database = FDB.open
|
10
12
|
end
|
11
13
|
|
14
|
+
def self.config_path
|
15
|
+
@@config_key
|
16
|
+
end
|
17
|
+
|
12
18
|
def get(key)
|
13
19
|
database[key.to_s]
|
14
20
|
end
|
@@ -20,4 +26,26 @@ class Hypostasis::Connection
|
|
20
26
|
def unset(key)
|
21
27
|
database.clear(key).nil?
|
22
28
|
end
|
29
|
+
|
30
|
+
def create_namespace(name, options = {data_model: :key_value})
|
31
|
+
path = @@config_key.extend_path(name.to_s).to_s
|
32
|
+
raise Hypostasis::Errors::NamespaceAlreadyCreated unless database[path].nil?
|
33
|
+
database[path] = Marshal.dump(options)
|
34
|
+
Hypostasis::Namespace.new(name, options[:data_model])
|
35
|
+
end
|
36
|
+
|
37
|
+
def open_namespace(name)
|
38
|
+
path = @@config_key.extend_path(name.to_s).to_s
|
39
|
+
raise Hypostasis::Errors::NonExistentNamespace if database[path].nil?
|
40
|
+
options = Marshal.load(database[path])
|
41
|
+
Hypostasis::Namespace.new(name, options[:data_model])
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy_namespace(name)
|
45
|
+
path = @@config_key.extend_path(name.to_s).to_s
|
46
|
+
raise Hypostasis::Errors::NonExistentNamespace if database[path].nil?
|
47
|
+
database.clear_range_start_with(path)
|
48
|
+
database.clear_range_start_with(name.to_s)
|
49
|
+
true
|
50
|
+
end
|
23
51
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Hypostasis::Errors
|
2
|
+
class NamespaceAlreadyCreated < StandardError; end
|
3
|
+
class NonExistentNamespace < StandardError; end
|
4
|
+
class InvalidKeyPath < StandardError; end
|
5
|
+
class KeyPathExhausted < StandardError; end
|
6
|
+
class InvalidTuple < StandardError; end
|
7
|
+
class TupleExhausted < StandardError; end
|
8
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Hypostasis::KeyPath
|
2
|
+
def initialize(*path)
|
3
|
+
@path = path.to_a.flatten
|
4
|
+
raise Hypostasis::Errors::InvalidKeyPath if @path.empty?
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@path.join('\\')
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_a
|
13
|
+
@path
|
14
|
+
end
|
15
|
+
|
16
|
+
def extend_path(*extension)
|
17
|
+
return self if extension.empty?
|
18
|
+
extended_path = @path + extension.to_a
|
19
|
+
Hypostasis::KeyPath.new(extended_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def move_up(count = 0)
|
23
|
+
return self if count <= 0
|
24
|
+
raise Hypostasis::Errors::KeyPathExhausted if count >= @path.size
|
25
|
+
new_path = @path
|
26
|
+
new_path.pop(count)
|
27
|
+
Hypostasis::KeyPath.new(new_path)
|
28
|
+
end
|
29
|
+
end
|
data/lib/hypostasis/namespace.rb
CHANGED
@@ -4,14 +4,13 @@ class Hypostasis::Namespace
|
|
4
4
|
def initialize(name, data_model)
|
5
5
|
@name = name.to_s
|
6
6
|
@data_model = data_model.to_sym
|
7
|
-
|
8
|
-
#self.setup
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
#end
|
9
|
+
def key_path
|
10
|
+
@key_path ||= Hypostasis::KeyPath.new(name)
|
11
|
+
end
|
16
12
|
|
13
|
+
def config_path
|
14
|
+
@config_path ||= Hypostasis::Connection.config_path.extend_path(name)
|
15
|
+
end
|
17
16
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Hypostasis::Tuple
|
2
|
+
def initialize(*tuple)
|
3
|
+
@tuple = tuple.to_a.flatten
|
4
|
+
raise Hypostasis::Errors::InvalidTuple if @tuple.empty?
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_a
|
9
|
+
@tuple
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@tuple_str ||= FDB::Tuple.pack(@tuple)
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepend(*prefix)
|
17
|
+
return self if prefix.empty?
|
18
|
+
prepended_tuple = prefix.to_a + @tuple
|
19
|
+
Hypostasis::Tuple.new(prepended_tuple)
|
20
|
+
end
|
21
|
+
|
22
|
+
def append(*extension)
|
23
|
+
return self if extension.empty?
|
24
|
+
appended_tuple = @tuple + extension.to_a
|
25
|
+
Hypostasis::Tuple.new(appended_tuple)
|
26
|
+
end
|
27
|
+
|
28
|
+
def trim(count = 0)
|
29
|
+
count = count.to_i
|
30
|
+
raise Hypostasis::Errors::TupleExhausted if count.abs > @tuple.size - 1
|
31
|
+
trimmed_tuple = @tuple
|
32
|
+
if count > 0
|
33
|
+
trimmed_tuple.pop(count.abs)
|
34
|
+
Hypostasis::Tuple.new(trimmed_tuple)
|
35
|
+
elsif count < 0
|
36
|
+
trimmed_tuple.shift(count.abs)
|
37
|
+
Hypostasis::Tuple.new(trimmed_tuple)
|
38
|
+
else
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_range
|
44
|
+
FDB::Tuple.range(@tuple)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.unpack(tuple_string)
|
48
|
+
Hypostasis::Tuple.new(FDB::Tuple.unpack(tuple_string))
|
49
|
+
end
|
50
|
+
end
|
data/lib/hypostasis/version.rb
CHANGED
data/test/connection_spec.rb
CHANGED
@@ -7,11 +7,56 @@ describe Hypostasis::Connection do
|
|
7
7
|
it { subject.must_respond_to :set }
|
8
8
|
it { subject.must_respond_to :unset }
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
describe '#get and #set' do
|
11
|
+
before :each do
|
12
|
+
subject.set('preset_key', 'preset_value')
|
13
|
+
end
|
14
|
+
|
15
|
+
after :each do
|
16
|
+
subject.unset('preset_key')
|
17
|
+
end
|
18
|
+
|
19
|
+
it { subject.get('invalid_key').nil?.must_equal true }
|
20
|
+
it { subject.get('preset_key').must_equal 'preset_value' }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#unset' do
|
24
|
+
it 'unsets a previously set key' do
|
25
|
+
subject.set('preset_key', 'preset_value')
|
26
|
+
subject.get('preset_key').must_equal 'preset_value'
|
27
|
+
subject.unset('preset_key').must_equal true
|
28
|
+
subject.get('preset_key').nil?.must_equal true
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns true for an unset key' do
|
32
|
+
subject.get('preset_key').nil?.must_equal true
|
33
|
+
subject.unset('preset_key').must_equal true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#create_namespace' do
|
38
|
+
before :each do
|
39
|
+
subject.create_namespace('already_created')
|
40
|
+
end
|
41
|
+
|
42
|
+
it { subject.create_namespace('newly_created').is_a?(Hypostasis::Namespace).must_equal true }
|
43
|
+
it { lambda { subject.create_namespace('already_created') }.must_raise Hypostasis::Errors::NamespaceAlreadyCreated }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#open_namespace' do
|
47
|
+
before :each do
|
48
|
+
subject.create_namespace('already_created')
|
49
|
+
end
|
50
|
+
|
51
|
+
it { subject.open_namespace('already_created').is_a?(Hypostasis::Namespace).must_equal true }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#destroy_namespace' do
|
55
|
+
before :each do
|
56
|
+
subject.create_namespace('already_created')
|
57
|
+
end
|
58
|
+
|
59
|
+
it { subject.destroy_namespace('already_created').must_equal true }
|
60
|
+
it { lambda { subject.destroy_namespace('not_created') }.must_raise Hypostasis::Errors::NonExistentNamespace }
|
16
61
|
end
|
17
62
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe Hypostasis::KeyPath do
|
4
|
+
let(:subject) { Hypostasis::KeyPath.new('hypostasis', 'demo', 'path') }
|
5
|
+
|
6
|
+
it { lambda { Hypostasis::KeyPath.new }.must_raise Hypostasis::Errors::InvalidKeyPath }
|
7
|
+
|
8
|
+
it { subject.to_s.must_equal 'hypostasis\demo\path' }
|
9
|
+
it { subject.to_a.must_equal %w{hypostasis demo path} }
|
10
|
+
|
11
|
+
describe '#extend_path' do
|
12
|
+
it { subject.extend_path.must_equal subject }
|
13
|
+
|
14
|
+
it { subject.extend_path('extension').to_s.must_equal 'hypostasis\demo\path\extension' }
|
15
|
+
it { subject.extend_path('extension').to_a.must_equal %w{hypostasis demo path extension} }
|
16
|
+
|
17
|
+
it { subject.extend_path('extension', 'path').to_s.must_equal 'hypostasis\demo\path\extension\path' }
|
18
|
+
it { subject.extend_path('extension', 'path').to_a.must_equal %w{hypostasis demo path extension path} }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#move_up' do
|
22
|
+
it { subject.move_up.must_equal subject }
|
23
|
+
it { subject.move_up(0).must_equal subject }
|
24
|
+
it { subject.move_up(-1).must_equal subject }
|
25
|
+
it { subject.move_up(-2).must_equal subject }
|
26
|
+
|
27
|
+
it { subject.move_up(1).to_a.must_equal %w{hypostasis demo} }
|
28
|
+
it { subject.move_up(2).to_a.must_equal %w{hypostasis} }
|
29
|
+
it { lambda { subject.move_up(3) }.must_raise Hypostasis::Errors::KeyPathExhausted }
|
30
|
+
end
|
31
|
+
end
|
data/test/minitest_helper.rb
CHANGED
@@ -12,3 +12,22 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
12
12
|
require 'hypostasis'
|
13
13
|
|
14
14
|
require 'minitest/autorun'
|
15
|
+
|
16
|
+
class Minitest::Spec
|
17
|
+
|
18
|
+
after do
|
19
|
+
database.get_range_start_with("hypostasis\\config\\namespaces") do |kv|
|
20
|
+
namespace = kv.key.gsub("hypostasis\\config\\namespaces\\", '')
|
21
|
+
database.clear_range_start_with(namespace)
|
22
|
+
end
|
23
|
+
|
24
|
+
database.clear_range_start_with('hypostasis')
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def database
|
30
|
+
@database ||= FDB.open
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/namespace_spec.rb
CHANGED
@@ -9,6 +9,11 @@ describe Hypostasis::Namespace do
|
|
9
9
|
it { subject.must_respond_to :data_model }
|
10
10
|
it { subject.data_model.must_equal :document }
|
11
11
|
|
12
|
-
it
|
13
|
-
it
|
12
|
+
it { subject.must_respond_to :key_path }
|
13
|
+
it { subject.key_path.is_a?(Hypostasis::KeyPath).must_equal true }
|
14
|
+
it { subject.key_path.to_a.must_equal %w{demonstration} }
|
15
|
+
|
16
|
+
it { subject.must_respond_to :config_path }
|
17
|
+
it { subject.config_path.is_a?(Hypostasis::KeyPath).must_equal true }
|
18
|
+
it { subject.config_path.to_a.must_equal %w{hypostasis config namespaces demonstration} }
|
14
19
|
end
|
data/test/tuple_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe Hypostasis::Tuple do
|
4
|
+
let(:subject) { Hypostasis::Tuple.new('tuple', 'example', 123) }
|
5
|
+
|
6
|
+
it { subject.must_respond_to :to_a }
|
7
|
+
it { subject.must_respond_to :to_s }
|
8
|
+
it { subject.must_respond_to :prepend }
|
9
|
+
it { subject.must_respond_to :append }
|
10
|
+
it { subject.must_respond_to :trim }
|
11
|
+
|
12
|
+
it { subject.to_a.must_equal ['tuple', 'example', 123] }
|
13
|
+
it { subject.to_s.must_equal FDB::Tuple.pack(['tuple', 'example', 123]) }
|
14
|
+
|
15
|
+
it { subject.prepend('another').is_a?(Hypostasis::Tuple).must_equal true }
|
16
|
+
it { subject.prepend('another').to_a.must_equal ['another', 'tuple', 'example', 123] }
|
17
|
+
|
18
|
+
it { subject.append('another').is_a?(Hypostasis::Tuple).must_equal true }
|
19
|
+
it { subject.append('another').to_a.must_equal ['tuple', 'example', 123, 'another'] }
|
20
|
+
|
21
|
+
it { subject.trim.must_equal subject }
|
22
|
+
it { subject.trim(1).to_a.must_equal ['tuple', 'example'] }
|
23
|
+
it { subject.trim(-1).to_a.must_equal ['example', 123] }
|
24
|
+
it { lambda { subject.trim(3) }.must_raise Hypostasis::Errors::TupleExhausted }
|
25
|
+
it { lambda { subject.trim(4) }.must_raise Hypostasis::Errors::TupleExhausted }
|
26
|
+
it { lambda { subject.trim(-3) }.must_raise Hypostasis::Errors::TupleExhausted }
|
27
|
+
it { lambda { subject.trim(-4) }.must_raise Hypostasis::Errors::TupleExhausted }
|
28
|
+
|
29
|
+
it { lambda { Hypostasis::Tuple.new }.must_raise Hypostasis::Errors::InvalidTuple }
|
30
|
+
|
31
|
+
it { Hypostasis::Tuple.unpack(subject.to_s).is_a?(Hypostasis::Tuple).must_equal true }
|
32
|
+
it { Hypostasis::Tuple.unpack(subject.to_s).to_a.must_equal subject.to_a }
|
33
|
+
|
34
|
+
it { subject.to_range.must_equal FDB::Tuple.range(['tuple', 'example', 123]) }
|
35
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hypostasis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fdb
|
@@ -83,11 +83,21 @@ files:
|
|
83
83
|
- hypostasis.gemspec
|
84
84
|
- lib/hypostasis.rb
|
85
85
|
- lib/hypostasis/connection.rb
|
86
|
+
- lib/hypostasis/data_model/document.rb
|
87
|
+
- lib/hypostasis/data_model/key_value.rb
|
88
|
+
- lib/hypostasis/data_models.rb
|
89
|
+
- lib/hypostasis/errors.rb
|
90
|
+
- lib/hypostasis/key_path.rb
|
86
91
|
- lib/hypostasis/namespace.rb
|
92
|
+
- lib/hypostasis/tuple.rb
|
87
93
|
- lib/hypostasis/version.rb
|
88
94
|
- test/connection_spec.rb
|
95
|
+
- test/data_models/document/document_spec.rb
|
96
|
+
- test/data_models/key_value/key_value_spec.rb
|
97
|
+
- test/key_path_spec.rb
|
89
98
|
- test/minitest_helper.rb
|
90
99
|
- test/namespace_spec.rb
|
100
|
+
- test/tuple_spec.rb
|
91
101
|
homepage: ''
|
92
102
|
licenses:
|
93
103
|
- MIT
|
@@ -114,5 +124,9 @@ specification_version: 4
|
|
114
124
|
summary: A layer for FoundationDB providing multiple data models for Ruby.
|
115
125
|
test_files:
|
116
126
|
- test/connection_spec.rb
|
127
|
+
- test/data_models/document/document_spec.rb
|
128
|
+
- test/data_models/key_value/key_value_spec.rb
|
129
|
+
- test/key_path_spec.rb
|
117
130
|
- test/minitest_helper.rb
|
118
131
|
- test/namespace_spec.rb
|
132
|
+
- test/tuple_spec.rb
|