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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 490693935730e28be31a446231221acbfab3ad1b
4
- data.tar.gz: 43b5d9cface98769d770318c6f864708bf27d417
3
+ metadata.gz: 9dbac3fb199bc4d6edf4065159d9ec92e41b071b
4
+ data.tar.gz: 06a5045d627c2b6a0e3e9d95f14ca106c0b95ce7
5
5
  SHA512:
6
- metadata.gz: 6e126c676cd74dff9dae11c287b7fde193c159df9e1e64a55407e7248f548359ce57a693cf8c167e79c40bfacc7c4add9f03b58cdb799d46ef753ea44553a0ec
7
- data.tar.gz: 268813a84afba95aaec59ed7bc6a017ebe3762fe32d50e2613d3009c5730cdf38d91e8853d4a01e1623107c1559a96da86ffbcd1fbca5a4242d6968b9e5277f3
6
+ metadata.gz: 4e378bc61f2ffd706f4a3824292cdc55b14712beab90a7e4bfd5210ca1623047599e34643039edf9700dd4b96bf2e56dd61fcb0c3f59ec16318be10fa477000f
7
+ data.tar.gz: e6d76b2b7160982607a608a75ab966d59575d3bd53422d142a78145988752f1fbe06f645e2b5c97b01c6762557f22c3503f70bc7a73ba7ac9e344cbb215a854d
data/lib/hypostasis.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  require 'hypostasis/version'
2
2
 
3
+ require 'hypostasis/errors'
4
+
5
+ require 'hypostasis/tuple'
6
+ require 'hypostasis/key_path'
3
7
  require 'hypostasis/connection'
4
8
  require 'hypostasis/namespace'
9
+
10
+ require 'hypostasis/data_models'
@@ -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,3 @@
1
+ module Hypostasis::DataModel::Document
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ module Hypostasis::DataModel::KeyValue
2
+
3
+ end
@@ -0,0 +1,4 @@
1
+ module Hypostasis::DataModel; end
2
+
3
+ require 'hypostasis/data_model/document'
4
+ require 'hypostasis/data_model/key_value'
@@ -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
@@ -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
- private
12
-
13
- #def setup
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
@@ -1,3 +1,3 @@
1
1
  module Hypostasis
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -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
- it 'supports simple getting and setting' do
11
- subject.get('test_key').nil?.must_equal true
12
- subject.set('test_key', 'test_value').must_equal true
13
- subject.get('test_key').must_equal 'test_value'
14
- subject.unset('test_key').must_equal true
15
- subject.get('test_key').nil?.must_equal true
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,5 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Hypostasis::DataModel::Document do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Hypostasis::DataModel::KeyValue do
4
+
5
+ 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
@@ -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
@@ -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 "sets 'hypostasis/config/namespaces/demonstration' key"
13
- it "sets 'hypostasis/config/namespaces/demonstration/data_model' key"
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
@@ -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.2
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 00:00:00.000000000 Z
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