ccp 0.2.9 → 0.3.0
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.
- data/ccp.gemspec +1 -0
- data/lib/ccp.rb +1 -0
- data/lib/ccp/kvs/core.rb +6 -0
- data/lib/ccp/kvs/hash.rb +6 -4
- data/lib/ccp/kvs/tch.rb +2 -0
- data/lib/ccp/kvs/tokyo/base.rb +5 -5
- data/lib/ccp/kvs/tokyo/cabinet.rb +38 -5
- data/lib/ccp/storage.rb +62 -0
- data/lib/ccp/version.rb +1 -1
- data/spec/kvs/core_spec.rb +1 -0
- data/spec/kvs/kvs_spec.rb +56 -9
- data/spec/kvs/tokyo/cabinet_spec.rb +15 -2
- data/spec/storage/loadable_spec.rb +72 -0
- metadata +9 -8
- data/spec/kvs/tch_spec.rb +0 -19
data/ccp.gemspec
CHANGED
data/lib/ccp.rb
CHANGED
data/lib/ccp/kvs/core.rb
CHANGED
@@ -4,6 +4,8 @@ module Ccp
|
|
4
4
|
def get(k) ; raise NotImplementedError, "subclass resposibility"; end
|
5
5
|
def set(k,v) ; raise NotImplementedError, "subclass resposibility"; end
|
6
6
|
def del(k) ; raise NotImplementedError, "subclass resposibility"; end
|
7
|
+
def keys ; raise NotImplementedError, "subclass resposibility"; end
|
8
|
+
def read! ; keys.inject({}){|h,k| h[k] = get(k); h } ; end
|
7
9
|
|
8
10
|
def open(*) ; end
|
9
11
|
def close ; end
|
@@ -16,6 +18,10 @@ module Ccp
|
|
16
18
|
def put(k,v) ; set(k,v) ; end
|
17
19
|
def out(k) ; del(k) ; end
|
18
20
|
|
21
|
+
def codec!(c); @codec = Ccp::Serializers[c] ; self ; end
|
22
|
+
def encode(v); @codec ? @codec.encode(v) : v ; end
|
23
|
+
def decode(v); (v && @codec) ? @codec.decode(v) : v ; end
|
24
|
+
|
19
25
|
def ext; self.class.name.split(/::/).last.to_s.downcase; end
|
20
26
|
def self.included(klass)
|
21
27
|
klass.class_eval do
|
data/lib/ccp/kvs/hash.rb
CHANGED
@@ -3,14 +3,16 @@ module Ccp
|
|
3
3
|
class Hash
|
4
4
|
include Core
|
5
5
|
|
6
|
+
delegate :keys, :to=>"@db"
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
@db = {}
|
8
10
|
end
|
9
11
|
|
10
|
-
def get(k) ; @db[k.to_s]
|
11
|
-
def set(k,v) ; @db[k.to_s] = v.to_s
|
12
|
-
def del(k) ; @db.delete(k.to_s)
|
13
|
-
def count ; @db.size
|
12
|
+
def get(k) ; decode(@db[k.to_s]) ; end
|
13
|
+
def set(k,v) ; @db[k.to_s] = encode(v).to_s; end
|
14
|
+
def del(k) ; decode(@db.delete(k.to_s)) ; end
|
15
|
+
def count ; @db.size ; end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/lib/ccp/kvs/tch.rb
CHANGED
data/lib/ccp/kvs/tokyo/base.rb
CHANGED
@@ -19,10 +19,6 @@ module Ccp
|
|
19
19
|
######################################################################
|
20
20
|
### kvs
|
21
21
|
|
22
|
-
def get(k) ; @db[k] ; end
|
23
|
-
def set(k,v) ; @db[k] = v ; end
|
24
|
-
def del(k) ; @db.delete(k) ; end
|
25
|
-
|
26
22
|
def path
|
27
23
|
file = @source.to_s.sub(/#.*$/, '') # parse "foo.tch#mode=r"
|
28
24
|
Pathname(file)
|
@@ -30,7 +26,11 @@ module Ccp
|
|
30
26
|
|
31
27
|
private
|
32
28
|
def tokyo_error!(label = nil)
|
33
|
-
raise Ccp::Kvs::Tokyo::Error, "%s%s" % [label, error_message]
|
29
|
+
raise Ccp::Kvs::Tokyo::Error, "%s%s (%s)" % [label, error_message, @source]
|
30
|
+
end
|
31
|
+
|
32
|
+
def tokyo_error?
|
33
|
+
@db.ecode != HDB::ESUCCESS
|
34
34
|
end
|
35
35
|
|
36
36
|
def error_message
|
@@ -16,7 +16,7 @@ module Ccp
|
|
16
16
|
tryR("get")
|
17
17
|
v = @db[k.to_s]
|
18
18
|
if v
|
19
|
-
return v
|
19
|
+
return decode(v)
|
20
20
|
else
|
21
21
|
if @db.ecode == HDB::ENOREC
|
22
22
|
return nil
|
@@ -28,15 +28,17 @@ module Ccp
|
|
28
28
|
|
29
29
|
def set(k,v)
|
30
30
|
tryW("set")
|
31
|
-
|
31
|
+
val = encode(v)
|
32
|
+
@db[k.to_s] = val or
|
33
|
+
tokyo_error!("set(%s): " % k)
|
32
34
|
end
|
33
35
|
|
34
36
|
def del(k)
|
35
37
|
tryW("del")
|
36
|
-
v =
|
38
|
+
v = @db[k.to_s]
|
37
39
|
if v
|
38
|
-
if @db.delete(k.to_s)
|
39
|
-
return v
|
40
|
+
if @db.delete(k.to_s)
|
41
|
+
return decode(v)
|
40
42
|
else
|
41
43
|
tokyo_error!("del(%s): " % k)
|
42
44
|
end
|
@@ -50,6 +52,37 @@ module Ccp
|
|
50
52
|
return @db.rnum
|
51
53
|
end
|
52
54
|
|
55
|
+
######################################################################
|
56
|
+
### iterator
|
57
|
+
|
58
|
+
def each(&block)
|
59
|
+
each_keys do |key|
|
60
|
+
block.call(get(key))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def each_pair(&block)
|
65
|
+
each_keys do |key|
|
66
|
+
block.call(key, get(key))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def each_keys(&block)
|
71
|
+
tryR("each_keys")
|
72
|
+
@db.iterinit
|
73
|
+
while key = @db.iternext
|
74
|
+
block.call(key)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def keys
|
79
|
+
array = []
|
80
|
+
each_keys do |key|
|
81
|
+
array << key
|
82
|
+
end
|
83
|
+
return array
|
84
|
+
end
|
85
|
+
|
53
86
|
end
|
54
87
|
end
|
55
88
|
end
|
data/lib/ccp/storage.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Ccp
|
2
|
+
class Storage
|
3
|
+
NotFound = Class.new(RuntimeError)
|
4
|
+
|
5
|
+
def self.load(path)
|
6
|
+
array = path.split(".")
|
7
|
+
kvs = Ccp::Kvs[array.pop]
|
8
|
+
codec = Ccp::Serializers[array.pop]
|
9
|
+
return new(path, kvs, codec)
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :source, :kvs, :codec, :path
|
13
|
+
delegate :get, :set, :del, :keys, :read!, :to=>"@kvs"
|
14
|
+
|
15
|
+
def initialize(source, kvs, codec)
|
16
|
+
@source = source
|
17
|
+
@codec = codec
|
18
|
+
@path = Pathname(source)
|
19
|
+
@kvs = kvs.new(source).codec!(codec)
|
20
|
+
@tables = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
######################################################################
|
24
|
+
### meta kvs
|
25
|
+
|
26
|
+
def table_names
|
27
|
+
tables # force to update @tables
|
28
|
+
@tables.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def tables
|
32
|
+
files = Dir.chdir(@path) { Dir["**/*.#{@kvs.ext}"] }
|
33
|
+
files.map{|file|
|
34
|
+
name = file.sub(/(\.#{@codec.ext})?(\.#{@kvs.ext})?$/, '')
|
35
|
+
table(name, file)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def table(name, file = nil)
|
40
|
+
@tables[name.to_s] ||= (
|
41
|
+
file ||= "%s.%s.%s" % [name, @codec.ext, @kvs.ext]
|
42
|
+
Storage.new((@path + file).to_s, @kvs.class, @codec)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
######################################################################
|
47
|
+
### kvs
|
48
|
+
|
49
|
+
def read!
|
50
|
+
if @path.directory?
|
51
|
+
tables
|
52
|
+
hash = {}
|
53
|
+
@tables.each_pair do |k, kvs|
|
54
|
+
hash[k] = kvs.read!
|
55
|
+
end
|
56
|
+
return hash
|
57
|
+
else
|
58
|
+
return @kvs.read!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/ccp/version.rb
CHANGED
data/spec/kvs/core_spec.rb
CHANGED
data/spec/kvs/kvs_spec.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
describe kvs do
|
4
|
+
kvs_args = {}
|
5
|
+
kvs_args["tch"] = "#{tmp_path}/kvs/foo.tch"
|
6
|
+
|
7
|
+
Ccp::Kvs.each do |klass|
|
8
|
+
describe klass do
|
10
9
|
before { FileUtils.rm_rf(tmp_path) if tmp_path.directory? }
|
11
10
|
|
12
|
-
|
11
|
+
let(:kvs) { kvs_args[klass.ext] ? klass.new(*kvs_args[klass.ext]) : klass.new }
|
13
12
|
|
14
13
|
describe "#get, #set, #out" do
|
15
14
|
let(:key) { raise "Sub context responsibility" }
|
@@ -34,11 +33,59 @@ kvss.each do |kvs|
|
|
34
33
|
it { should be }
|
35
34
|
end
|
36
35
|
|
37
|
-
context ":foo => 2" do
|
36
|
+
context ":foo => '2'" do
|
38
37
|
let(:key) { :foo }
|
39
|
-
let(:val) { 2
|
38
|
+
let(:val) { "2" }
|
40
39
|
it { should be }
|
41
40
|
end
|
42
41
|
end
|
42
|
+
|
43
|
+
describe "#get, #set, #ou (with msgpack)t" do
|
44
|
+
let(:key) { raise "Sub context responsibility" }
|
45
|
+
let(:val) { raise "Sub context responsibility" }
|
46
|
+
|
47
|
+
before { kvs.codec! :msgpack }
|
48
|
+
|
49
|
+
subject {
|
50
|
+
k = kvs
|
51
|
+
k.touch
|
52
|
+
k.count.should == 0
|
53
|
+
k.get(key).should == nil
|
54
|
+
k.set(key, val)
|
55
|
+
k.get(key).should == val
|
56
|
+
k.count.should == 1
|
57
|
+
k.out(key).should == val
|
58
|
+
k.get(key).should == nil
|
59
|
+
k
|
60
|
+
}
|
61
|
+
|
62
|
+
context "nil" do
|
63
|
+
let(:key) { :foo }
|
64
|
+
let(:val) { nil }
|
65
|
+
it { should be }
|
66
|
+
end
|
67
|
+
|
68
|
+
context ":foo => [true, nil]" do
|
69
|
+
let(:key) { :foo }
|
70
|
+
let(:val) { [true, nil] }
|
71
|
+
it { should be }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#read!" do
|
76
|
+
specify do
|
77
|
+
kvs.touch
|
78
|
+
kvs.codec! :json
|
79
|
+
kvs.set(:a, 1)
|
80
|
+
kvs.set(:b, ["x", 0])
|
81
|
+
kvs.read!.should == {"a"=>1, "b"=>["x", 0]}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#codec!" do
|
86
|
+
specify "return self" do
|
87
|
+
kvs.codec!(:msgpack).should == kvs
|
88
|
+
end
|
89
|
+
end
|
43
90
|
end
|
44
91
|
end
|
@@ -140,11 +140,11 @@ describe Ccp::Kvs::Tokyo::Cabinet do
|
|
140
140
|
|
141
141
|
context "(for write)" do
|
142
142
|
before { kvs.W! }
|
143
|
-
specify { kvs.set("foo", 2).
|
143
|
+
specify { lambda { kvs.set("foo", 2) }.should_not raise_error }
|
144
144
|
end
|
145
145
|
|
146
146
|
context "(for write block)" do
|
147
|
-
specify { kvs.W{ kvs.set("foo", 2) }.
|
147
|
+
specify { lambda { kvs.W{ kvs.set("foo", 2) }.should_not raise_error } }
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -205,4 +205,17 @@ describe Ccp::Kvs::Tokyo::Cabinet do
|
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
208
|
+
######################################################################
|
209
|
+
### keys
|
210
|
+
|
211
|
+
describe "#keys" do
|
212
|
+
specify do
|
213
|
+
put(:foo, 1)
|
214
|
+
put(:bar, 2)
|
215
|
+
put(:baz, 3)
|
216
|
+
|
217
|
+
kvs.R!
|
218
|
+
kvs.keys.sort.should == %w( bar baz foo )
|
219
|
+
end
|
220
|
+
end
|
208
221
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Ccp::Storage do
|
5
|
+
specify ".load" do
|
6
|
+
Ccp::Storage.should respond_to(:load)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ".load" do
|
10
|
+
context "('tmp/foo.json.tch')" do
|
11
|
+
subject { Ccp::Storage.load('tmp/foo.json.tch') }
|
12
|
+
its(:source) { should == 'tmp/foo.json.tch' }
|
13
|
+
its(:kvs) { should be_kind_of(Ccp::Kvs::Tch) }
|
14
|
+
its(:codec) { should == Ccp::Serializers::Json }
|
15
|
+
|
16
|
+
describe "table(:foo)" do
|
17
|
+
subject { Ccp::Storage.load('tmp/foo.json.tch').table(:bar) }
|
18
|
+
its(:source) { should == 'tmp/foo.json.tch/bar.json.tch' }
|
19
|
+
its(:kvs) { should be_kind_of(Ccp::Kvs::Tch) }
|
20
|
+
its(:codec) { should == Ccp::Serializers::Json }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "('tmp/foo.msgpack.tch')" do
|
25
|
+
subject { Ccp::Storage.load('tmp/foo.msgpack.tch') }
|
26
|
+
its(:source) { should == 'tmp/foo.msgpack.tch' }
|
27
|
+
its(:kvs) { should be_kind_of(Ccp::Kvs::Tch) }
|
28
|
+
its(:codec) { should == Ccp::Serializers::Msgpack }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#read!" do
|
33
|
+
before { FileUtils.rm_rf(tmp_path) if tmp_path.directory? }
|
34
|
+
|
35
|
+
context "(file)" do
|
36
|
+
let(:tch) { tmp_path + "foo.json.tch" }
|
37
|
+
subject { Ccp::Storage.new(tch, Ccp::Kvs::Tch, Ccp::Serializers::Json) }
|
38
|
+
before {
|
39
|
+
tch.parent.mkpath
|
40
|
+
system("tchmgr create #{tch}")
|
41
|
+
system("tchmgr put #{tch} a '[1,2]'")
|
42
|
+
system("tchmgr put #{tch} b 0.1")
|
43
|
+
}
|
44
|
+
specify do
|
45
|
+
subject.read!.should == {"a" => [1, 2], "b" => 0.1}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "(directory)" do
|
50
|
+
let(:tch) { tmp_path + "foo.json.tch" }
|
51
|
+
subject { Ccp::Storage.new(tch, Ccp::Kvs::Tch, Ccp::Serializers::Json) }
|
52
|
+
before {
|
53
|
+
tch.mkpath
|
54
|
+
system("tchmgr create #{tch}/a.json.tch")
|
55
|
+
system("tchmgr put #{tch}/a.json.tch x '[1,2]'")
|
56
|
+
system("tchmgr put #{tch}/a.json.tch y []")
|
57
|
+
system("tchmgr create #{tch}/b.json.tch")
|
58
|
+
system("tchmgr put #{tch}/b.json.tch y 0.1")
|
59
|
+
}
|
60
|
+
specify do
|
61
|
+
subject.read!.should == {
|
62
|
+
"a" => {"x" => [1, 2], "y" => []},
|
63
|
+
"b" => {"y" => 0.1},
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# it { should respond_to(:tables) }
|
71
|
+
# it { should respond_to(:table) }
|
72
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ccp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- maiha
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-08-
|
18
|
+
date: 2013-08-23 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: activesupport
|
@@ -220,6 +220,7 @@ files:
|
|
220
220
|
- lib/ccp/serializers/json.rb
|
221
221
|
- lib/ccp/serializers/msgpack.rb
|
222
222
|
- lib/ccp/serializers/yaml.rb
|
223
|
+
- lib/ccp/storage.rb
|
223
224
|
- lib/ccp/utils.rb
|
224
225
|
- lib/ccp/utils/colorize.rb
|
225
226
|
- lib/ccp/utils/fixture_options.rb
|
@@ -243,7 +244,6 @@ files:
|
|
243
244
|
- spec/kvs/core_spec.rb
|
244
245
|
- spec/kvs/kvs_spec.rb
|
245
246
|
- spec/kvs/lookup_spec.rb
|
246
|
-
- spec/kvs/tch_spec.rb
|
247
247
|
- spec/kvs/tokyo/cabinet_spec.rb
|
248
248
|
- spec/kvs/tokyo/info_spec.rb
|
249
249
|
- spec/models.rb
|
@@ -264,9 +264,10 @@ files:
|
|
264
264
|
- spec/serializers/lookup_spec.rb
|
265
265
|
- spec/serializers/serializer_spec.rb
|
266
266
|
- spec/spec_helper.rb
|
267
|
+
- spec/storage/loadable_spec.rb
|
267
268
|
homepage: http://github.com/maiha/ccp
|
268
|
-
licenses:
|
269
|
-
|
269
|
+
licenses:
|
270
|
+
- MIT
|
270
271
|
post_install_message:
|
271
272
|
rdoc_options: []
|
272
273
|
|
data/spec/kvs/tch_spec.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
__END__
|
5
|
-
|
6
|
-
describe Ccp::Kvs::Tch do
|
7
|
-
let(:kvs) { s = Ccp::Kvs::Tch.new; s.open(source); s }
|
8
|
-
let(:tmp) { tmp_path + "kvs/tch" }
|
9
|
-
before { FileUtils.rm_rf(tmp) if tmp.directory? }
|
10
|
-
|
11
|
-
describe "#open" do
|
12
|
-
subject { inform }
|
13
|
-
|
14
|
-
context "foo.tch" do
|
15
|
-
let(:source) { tmp + "foo.tch" }
|
16
|
-
its(:path) { should == "" }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|