sophia-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +22 -0
- data/ext/extconf.rb +13 -0
- data/ext/sophia.c +220 -0
- data/lib/sophia-ruby.rb +1 -0
- data/lib/sophia/version.rb +3 -0
- data/sophia-ruby.gemspec +47 -0
- data/test/test_sophia.rb +33 -0
- data/vendor/sophia/.gitignore +18 -0
- data/vendor/sophia/COPYRIGHT +29 -0
- data/vendor/sophia/README +5 -0
- data/vendor/sophia/db/a.h +58 -0
- data/vendor/sophia/db/cat.c +195 -0
- data/vendor/sophia/db/cat.h +32 -0
- data/vendor/sophia/db/core.h +129 -0
- data/vendor/sophia/db/crc.c +343 -0
- data/vendor/sophia/db/crc.h +14 -0
- data/vendor/sophia/db/cursor.c +551 -0
- data/vendor/sophia/db/cursor.h +47 -0
- data/vendor/sophia/db/e.c +49 -0
- data/vendor/sophia/db/e.h +49 -0
- data/vendor/sophia/db/file.c +355 -0
- data/vendor/sophia/db/file.h +106 -0
- data/vendor/sophia/db/gc.c +71 -0
- data/vendor/sophia/db/gc.h +14 -0
- data/vendor/sophia/db/i.c +368 -0
- data/vendor/sophia/db/i.h +155 -0
- data/vendor/sophia/db/list.h +91 -0
- data/vendor/sophia/db/lock.h +77 -0
- data/vendor/sophia/db/macro.h +20 -0
- data/vendor/sophia/db/makefile +44 -0
- data/vendor/sophia/db/merge.c +662 -0
- data/vendor/sophia/db/merge.h +14 -0
- data/vendor/sophia/db/meta.h +87 -0
- data/vendor/sophia/db/recover.c +433 -0
- data/vendor/sophia/db/recover.h +14 -0
- data/vendor/sophia/db/ref.h +111 -0
- data/vendor/sophia/db/rep.c +128 -0
- data/vendor/sophia/db/rep.h +120 -0
- data/vendor/sophia/db/sophia.h +84 -0
- data/vendor/sophia/db/sp.c +626 -0
- data/vendor/sophia/db/sp.h +50 -0
- data/vendor/sophia/db/task.h +70 -0
- data/vendor/sophia/db/track.h +99 -0
- data/vendor/sophia/db/util.c +105 -0
- data/vendor/sophia/db/util.h +25 -0
- data/vendor/sophia/makefile +7 -0
- data/vendor/sophia/sophia.gyp +30 -0
- data/vendor/sophia/test/common.c +870 -0
- data/vendor/sophia/test/crash.c +492 -0
- data/vendor/sophia/test/i.c +403 -0
- data/vendor/sophia/test/limit.c +65 -0
- data/vendor/sophia/test/makefile +30 -0
- data/vendor/sophia/test/merge.c +890 -0
- data/vendor/sophia/test/recover.c +1550 -0
- data/vendor/sophia/test/test.h +66 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 533b4d801eea26b4985fa2dd294d317ad439947f
|
4
|
+
data.tar.gz: a8d25941d1559a6b623070eb68c329bca7f03ecf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2e61b3eae94389f15920484f179857d3d588ba61642a6a5994cc23a8ed0d2a04550b1fd870ee5615e547dd3502e6b1969b8d044b978e409f9f67ab68bca2d357
|
7
|
+
data.tar.gz: d213cd87d5c61e594da3d9343ac31d9cc179dff9e6ebbb2a3dd5f90627f17543f1c53f058b3d57c5d6f3e4121306c0b820a86dd15ee73ad1d028a1256c5bbbc9
|
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 miyucy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Sophia::Ruby
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'sophia-ruby'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install sophia-ruby
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
DLEXT = RbConfig::CONFIG['DLEXT']
|
6
|
+
SOFILE = "sophia.#{DLEXT}"
|
7
|
+
|
8
|
+
file "lib/sophia.#{DLEXT}" => Dir['ext/*{.rb,.c}'] do
|
9
|
+
Dir.chdir('ext') do
|
10
|
+
ruby 'extconf.rb'
|
11
|
+
sh 'make'
|
12
|
+
end
|
13
|
+
cp "ext/sophia.#{DLEXT}", 'lib'
|
14
|
+
end
|
15
|
+
|
16
|
+
Rake::TestTask.new do |t|
|
17
|
+
t.warning = true
|
18
|
+
t.verbose = true
|
19
|
+
end
|
20
|
+
task :test => "lib/sophia.#{DLEXT}"
|
21
|
+
|
22
|
+
task :default => :test
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
dir_config 'sophia'
|
4
|
+
|
5
|
+
unless have_library('sophia')
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
f = File.dirname(File.expand_path __FILE__)
|
9
|
+
g = File.expand_path '../../vendor/sophia/db/*.{c,h}', __FILE__
|
10
|
+
Dir[g].each { |e| FileUtils.copy e, f }
|
11
|
+
end
|
12
|
+
|
13
|
+
create_makefile 'sophia'
|
data/ext/sophia.c
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "sophia.h"
|
3
|
+
|
4
|
+
#define GetSophia(object, sophia) { \
|
5
|
+
Data_Get_Struct((object), Sophia, (sophia)); \
|
6
|
+
if ((sophia) == NULL) { \
|
7
|
+
rb_raise(rb_eStandardError, "closed object"); \
|
8
|
+
} \
|
9
|
+
if ((sophia)->env == NULL) { \
|
10
|
+
rb_raise(rb_eStandardError, "closed object"); \
|
11
|
+
} \
|
12
|
+
if ((sophia)->db == NULL) { \
|
13
|
+
rb_raise(rb_eStandardError, "closed object"); \
|
14
|
+
} \
|
15
|
+
}
|
16
|
+
|
17
|
+
static VALUE rb_cSophia;
|
18
|
+
|
19
|
+
typedef struct {
|
20
|
+
void* env;
|
21
|
+
void* db;
|
22
|
+
} Sophia;
|
23
|
+
|
24
|
+
static void
|
25
|
+
sophia_free(Sophia *sophia)
|
26
|
+
{
|
27
|
+
if (sophia) {
|
28
|
+
if (sophia->db) {
|
29
|
+
sp_destroy(sophia->db);
|
30
|
+
}
|
31
|
+
if (sophia->env) {
|
32
|
+
sp_destroy(sophia->env);
|
33
|
+
}
|
34
|
+
xfree(sophia);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
static void
|
39
|
+
sophia_mark(Sophia *sophia)
|
40
|
+
{
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE
|
44
|
+
sophia_alloc(VALUE klass)
|
45
|
+
{
|
46
|
+
Sophia *sophia = ALLOC(Sophia);
|
47
|
+
|
48
|
+
return Data_Wrap_Struct(klass, sophia_mark, sophia_free, sophia);
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* Sophia.new("/path/to/db") -> sophia
|
54
|
+
*/
|
55
|
+
static VALUE
|
56
|
+
sophia_initialize(int argc, VALUE *argv, VALUE self)
|
57
|
+
{
|
58
|
+
Sophia *sophia;
|
59
|
+
VALUE file;
|
60
|
+
|
61
|
+
Data_Get_Struct(self, Sophia, sophia);
|
62
|
+
|
63
|
+
rb_scan_args(argc, argv, "1", &file);
|
64
|
+
|
65
|
+
FilePathValue(file);
|
66
|
+
|
67
|
+
sophia->env = sp_env();
|
68
|
+
|
69
|
+
if (sophia->env == NULL) {
|
70
|
+
rb_raise(rb_eStandardError, "sp_env(3)");
|
71
|
+
}
|
72
|
+
|
73
|
+
if (sp_ctl(sophia->env, SPDIR, SPO_CREAT|SPO_RDWR, RSTRING_PTR(file))) {
|
74
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
75
|
+
}
|
76
|
+
|
77
|
+
sophia->db = sp_open(sophia->env);
|
78
|
+
|
79
|
+
if (sophia->db == NULL) {
|
80
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
81
|
+
}
|
82
|
+
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
/*
|
87
|
+
* call-seq:
|
88
|
+
* sophia.close -> nil
|
89
|
+
*/
|
90
|
+
static VALUE
|
91
|
+
sophia_close(VALUE self)
|
92
|
+
{
|
93
|
+
Sophia *sophia;
|
94
|
+
|
95
|
+
GetSophia(self, sophia);
|
96
|
+
|
97
|
+
if (sophia->db) {
|
98
|
+
if (sp_destroy(sophia->db)) {
|
99
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
100
|
+
}
|
101
|
+
sophia->db = NULL;
|
102
|
+
}
|
103
|
+
|
104
|
+
if (sophia->env) {
|
105
|
+
if (sp_destroy(sophia->env)) {
|
106
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
107
|
+
}
|
108
|
+
sophia->env = NULL;
|
109
|
+
}
|
110
|
+
|
111
|
+
return Qnil;
|
112
|
+
}
|
113
|
+
|
114
|
+
/*
|
115
|
+
* call-seq:
|
116
|
+
* sophia.closed? -> true or false
|
117
|
+
*/
|
118
|
+
static VALUE
|
119
|
+
sophia_closed_p(VALUE self)
|
120
|
+
{
|
121
|
+
Sophia *sophia;
|
122
|
+
|
123
|
+
Data_Get_Struct(self, Sophia, sophia);
|
124
|
+
|
125
|
+
if (sophia == NULL) {
|
126
|
+
return Qtrue;
|
127
|
+
}
|
128
|
+
|
129
|
+
if (sophia->env == NULL) {
|
130
|
+
return Qtrue;
|
131
|
+
}
|
132
|
+
|
133
|
+
if (sophia->db == NULL) {
|
134
|
+
return Qtrue;
|
135
|
+
}
|
136
|
+
|
137
|
+
return Qfalse;
|
138
|
+
}
|
139
|
+
|
140
|
+
static VALUE
|
141
|
+
sophia_set(VALUE self, VALUE key, VALUE value)
|
142
|
+
{
|
143
|
+
Sophia *sophia;
|
144
|
+
|
145
|
+
GetSophia(self, sophia);
|
146
|
+
|
147
|
+
key = rb_obj_as_string(key);
|
148
|
+
value = rb_obj_as_string(value);
|
149
|
+
|
150
|
+
if (sp_set(sophia->db,
|
151
|
+
RSTRING_PTR(key), RSTRING_LEN(key),
|
152
|
+
RSTRING_PTR(value), RSTRING_LEN(value))) {
|
153
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
154
|
+
}
|
155
|
+
|
156
|
+
return value;
|
157
|
+
}
|
158
|
+
|
159
|
+
static VALUE
|
160
|
+
sophia_get(VALUE self, VALUE key, VALUE ifnone)
|
161
|
+
{
|
162
|
+
Sophia *sophia;
|
163
|
+
void *value;
|
164
|
+
size_t vsize;
|
165
|
+
int result;
|
166
|
+
|
167
|
+
GetSophia(self, sophia);
|
168
|
+
|
169
|
+
ExportStringValue(key);
|
170
|
+
|
171
|
+
result = sp_get(sophia->db,
|
172
|
+
RSTRING_PTR(key), RSTRING_LEN(key),
|
173
|
+
&value, &vsize);
|
174
|
+
|
175
|
+
if (result == 1) {
|
176
|
+
return rb_str_new(value, vsize);
|
177
|
+
} else if (result == 0) {
|
178
|
+
if (NIL_P(ifnone) && rb_block_given_p()) {
|
179
|
+
return rb_yield(key);
|
180
|
+
} else {
|
181
|
+
return ifnone;
|
182
|
+
}
|
183
|
+
} else if (result == -1) {
|
184
|
+
rb_raise(rb_eStandardError, sp_error(sophia->env));
|
185
|
+
}
|
186
|
+
|
187
|
+
rb_raise(rb_eStandardError, "error");
|
188
|
+
return Qnil;
|
189
|
+
}
|
190
|
+
|
191
|
+
static VALUE
|
192
|
+
sophia_aref(VALUE self, VALUE key)
|
193
|
+
{
|
194
|
+
return sophia_get(self, key, Qnil);
|
195
|
+
}
|
196
|
+
|
197
|
+
static VALUE
|
198
|
+
sophia_fetch(int argc, VALUE *argv, VALUE self)
|
199
|
+
{
|
200
|
+
VALUE key, ifnone;
|
201
|
+
rb_scan_args(argc, argv, "11", &key, &ifnone);
|
202
|
+
|
203
|
+
return sophia_get(self, key, ifnone);
|
204
|
+
}
|
205
|
+
|
206
|
+
void
|
207
|
+
Init_sophia()
|
208
|
+
{
|
209
|
+
rb_cSophia = rb_define_class("Sophia", rb_cObject);
|
210
|
+
rb_define_alloc_func(rb_cSophia, sophia_alloc);
|
211
|
+
rb_define_private_method(rb_cSophia, "initialize", sophia_initialize, -1);
|
212
|
+
rb_define_method(rb_cSophia, "close", sophia_close, 0);
|
213
|
+
rb_define_method(rb_cSophia, "closed?", sophia_closed_p, 0);
|
214
|
+
rb_define_method(rb_cSophia, "set", sophia_set, 2);
|
215
|
+
rb_define_method(rb_cSophia, "[]=", sophia_set, 2);
|
216
|
+
rb_define_method(rb_cSophia, "get", sophia_aref, 1);
|
217
|
+
rb_define_method(rb_cSophia, "[]", sophia_aref, 1);
|
218
|
+
rb_define_method(rb_cSophia, "fetch", sophia_fetch, -1);
|
219
|
+
rb_require("sophia/version");
|
220
|
+
}
|
data/lib/sophia-ruby.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'sophia'
|
data/sophia-ruby.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sophia/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sophia-ruby"
|
8
|
+
spec.version = Sophia::VERSION
|
9
|
+
spec.authors = ["miyucy"]
|
10
|
+
spec.email = ["fistfvck@gmail.com"]
|
11
|
+
spec.description = %q{Ruby bindings for the Sophia key/value store}
|
12
|
+
spec.summary = %q{Ruby bindings for the Sophia key/value store}
|
13
|
+
spec.homepage = "http://github.com/miyucy/sophia-ruby"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.extensions = ["ext/extconf.rb"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
|
25
|
+
`git submodule --quiet foreach pwd`.split($\).each do |submodule_path|
|
26
|
+
# for each submodule, change working directory to that submodule
|
27
|
+
Dir.chdir(submodule_path) do
|
28
|
+
|
29
|
+
# issue git ls-files in submodule's directory
|
30
|
+
submodule_files = `git ls-files`.split($\)
|
31
|
+
|
32
|
+
# prepend the submodule path to create absolute file paths
|
33
|
+
submodule_files_fullpaths = submodule_files.map do |filename|
|
34
|
+
"#{submodule_path}/#{filename}"
|
35
|
+
end
|
36
|
+
|
37
|
+
# remove leading path parts to get paths relative to the gem's root dir
|
38
|
+
# (this assumes, that the gemspec resides in the gem's root dir)
|
39
|
+
submodule_files_paths = submodule_files_fullpaths.map do |filename|
|
40
|
+
filename.gsub "#{File.dirname(__FILE__)}/", ""
|
41
|
+
end
|
42
|
+
|
43
|
+
# add relative paths to gem.files
|
44
|
+
spec.files += submodule_files_paths
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/test_sophia.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler.require
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require 'sophia'
|
7
|
+
require 'tmpdir'
|
8
|
+
|
9
|
+
describe Sophia do
|
10
|
+
it 'get/set' do
|
11
|
+
path = Dir.mktmpdir
|
12
|
+
sophia = Sophia.new path
|
13
|
+
sophia['key'] = 'value'
|
14
|
+
sophia['key'].must_equal 'value'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'fetch' do
|
18
|
+
path = Dir.mktmpdir
|
19
|
+
sophia = Sophia.new path
|
20
|
+
|
21
|
+
sophia.fetch('key', '123').must_equal '123'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'fetch block' do
|
25
|
+
path = Dir.mktmpdir
|
26
|
+
sophia = Sophia.new path
|
27
|
+
|
28
|
+
sophia.fetch('key') { |key|
|
29
|
+
key.must_equal 'key'
|
30
|
+
'456'
|
31
|
+
}.must_equal '456'
|
32
|
+
end
|
33
|
+
end
|