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