sophia-ruby 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/sophia.c +188 -19
- data/lib/sophia/version.rb +1 -1
- data/test/test_sophia.rb +122 -8
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03126fdd239f628aa86ab992b6c6c4e539b76f09
|
4
|
+
data.tar.gz: 82ef09e5e5613ea32528e79a57e806049e641ecf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8fd0a625c9885df5906d3c1869d0cf9ee9bd90c94ad9c4e28946c609d370cd357415e4c8d44142ade1fbd239f77ad23ac282a69e4a35ba09c717bc5e92a4559
|
7
|
+
data.tar.gz: 9e3bac14487e3580639c6ecf51e1d2ef6ffe40167062f8853b41477fb2683b1e067512cb3f26c524516f8ee0f2b22073b6aaade6aebdec44a3f47015c2841273
|
data/ext/sophia.c
CHANGED
@@ -4,17 +4,18 @@
|
|
4
4
|
#define GetSophia(object, sophia) { \
|
5
5
|
Data_Get_Struct((object), Sophia, (sophia)); \
|
6
6
|
if ((sophia) == NULL) { \
|
7
|
-
rb_raise(
|
7
|
+
rb_raise(rb_eSophiaError, "closed object"); \
|
8
8
|
} \
|
9
9
|
if ((sophia)->env == NULL) { \
|
10
|
-
rb_raise(
|
10
|
+
rb_raise(rb_eSophiaError, "closed object"); \
|
11
11
|
} \
|
12
12
|
if ((sophia)->db == NULL) { \
|
13
|
-
rb_raise(
|
13
|
+
rb_raise(rb_eSophiaError, "closed object"); \
|
14
14
|
} \
|
15
15
|
}
|
16
16
|
|
17
17
|
static VALUE rb_cSophia;
|
18
|
+
static VALUE rb_eSophiaError;
|
18
19
|
|
19
20
|
typedef struct {
|
20
21
|
void* env;
|
@@ -67,20 +68,20 @@ sophia_initialize(int argc, VALUE *argv, VALUE self)
|
|
67
68
|
sophia->env = sp_env();
|
68
69
|
|
69
70
|
if (sophia->env == NULL) {
|
70
|
-
rb_raise(
|
71
|
+
rb_raise(rb_eSophiaError, "sp_env(3)");
|
71
72
|
}
|
72
73
|
|
73
74
|
if (sp_ctl(sophia->env, SPDIR, SPO_CREAT|SPO_RDWR, RSTRING_PTR(file))) {
|
74
|
-
rb_raise(
|
75
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
75
76
|
}
|
76
77
|
|
77
78
|
sophia->db = sp_open(sophia->env);
|
78
79
|
|
79
80
|
if (sophia->db == NULL) {
|
80
|
-
rb_raise(
|
81
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
81
82
|
}
|
82
83
|
|
83
|
-
return
|
84
|
+
return self;
|
84
85
|
}
|
85
86
|
|
86
87
|
/*
|
@@ -96,14 +97,14 @@ sophia_close(VALUE self)
|
|
96
97
|
|
97
98
|
if (sophia->db) {
|
98
99
|
if (sp_destroy(sophia->db)) {
|
99
|
-
rb_raise(
|
100
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
100
101
|
}
|
101
102
|
sophia->db = NULL;
|
102
103
|
}
|
103
104
|
|
104
105
|
if (sophia->env) {
|
105
106
|
if (sp_destroy(sophia->env)) {
|
106
|
-
rb_raise(
|
107
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
107
108
|
}
|
108
109
|
sophia->env = NULL;
|
109
110
|
}
|
@@ -111,6 +112,27 @@ sophia_close(VALUE self)
|
|
111
112
|
return Qnil;
|
112
113
|
}
|
113
114
|
|
115
|
+
/*
|
116
|
+
* call-seq:
|
117
|
+
* Sophia.open("/path/to/db") -> sophia
|
118
|
+
* Sophia.open("/path/to/db") { |sophia| block } -> block
|
119
|
+
*/
|
120
|
+
static VALUE
|
121
|
+
sophia_s_open(int argc, VALUE *argv, VALUE self)
|
122
|
+
{
|
123
|
+
VALUE sophia = sophia_alloc(self);
|
124
|
+
|
125
|
+
if (NIL_P(sophia_initialize(argc, argv, sophia))) {
|
126
|
+
return Qnil;
|
127
|
+
}
|
128
|
+
|
129
|
+
if (rb_block_given_p()) {
|
130
|
+
return rb_ensure(rb_yield, sophia, sophia_close, sophia);
|
131
|
+
}
|
132
|
+
|
133
|
+
return sophia;
|
134
|
+
}
|
135
|
+
|
114
136
|
/*
|
115
137
|
* call-seq:
|
116
138
|
* sophia.closed? -> true or false
|
@@ -150,7 +172,7 @@ sophia_set(VALUE self, VALUE key, VALUE value)
|
|
150
172
|
if (sp_set(sophia->db,
|
151
173
|
RSTRING_PTR(key), RSTRING_LEN(key),
|
152
174
|
RSTRING_PTR(value), RSTRING_LEN(value))) {
|
153
|
-
rb_raise(
|
175
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
154
176
|
}
|
155
177
|
|
156
178
|
return value;
|
@@ -181,10 +203,10 @@ sophia_get(VALUE self, VALUE key, VALUE ifnone)
|
|
181
203
|
return ifnone;
|
182
204
|
}
|
183
205
|
} else if (result == -1) {
|
184
|
-
rb_raise(
|
206
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
185
207
|
}
|
186
208
|
|
187
|
-
rb_raise(
|
209
|
+
rb_raise(rb_eSophiaError, "error");
|
188
210
|
return Qnil;
|
189
211
|
}
|
190
212
|
|
@@ -203,18 +225,165 @@ sophia_fetch(int argc, VALUE *argv, VALUE self)
|
|
203
225
|
return sophia_get(self, key, ifnone);
|
204
226
|
}
|
205
227
|
|
228
|
+
static VALUE
|
229
|
+
sophia_delete(VALUE self, VALUE key)
|
230
|
+
{
|
231
|
+
Sophia *sophia;
|
232
|
+
int result;
|
233
|
+
VALUE val;
|
234
|
+
|
235
|
+
GetSophia(self, sophia);
|
236
|
+
|
237
|
+
ExportStringValue(key);
|
238
|
+
|
239
|
+
val = sophia_aref(self, key);
|
240
|
+
|
241
|
+
result = sp_delete(sophia->db,
|
242
|
+
RSTRING_PTR(key), RSTRING_LEN(key));
|
243
|
+
if (result == 0) {
|
244
|
+
return val;
|
245
|
+
} else if (result == -1) {
|
246
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
247
|
+
}
|
248
|
+
|
249
|
+
rb_raise(rb_eSophiaError, "error");
|
250
|
+
return Qnil;
|
251
|
+
}
|
252
|
+
|
253
|
+
static VALUE
|
254
|
+
sophia_length(VALUE self)
|
255
|
+
{
|
256
|
+
Sophia *sophia;
|
257
|
+
int length = 0;
|
258
|
+
void *cursor;
|
259
|
+
|
260
|
+
GetSophia(self, sophia);
|
261
|
+
|
262
|
+
cursor = sp_cursor(sophia->db, SPGT, NULL, 0);
|
263
|
+
if (cursor == NULL) {
|
264
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
265
|
+
}
|
266
|
+
while (sp_fetch(cursor)) {
|
267
|
+
length += 1;
|
268
|
+
}
|
269
|
+
sp_destroy(cursor);
|
270
|
+
|
271
|
+
return INT2FIX(length);
|
272
|
+
}
|
273
|
+
|
274
|
+
static VALUE
|
275
|
+
sophia_empty_p(VALUE self)
|
276
|
+
{
|
277
|
+
Sophia *sophia;
|
278
|
+
int result;
|
279
|
+
void *cursor;
|
280
|
+
|
281
|
+
GetSophia(self, sophia);
|
282
|
+
|
283
|
+
cursor = sp_cursor(sophia->db, SPGT, NULL, 0);
|
284
|
+
if (cursor == NULL) {
|
285
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
286
|
+
}
|
287
|
+
result = sp_fetch(cursor);
|
288
|
+
sp_destroy(cursor);
|
289
|
+
|
290
|
+
return result == 0 ? Qtrue : Qfalse;
|
291
|
+
}
|
292
|
+
|
293
|
+
static VALUE
|
294
|
+
sophia_each_pair(VALUE self)
|
295
|
+
{
|
296
|
+
Sophia *sophia;
|
297
|
+
void *cursor;
|
298
|
+
|
299
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
300
|
+
|
301
|
+
GetSophia(self, sophia);
|
302
|
+
|
303
|
+
cursor = sp_cursor(sophia->db, SPGT, NULL, 0);
|
304
|
+
if (cursor == NULL) {
|
305
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
306
|
+
}
|
307
|
+
while (sp_fetch(cursor)) {
|
308
|
+
rb_yield(rb_assoc_new(rb_str_new(sp_key(cursor), sp_keysize(cursor)),
|
309
|
+
rb_str_new(sp_value(cursor), sp_valuesize(cursor))));
|
310
|
+
}
|
311
|
+
sp_destroy(cursor);
|
312
|
+
|
313
|
+
return self;
|
314
|
+
}
|
315
|
+
|
316
|
+
static VALUE
|
317
|
+
sophia_each_key(VALUE self)
|
318
|
+
{
|
319
|
+
Sophia *sophia;
|
320
|
+
void *cursor;
|
321
|
+
|
322
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
323
|
+
|
324
|
+
GetSophia(self, sophia);
|
325
|
+
|
326
|
+
cursor = sp_cursor(sophia->db, SPGT, NULL, 0);
|
327
|
+
if (cursor == NULL) {
|
328
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
329
|
+
}
|
330
|
+
while (sp_fetch(cursor)) {
|
331
|
+
rb_yield(rb_str_new(sp_key(cursor), sp_keysize(cursor)));
|
332
|
+
}
|
333
|
+
sp_destroy(cursor);
|
334
|
+
|
335
|
+
return self;
|
336
|
+
}
|
337
|
+
|
338
|
+
static VALUE
|
339
|
+
sophia_each_value(VALUE self)
|
340
|
+
{
|
341
|
+
Sophia *sophia;
|
342
|
+
void *cursor;
|
343
|
+
|
344
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
345
|
+
|
346
|
+
GetSophia(self, sophia);
|
347
|
+
|
348
|
+
cursor = sp_cursor(sophia->db, SPGT, NULL, 0);
|
349
|
+
if (cursor == NULL) {
|
350
|
+
rb_raise(rb_eSophiaError, sp_error(sophia->env));
|
351
|
+
}
|
352
|
+
while (sp_fetch(cursor)) {
|
353
|
+
rb_yield(rb_str_new(sp_value(cursor), sp_valuesize(cursor)));
|
354
|
+
}
|
355
|
+
sp_destroy(cursor);
|
356
|
+
|
357
|
+
return self;
|
358
|
+
}
|
359
|
+
|
206
360
|
void
|
207
361
|
Init_sophia()
|
208
362
|
{
|
209
363
|
rb_cSophia = rb_define_class("Sophia", rb_cObject);
|
364
|
+
rb_include_module(rb_cSophia, rb_mEnumerable); /* include Enumerable */
|
210
365
|
rb_define_alloc_func(rb_cSophia, sophia_alloc);
|
366
|
+
|
367
|
+
rb_eSophiaError = rb_define_class("SophiaError", rb_eStandardError);
|
368
|
+
|
369
|
+
rb_define_singleton_method(rb_cSophia, "open", sophia_s_open, -1);
|
370
|
+
|
211
371
|
rb_define_private_method(rb_cSophia, "initialize", sophia_initialize, -1);
|
212
|
-
rb_define_method(rb_cSophia, "close",
|
213
|
-
rb_define_method(rb_cSophia, "closed?",
|
214
|
-
rb_define_method(rb_cSophia, "set",
|
215
|
-
rb_define_method(rb_cSophia, "[]=",
|
216
|
-
rb_define_method(rb_cSophia, "get",
|
217
|
-
rb_define_method(rb_cSophia, "[]",
|
218
|
-
rb_define_method(rb_cSophia, "fetch",
|
372
|
+
rb_define_method(rb_cSophia, "close", sophia_close, 0);
|
373
|
+
rb_define_method(rb_cSophia, "closed?", sophia_closed_p, 0);
|
374
|
+
rb_define_method(rb_cSophia, "set", sophia_set, 2);
|
375
|
+
rb_define_method(rb_cSophia, "[]=", sophia_set, 2);
|
376
|
+
rb_define_method(rb_cSophia, "get", sophia_aref, 1);
|
377
|
+
rb_define_method(rb_cSophia, "[]", sophia_aref, 1);
|
378
|
+
rb_define_method(rb_cSophia, "fetch", sophia_fetch, -1);
|
379
|
+
rb_define_method(rb_cSophia, "delete", sophia_delete, 1);
|
380
|
+
rb_define_method(rb_cSophia, "length", sophia_length, 0);
|
381
|
+
rb_define_alias(rb_cSophia, "size", "length");
|
382
|
+
rb_define_method(rb_cSophia, "empty?", sophia_empty_p, 0);
|
383
|
+
rb_define_method(rb_cSophia, "each_pair", sophia_each_pair, 0);
|
384
|
+
rb_define_alias(rb_cSophia, "each", "each_pair");
|
385
|
+
rb_define_method(rb_cSophia, "each_key", sophia_each_key, 0);
|
386
|
+
rb_define_method(rb_cSophia, "each_value", sophia_each_value, 0);
|
387
|
+
|
219
388
|
rb_require("sophia/version");
|
220
389
|
}
|
data/lib/sophia/version.rb
CHANGED
data/test/test_sophia.rb
CHANGED
@@ -1,33 +1,147 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
|
-
Bundler.require
|
3
|
+
Bundler.require :default, :test
|
4
4
|
require 'minitest/spec'
|
5
5
|
require 'minitest/autorun'
|
6
6
|
require 'sophia'
|
7
7
|
require 'tmpdir'
|
8
|
+
require 'fileutils'
|
8
9
|
|
9
10
|
describe Sophia do
|
11
|
+
before { @tmpdir = Dir.mktmpdir }
|
12
|
+
after { FileUtils.remove_entry_secure @tmpdir }
|
13
|
+
|
14
|
+
it 'open' do
|
15
|
+
Sophia.open(@tmpdir).must_be_instance_of Sophia
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'open with block' do
|
19
|
+
retval = rand
|
20
|
+
Sophia.open(@tmpdir) { |sophia| retval }.must_equal retval
|
21
|
+
end
|
22
|
+
|
10
23
|
it 'get/set' do
|
11
|
-
|
12
|
-
sophia = Sophia.new path
|
24
|
+
sophia = Sophia.new @tmpdir
|
13
25
|
sophia['key'] = 'value'
|
26
|
+
|
14
27
|
sophia['key'].must_equal 'value'
|
15
28
|
end
|
16
29
|
|
17
30
|
it 'fetch' do
|
18
|
-
|
19
|
-
sophia =
|
31
|
+
sophia = Sophia.new @tmpdir
|
32
|
+
sophia['key'] = 'value'
|
33
|
+
|
34
|
+
sophia.fetch('key').must_equal 'value'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'fetch not exists key' do
|
38
|
+
sophia = Sophia.new @tmpdir
|
39
|
+
|
40
|
+
sophia.fetch('key').must_be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'fetch with default value' do
|
44
|
+
sophia = Sophia.new @tmpdir
|
20
45
|
|
21
46
|
sophia.fetch('key', '123').must_equal '123'
|
22
47
|
end
|
23
48
|
|
24
|
-
it 'fetch block' do
|
25
|
-
|
26
|
-
sophia = Sophia.new path
|
49
|
+
it 'fetch with block' do
|
50
|
+
sophia = Sophia.new @tmpdir
|
27
51
|
|
28
52
|
sophia.fetch('key') { |key|
|
29
53
|
key.must_equal 'key'
|
30
54
|
'456'
|
31
55
|
}.must_equal '456'
|
32
56
|
end
|
57
|
+
|
58
|
+
it 'delete' do
|
59
|
+
sophia = Sophia.new @tmpdir
|
60
|
+
sophia['key'] = 'val'
|
61
|
+
|
62
|
+
sophia.delete('key').must_equal 'val'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'delete not exists key' do
|
66
|
+
sophia = Sophia.new @tmpdir
|
67
|
+
|
68
|
+
sophia.delete('key').must_be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'length' do
|
72
|
+
sophia = Sophia.new @tmpdir
|
73
|
+
|
74
|
+
sophia.length.must_equal 0
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'length with key' do
|
78
|
+
sophia = Sophia.new @tmpdir
|
79
|
+
sophia['key'] = 'val'
|
80
|
+
|
81
|
+
sophia.length.must_equal 1
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'empty?' do
|
85
|
+
sophia = Sophia.new @tmpdir
|
86
|
+
|
87
|
+
sophia.must_be :empty?
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'empty? with key' do
|
91
|
+
sophia = Sophia.new @tmpdir
|
92
|
+
sophia['key'] = 'val'
|
93
|
+
|
94
|
+
sophia.wont_be :empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'access to closed sophia db' do
|
98
|
+
sophia = Sophia.new @tmpdir
|
99
|
+
sophia.close
|
100
|
+
|
101
|
+
lambda { sophia['key'] = 'val' }.must_raise SophiaError
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'each' do
|
105
|
+
sophia = Sophia.new @tmpdir
|
106
|
+
sophia['key1'] = 'val1'
|
107
|
+
sophia['key2'] = 'val2'
|
108
|
+
keys, vals = [], []
|
109
|
+
sophia.each { |k, v| keys << k; vals << v }
|
110
|
+
|
111
|
+
keys.must_equal %w[key1 key2]
|
112
|
+
vals.must_equal %w[val1 val2]
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'each_key' do
|
116
|
+
sophia = Sophia.new @tmpdir
|
117
|
+
sophia['key1'] = 'val1'
|
118
|
+
sophia['key2'] = 'val2'
|
119
|
+
keys = []
|
120
|
+
sophia.each_key { |k| keys << k }
|
121
|
+
|
122
|
+
keys.must_equal %w[key1 key2]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'each_value' do
|
126
|
+
sophia = Sophia.new @tmpdir
|
127
|
+
sophia['key1'] = 'val1'
|
128
|
+
sophia['key2'] = 'val2'
|
129
|
+
vals = []
|
130
|
+
sophia.each_value { |v| vals << v }
|
131
|
+
|
132
|
+
vals.must_equal %w[val1 val2]
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'find' do
|
136
|
+
sophia = Sophia.new @tmpdir
|
137
|
+
sophia['key1'] = 'val1'
|
138
|
+
sophia['key2'] = 'val2'
|
139
|
+
sophia['key3'] = 'val3'
|
140
|
+
sophia['key4'] = 'val4'
|
141
|
+
expect = %w[key2 val2]
|
142
|
+
|
143
|
+
sophia.find { |key, val|
|
144
|
+
[key, val] == expect
|
145
|
+
}.must_equal expect
|
146
|
+
end
|
33
147
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sophia-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- miyucy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
version: '0'
|
127
127
|
requirements: []
|
128
128
|
rubyforge_project:
|
129
|
-
rubygems_version: 2.1.
|
129
|
+
rubygems_version: 2.1.9
|
130
130
|
signing_key:
|
131
131
|
specification_version: 4
|
132
132
|
summary: Ruby bindings for the Sophia key/value store
|