hypostasis 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|