kyotocabinet-java 0.2.0-java → 0.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ before_install:
3
+ - sudo ./travis-ci/install_kc
4
+ bundler_args: --without development
5
+ script: "bundle exec rake spec"
6
+ rvm:
7
+ - jruby-19mode # JRuby in 1.9 mode
data/Gemfile CHANGED
@@ -6,10 +6,15 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
- gem "shoulda", ">= 0"
10
9
  gem "rdoc", "~> 3.12"
11
- gem "bundler", "~> 1.1.3"
12
- gem "jeweler", "~> 1.8.4"
13
10
  gem "simplecov", ">= 0"
14
11
  gem "jruby-openssl", ">= 0", :platforms => :jruby
15
12
  end
13
+
14
+ group :test do
15
+ gem "rake", ">= 0.9"
16
+ gem "bundler", "~> 1.1.3"
17
+ gem "rspec", "~> 2.10.0"
18
+ gem "jeweler", "~> 1.8.4"
19
+ gem "kyotocabinet-ruby", "~> 1.27.1", :platforms => :mri
20
+ end
@@ -0,0 +1,95 @@
1
+ # kyotocabinet-java
2
+
3
+ [![Build Status](https://secure.travis-ci.org/csw/kyotocabinet-java.png)](http://travis-ci.org/csw/kyotocabinet-java)
4
+
5
+
6
+ This is a Ruby gem providing a JRuby interface for the
7
+ [Kyoto Cabinet][] database library. It aims to provide an identical
8
+ interface to the official [Ruby library][]. However, that library uses
9
+ Ruby's C extension API and thus does not work under JRuby. This is
10
+ instead implemented atop Kyoto Cabinet's [Java API][], with a minimal
11
+ Ruby adaptation layer to compensate for interface differences.
12
+
13
+ [Kyoto Cabinet]: http://fallabs.com/kyotocabinet/
14
+ [Ruby library]: http://fallabs.com/kyotocabinet/rubydoc/
15
+ [Java API]: http://fallabs.com/kyotocabinet/javadoc/
16
+
17
+ ## Prerequisites
18
+
19
+ Installation of this gem requires that Kyoto Cabinet (>= 1.2.76)
20
+ already be installed. See the [installation notes][] for
21
+ platform-specific instructions. It also requires a C++ compiler and
22
+ JDK, since it contains a patched copy of the [kyotocabinet-java][]
23
+ library, which will be compiled upon installation. It does not attempt
24
+ to install anything outside the RubyGems directory.
25
+
26
+ [installation notes]: https://github.com/csw/kyotocabinet-java/wiki/Kyoto-Cabinet-installation
27
+ [kyotocabinet-java]: http://fallabs.com/kyotocabinet/javapkg/
28
+
29
+ ## Installation
30
+
31
+ ```
32
+ $ gem install kyotocabinet-java
33
+ ```
34
+
35
+ Or, if you're using [Bundler][] and want your Ruby code to be able to
36
+ transparently use Kyoto Cabinet under MRI or JRuby, you might want to
37
+ add something like this to your Gemfile:
38
+
39
+ [Bundler]: http://gembundler.com/
40
+
41
+ ```ruby
42
+ gem "kyotocabinet-ruby", "~> 1.27.1", :platforms => [:mri, :rbx]
43
+ gem "kyotocabinet-java", "~> 0.2.0", :platforms => :jruby
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ This is designed to be a drop-in replacement for `kyotocabinet-ruby`,
49
+ and so usage should be identical:
50
+
51
+ ```ruby
52
+ require 'kyotocabinet'
53
+ db = KyotoCabinet::DB.new
54
+ db.open("%", KyotoCabinet::DB::OWRITER | KyotoCabinet::DB::OCREATE)
55
+ db["hello"] = "world"
56
+ ```
57
+
58
+ ## Status
59
+
60
+ This library was written to maintain indexes for a
61
+ [BioRuby MAF parser][]. It works for that purpose but has not been
62
+ exhaustively tested. Other parts of the Kyoto Cabinet API might need
63
+ some work. The `bioruby-maf` code relies on storing binary data in
64
+ Kyoto Cabinet; this works with the Java API methods accepting or
65
+ returning `byte[]`, but not their `String` counterparts. Some of these
66
+ methods have been wrapped to explicitly convert arguments and return
67
+ values to byte arrays, but not all. See [kyotocabinet.rb][] for
68
+ examples. Feel free to submit pull requests.
69
+
70
+ [BioRuby MAF parser]: https://github.com/csw/bioruby-maf
71
+ [kyotocabinet.rb]: https://github.com/csw/kyotocabinet-java/blob/master/lib/kyotocabinet.rb
72
+
73
+ Installation has been tested on Mac OS X 10.7.4 and Debian wheezy, and
74
+ should work on Ubuntu and Fedora as well. Please report build problems
75
+ on other Unix platforms; it should be fairly easy to resolve them.
76
+
77
+ It's not completely clear what it would take to make this work on
78
+ Windows; shipping a pre-built JAR and the binary DLL provided by FAL
79
+ Labs might do it. Patches would be welcome.
80
+
81
+ ## Contributing to kyotocabinet-java
82
+
83
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
84
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
85
+ * Fork the project.
86
+ * Start a feature/bugfix branch.
87
+ * Commit and push until you are happy with your contribution.
88
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
89
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
90
+
91
+ ## Copyright
92
+
93
+ Copyright (c) 2012 Clayton Wheeler (packaging, Ruby library) and
94
+ copyright (c) 2009-2012 FAL Labs. See LICENSE.txt for further details.
95
+
data/Rakefile CHANGED
@@ -10,6 +10,7 @@ rescue Bundler::BundlerError => e
10
10
  exit e.status_code
11
11
  end
12
12
  require 'rake'
13
+ require 'rake/clean'
13
14
 
14
15
  require 'jeweler'
15
16
  Jeweler::Tasks.new do |gem|
@@ -33,13 +34,23 @@ file "ext/kyotocabinet-java/configure" => ["ext/kyotocabinet-java/configure.in"]
33
34
  end
34
35
  task :build => "ext/kyotocabinet-java/configure"
35
36
 
36
- require 'rake/testtask'
37
- Rake::TestTask.new(:test) do |test|
38
- test.libs << 'lib' << 'test'
39
- test.pattern = 'test/**/test_*.rb'
40
- test.verbose = true
37
+ file "test_ext/kyotocabinet.jar" => ["ext/kyotocabinet-java/configure"] do
38
+ sh "cd ext/kyotocabinet-java; ./configure --prefix=#{File.expand_path('../test_ext', __FILE__)} && make && make install && make clean"
41
39
  end
42
40
 
41
+ CLEAN.include("ext/kyotocabinet-java/Makefile")
42
+ CLEAN.include("test_ext/*")
43
+
44
+ CLOBBER.include("ext/kyotocabinet-java/config.status")
45
+ CLOBBER.include("ext/kyotocabinet-java/config.tmp")
46
+
47
+ require 'rspec/core'
48
+ require 'rspec/core/rake_task'
49
+ RSpec::Core::RakeTask.new(:spec) do |spec|
50
+ spec.pattern = FileList['spec/**/*_spec.rb']
51
+ end
52
+ task :spec => "test_ext/kyotocabinet.jar"
53
+
43
54
  # XXX: using simplecov instead
44
55
  # require 'rcov/rcovtask'
45
56
  # Rcov::RcovTask.new do |test|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -1 +1,4 @@
1
1
  autom4te.cache/*
2
+ Makefile
3
+ config.status
4
+ config.tmp
@@ -5,24 +5,25 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "kyotocabinet-java"
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
  s.platform = "java"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["FAL Labs", "Clayton Wheeler"]
13
- s.date = "2012-06-26"
13
+ s.date = "2012-07-12"
14
14
  s.description = "Wrapper for Kyoto Cabinet's Java library for use with JRuby, to provide the same interface as the native kyotocabinet-ruby gem for MRI."
15
15
  s.email = "cswh@umich.edu"
16
16
  s.extensions = ["ext/kyotocabinet-java/configure"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE.txt",
19
- "README.rdoc"
19
+ "README.md"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
+ ".travis.yml",
23
24
  "Gemfile",
24
25
  "LICENSE.txt",
25
- "README.rdoc",
26
+ "README.md",
26
27
  "Rakefile",
27
28
  "VERSION",
28
29
  "ext/kyotocabinet-java/.gitignore",
@@ -91,7 +92,13 @@ Gem::Specification.new do |s|
91
92
  "ext/kyotocabinet-java/kyotocabinet_ValueIterator.h",
92
93
  "ext/kyotocabinet-java/overview.html",
93
94
  "kyotocabinet-java.gemspec",
94
- "lib/kyotocabinet.rb"
95
+ "lib/kyotocabinet.rb",
96
+ "spec/kyotocabinet_spec.rb",
97
+ "spec/spec_helper.rb",
98
+ "test/.gitignore",
99
+ "test/kctest.rb",
100
+ "test/test.rb",
101
+ "travis-ci/install_kc"
95
102
  ]
96
103
  s.homepage = "http://github.com/csw/kyotocabinet-java"
97
104
  s.licenses = ["GPL"]
@@ -103,25 +110,16 @@ Gem::Specification.new do |s|
103
110
  s.specification_version = 3
104
111
 
105
112
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
106
- s.add_development_dependency(%q<shoulda>, [">= 0"])
107
113
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
108
- s.add_development_dependency(%q<bundler>, ["~> 1.1.3"])
109
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
110
114
  s.add_development_dependency(%q<simplecov>, [">= 0"])
111
115
  s.add_development_dependency(%q<jruby-openssl>, [">= 0"])
112
116
  else
113
- s.add_dependency(%q<shoulda>, [">= 0"])
114
117
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
115
- s.add_dependency(%q<bundler>, ["~> 1.1.3"])
116
- s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
117
118
  s.add_dependency(%q<simplecov>, [">= 0"])
118
119
  s.add_dependency(%q<jruby-openssl>, [">= 0"])
119
120
  end
120
121
  else
121
- s.add_dependency(%q<shoulda>, [">= 0"])
122
122
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
123
- s.add_dependency(%q<bundler>, ["~> 1.1.3"])
124
- s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
125
123
  s.add_dependency(%q<simplecov>, [">= 0"])
126
124
  s.add_dependency(%q<jruby-openssl>, [">= 0"])
127
125
  end
@@ -24,7 +24,7 @@ unless Java.const_defined? :Kyotocabinet
24
24
  # need to require kyotocabinet.jar
25
25
  soname = java.lang.System.mapLibraryName("jkyotocabinet")
26
26
  jdir = $LOAD_PATH.find { |d| File.exist? "#{d}/kyotocabinet.jar" }
27
- raise "Could not find kyotocabinet.jar on $LOAD_PATH!" unless jdir
27
+ raise "Could not find kyotocabinet.jar on $LOAD_PATH (#{$LOAD_PATH.join(':')})!" unless jdir
28
28
  sopath = "#{jdir}/#{soname}"
29
29
  unless File.exist? sopath
30
30
  raise "JNI library #{soname} not installed in #{jdir}!"
@@ -42,25 +42,149 @@ module KyotoCabinet
42
42
  module Adaptation
43
43
  BYTE_ARRAY = [1].to_java(:byte).java_class
44
44
 
45
+ def conv_string_array(a)
46
+ ba = Java::byte[a.size, 0].new
47
+ a.each_with_index do |k, i|
48
+ ba[i] = k.to_java_bytes
49
+ end
50
+ ba
51
+ end
52
+
53
+ def to_string_array(ba)
54
+ ba.collect { |e| String.from_java_bytes(e) }
55
+ end
56
+
45
57
  def self.included(mod)
46
58
  super(mod)
47
- mod.class_eval do
48
- def self.with_method_handle(mname, *args)
49
- $stderr.puts "in #{self}.with_method_handle(#{mname.inspect}, #{args.inspect})"
59
+ mod.instance_eval do
60
+ def with_java_method(mname, args)
50
61
  mh = self.java_method(mname, args)
51
- $stderr.puts "got method handle #{mh}"
52
62
  yield mh
53
63
  end
64
+ def convert_args(mname, args)
65
+ indices = []
66
+ args.each_with_index do |a, i|
67
+ if a == BYTE_ARRAY
68
+ indices << i
69
+ end
70
+ end
71
+ mh = self.java_method(mname, args)
72
+ self.send(:define_method, mname) do |*argv|
73
+ indices.each { |i| argv[i] = argv[i].to_java_bytes }
74
+ mh.bind(self).call(*argv)
75
+ end
76
+ end
77
+
78
+ def convert_args_ret(mname, args)
79
+ indices = []
80
+ args.each_with_index do |a, i|
81
+ if a == BYTE_ARRAY
82
+ indices << i
83
+ end
84
+ end
85
+ mh = self.java_method(mname, args)
86
+ self.send(:define_method, mname) do |*argv|
87
+ indices.each { |i| argv[i] = argv[i].to_java_bytes }
88
+ rv = mh.bind(self).call(*argv)
89
+ if rv
90
+ String.from_java_bytes(rv)
91
+ end
92
+ end
93
+ end
54
94
  end
55
95
  end
56
96
 
97
+ def ret_bytes(v)
98
+ if v
99
+ String.from_java_bytes(v)
100
+ end
101
+ end
102
+ end
103
+
104
+ class VisitorProxy
105
+ include Java::Kyotocabinet::Visitor
106
+
107
+ def initialize(v, readonly=false)
108
+ @v = v
109
+ @readonly = readonly
110
+ end
111
+
112
+ def visit_empty(key)
113
+ rv = @v.visit_empty(String.from_java_bytes(key))
114
+ rv && (! @readonly) ? rv.to_java_bytes : Visitor::NOP
115
+ end
116
+
117
+ def visit_full(key, value)
118
+ rv = @v.visit_full(String.from_java_bytes(key),
119
+ String.from_java_bytes(value))
120
+ rv && (! @readonly) ? rv.to_java_bytes : Visitor::NOP
121
+ end
57
122
  end
123
+
124
+ class BlockVisitor
125
+
126
+ def self.wrap(proc, ro=false)
127
+ VisitorProxy.new(self.new(proc), ro)
128
+ end
129
+
130
+ def self.wrap_nop(proc)
131
+ NOPVisitor.new(self.wrap(proc, true))
132
+ end
133
+
134
+ def initialize(proc)
135
+ @proc = proc
136
+ end
137
+
138
+ def visit_empty(key)
139
+ @proc.call(key)
140
+ end
141
+
142
+ def visit_full(key, value)
143
+ @proc.call(key, value)
144
+ end
145
+
146
+ end
147
+
148
+ class NOPVisitor
149
+ def initialize(base)
150
+ @base = base
151
+ end
152
+
153
+ def visit_empty(key)
154
+ @base.visit_empty(key)
155
+ Visitor::NOP
156
+ end
157
+
158
+ def visit_full(key, value)
159
+ @base.visit_full(key, value)
160
+ Visitor::NOP
161
+ end
162
+ end
163
+
58
164
  end
59
165
 
60
166
  module Java::Kyotocabinet
167
+ VisitorProxy = KyotoCabinet::VisitorProxy
168
+ BlockVisitor = KyotoCabinet::BlockVisitor
169
+
61
170
  class Cursor
62
171
  include KyotoCabinet::Adaptation
63
172
 
173
+ alias_method :_accept, :accept
174
+ def accept(visitor=nil, writable=true, step=false)
175
+ vp = if visitor
176
+ VisitorProxy.new(visitor, !writable)
177
+ else
178
+ if writable
179
+ BlockVisitor.wrap(blk)
180
+ else
181
+ BlockVisitor.wrap_nop(blk)
182
+ end
183
+ end
184
+ _accept(vp, writable, step)
185
+ end
186
+
187
+
64
188
  alias_method :_get, :get
65
189
  def get(step=false)
66
190
  r = self._get(step)
@@ -74,39 +198,188 @@ module Java::Kyotocabinet
74
198
 
75
199
  alias_method :_get_key, :get_key
76
200
  def get_key(step=false)
77
- r = self._get_key(step)
78
- if r
79
- return String.from_java_bytes(r)
201
+ ret_bytes(_get_key(step))
202
+ end
203
+
204
+ alias_method :_get_value, :get_value
205
+ def get_value(step=false)
206
+ ret_bytes(_get_value(step))
207
+ end
208
+
209
+
210
+ alias_method :_jump, :jump
211
+ def jump(key=nil)
212
+ if key
213
+ _jump(key.to_java_bytes)
80
214
  else
81
- return nil
215
+ _jump()
82
216
  end
83
217
  end
84
218
 
85
- alias_method :_jump, :jump
86
- def jump(key)
87
- self._jump(key.to_java_bytes)
219
+ alias_method :_jump_back, :jump_back
220
+ def jump_back(key=nil)
221
+ if key
222
+ _jump_back(key.to_java_bytes)
223
+ else
224
+ _jump_back()
225
+ end
226
+ end
227
+
228
+ alias_method :_seize, :seize
229
+ def seize()
230
+ to_string_array(_seize())
231
+ end
232
+
233
+
234
+ alias_method :_set_value, :set_value
235
+ def set_value(value, step=false)
236
+ _set_value(value ? value.to_java_bytes : nil,
237
+ step)
88
238
  end
239
+
240
+
89
241
  end # class Cursor
90
242
 
91
243
  class DB
92
244
  include KyotoCabinet::Adaptation
93
245
 
94
- alias_method :_match_prefix, :match_prefix
95
- def match_prefix(prefix, limit=-1)
96
- self._match_prefix(prefix, limit)
246
+ # The Java API is thread-safe so this can be a no-op
247
+ GCONCURRENT = 0
248
+
249
+ alias_method :_accept, :accept
250
+ def accept(key, visitor=nil, writable=true, &blk)
251
+ vp = if visitor
252
+ VisitorProxy.new(visitor, !writable)
253
+ else
254
+ if writable
255
+ BlockVisitor.wrap(blk)
256
+ else
257
+ BlockVisitor.wrap_nop(blk)
258
+ end
259
+ end
260
+ self._accept(key.to_java_bytes, vp, writable)
261
+ end
262
+
263
+ alias_method :_accept_bulk, :accept_bulk
264
+ def accept_bulk(keys, visitor=nil, writable=true, &blk)
265
+ vp = if visitor
266
+ VisitorProxy.new(visitor, !writable)
267
+ else
268
+ if writable
269
+ BlockVisitor.wrap(blk)
270
+ else
271
+ BlockVisitor.wrap_nop(blk)
272
+ end
273
+ end
274
+ self._accept_bulk(conv_string_array(keys), vp, writable)
275
+ end
276
+
277
+ convert_args :add, [BYTE_ARRAY, BYTE_ARRAY]
278
+ convert_args :append, [BYTE_ARRAY, BYTE_ARRAY]
279
+ convert_args :cas, [BYTE_ARRAY, BYTE_ARRAY, BYTE_ARRAY]
280
+ convert_args :check, [BYTE_ARRAY]
281
+
282
+ def each(&blk)
283
+ _iterate(BlockVisitor.wrap_nop(blk), false)
284
+ end
285
+
286
+ def each_key
287
+ _iterate(BlockVisitor.wrap_nop(lambda { |k, v| yield [k] }),
288
+ false)
289
+ end
290
+
291
+ def each_value
292
+ _iterate(BlockVisitor.wrap_nop(lambda { |k, v| yield [v] }),
293
+ false)
97
294
  end
98
295
 
99
296
  alias_method :_get, :get
100
297
  def get(key)
101
- String.from_java_bytes(self._get(key.to_java_bytes))
298
+ ret_bytes(self._get(key.to_java_bytes))
102
299
  end
103
300
  alias_method :[], :get
104
301
 
302
+ alias_method :_get_bulk, :get_bulk
303
+ def get_bulk(keys, atomic=true)
304
+ ra = _get_bulk(conv_string_array(keys), atomic)
305
+ h = {}
306
+ i = 0
307
+ while i < ra.size
308
+ h[String.from_java_bytes(ra[i])] = String.from_java_bytes(ra[i + 1])
309
+ i += 2
310
+ end
311
+ h
312
+ end
313
+
314
+ alias_method :_increment, :increment
315
+ def increment(key, num=0, orig=0)
316
+ self._increment(key.to_java_bytes, num, orig)
317
+ end
318
+
319
+ alias_method :_increment_double, :increment_double
320
+ def increment_double(key, num=0, orig=0)
321
+ _increment_double(key.to_java_bytes, num, orig)
322
+ end
323
+
324
+ alias_method :_iterate, :iterate
325
+ def iterate(visitor=nil, writable=true, &blk)
326
+ if visitor
327
+ _iterate(VisitorProxy.new(visitor),
328
+ writable)
329
+ else
330
+ _iterate(BlockVisitor.wrap(blk),
331
+ writable)
332
+ end
333
+ end
334
+
335
+ alias_method :_match_prefix, :match_prefix
336
+ def match_prefix(prefix, max=-1)
337
+ _match_prefix(prefix, max)
338
+ end
339
+
340
+ alias_method :_match_regex, :match_regex
341
+ def match_regex(regex, max=-1)
342
+ _match_regex(regex, max)
343
+ end
344
+
345
+ alias_method :_match_similar, :match_similar
346
+ def match_similar(origin, range=1, utf=false, max=-1)
347
+ _match_similar(origin, range, utf, max)
348
+ end
349
+
350
+ alias_method :_merge, :merge
351
+ def merge(srcary, mode=DB::MSET)
352
+ _merge(srcary.to_java(DB), mode)
353
+ end
354
+
355
+ alias_method :_occupy, :occupy
356
+ def occupy(writable=false, proc=nil)
357
+ _occupy(writable, proc)
358
+ end
359
+
360
+ alias_method :_open, :open
361
+ def open(path=':', mode=DB::OWRITER|DB::OCREATE)
362
+ _open(path, mode)
363
+ end
364
+
365
+ convert_args :remove, [BYTE_ARRAY]
366
+ alias_method :delete, :remove
367
+
368
+ alias_method :_remove_bulk, :remove_bulk
369
+ def remove_bulk(keys, atomic=true)
370
+ _remove_bulk(conv_string_array(keys), atomic)
371
+ end
372
+
373
+ convert_args :replace, [BYTE_ARRAY, BYTE_ARRAY]
374
+
375
+ convert_args_ret :seize, [BYTE_ARRAY]
376
+
105
377
  alias_method :_set, :set
106
378
  def set(k, v)
107
379
  self._set(k.to_java_bytes, v.to_s.to_java_bytes)
108
380
  end
109
381
  alias_method :[]=, :set
382
+ alias_method :store, :set
110
383
 
111
384
  alias_method :_set_bulk, :set_bulk
112
385
  def set_bulk(rec_h, atomic)
@@ -120,11 +393,25 @@ module Java::Kyotocabinet
120
393
  self._set_bulk(ba, atomic)
121
394
  end
122
395
 
396
+ ## TODO: store?
397
+
123
398
  alias_method :_synchronize, :synchronize
124
399
  def synchronize(hard=false, proc=nil)
125
400
  self._synchronize(hard, proc)
126
401
  end
127
402
 
403
+ def transaction(hard=false)
404
+ begin_transaction(hard)
405
+ commit = false
406
+ begin
407
+ commit = yield
408
+ ensure
409
+ end_transaction(commit)
410
+ end
411
+ commit
412
+ end
413
+
414
+
128
415
  def cursor_process
129
416
  cur = self.cursor()
130
417
  begin
@@ -137,5 +424,9 @@ module Java::Kyotocabinet
137
424
  end
138
425
 
139
426
  module KyotoCabinet
140
- import Java::Kyotocabinet
427
+ java_import Java::Kyotocabinet::Cursor
428
+ java_import Java::Kyotocabinet::DB
429
+ java_import Java::Kyotocabinet::Error
430
+ java_import Java::Kyotocabinet::FileProcessor
431
+ java_import Java::Kyotocabinet::Visitor
141
432
  end