rroonga 1.2.5 → 1.2.6
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/Rakefile +23 -285
- data/ext/groonga/Makefile +1 -1
- data/ext/groonga/extconf.rb +4 -2
- data/ext/groonga/rb-grn-array.c +5 -4
- data/ext/groonga/rb-grn-context.c +7 -22
- data/ext/groonga/rb-grn-database.c +43 -1
- data/ext/groonga/rb-grn-index-column.c +5 -0
- data/ext/groonga/rb-grn-object.c +58 -26
- data/ext/groonga/rb-grn-patricia-trie.c +2 -1
- data/ext/groonga/rb-grn-record.c +11 -1
- data/ext/groonga/rb-grn-table-key-support.c +21 -10
- data/ext/groonga/rb-grn-utils.c +3 -1
- data/ext/groonga/rb-grn-variable-size-column.c +47 -1
- data/ext/groonga/rb-grn.h +4 -1
- data/extconf.rb +1 -0
- data/lib/groonga/pagination.rb +1 -1
- data/lib/groonga/record.rb +10 -0
- data/rroonga-build.rb +1 -1
- data/test/test-accessor.rb +4 -0
- data/test/test-array.rb +9 -1
- data/test/test-database.rb +16 -0
- data/test/test-hash.rb +11 -2
- data/test/test-patricia-trie.rb +10 -1
- data/test/test-table-select.rb +31 -17
- data/test/test-type.rb +3 -3
- data/test/test-variable-size-column.rb +8 -1
- metadata +18 -4
data/Rakefile
CHANGED
@@ -26,6 +26,7 @@ require 'rubygems/package_task'
|
|
26
26
|
require 'yard'
|
27
27
|
require 'jeweler'
|
28
28
|
require 'rake/extensiontask'
|
29
|
+
require 'packnga'
|
29
30
|
|
30
31
|
if YAML.const_defined?(:ENGINE)
|
31
32
|
begin
|
@@ -101,6 +102,28 @@ Gem::PackageTask.new(spec) do |pkg|
|
|
101
102
|
pkg.need_tar_gz = true
|
102
103
|
end
|
103
104
|
|
105
|
+
document_task = Packnga::DocumentTask.new(spec) do |t|
|
106
|
+
t.yard do |yard_task|
|
107
|
+
yard_task.files += FileList["ext/**/*.c"]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
namespace :reference do
|
112
|
+
namespace :publication do
|
113
|
+
task :keep_compatible do
|
114
|
+
File.open(document_task.htaccess, "a") do |file|
|
115
|
+
file.puts("Redirect permanent /#{spec.name}/text/TUTORIAL_ja_rdoc.html " +
|
116
|
+
"#{spec.homepage}#{spec.name}/ja/file.tutorial.html")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
task :generate => :keep_compatible
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
Packnga::ReleaseTask.new(spec) do |task|
|
125
|
+
end
|
126
|
+
|
104
127
|
module YARD
|
105
128
|
module CodeObjects
|
106
129
|
class Proxy
|
@@ -123,33 +146,6 @@ module YARD
|
|
123
146
|
end
|
124
147
|
end
|
125
148
|
|
126
|
-
reference_base_dir = Pathname.new("doc/reference")
|
127
|
-
doc_en_dir = reference_base_dir + "en"
|
128
|
-
html_base_dir = Pathname.new("doc/html")
|
129
|
-
html_reference_dir = html_base_dir + spec.name
|
130
|
-
YARD::Rake::YardocTask.new do |task|
|
131
|
-
task.options += ["--title", spec.name]
|
132
|
-
# task.options += ["--charset", "UTF-8"]
|
133
|
-
task.options += ["--readme", "README.textile"]
|
134
|
-
task.options += ["--files", "doc/text/**/*"]
|
135
|
-
task.options += ["--output-dir", doc_en_dir.to_s]
|
136
|
-
task.options += ["--charset", "utf-8"]
|
137
|
-
task.files += FileList["ext/groonga/**/*.c"]
|
138
|
-
task.files += FileList["lib/**/*.rb"]
|
139
|
-
end
|
140
|
-
|
141
|
-
task :yard do
|
142
|
-
doc_en_dir.find do |path|
|
143
|
-
next if path.extname != ".html"
|
144
|
-
html = path.read
|
145
|
-
html = html.gsub(/<div id="footer">.+<\/div>/m,
|
146
|
-
"<div id=\"footer\"></div>")
|
147
|
-
path.open("w") do |html_file|
|
148
|
-
html_file.print(html)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
149
|
def windows?(platform=nil)
|
154
150
|
platform ||= RUBY_PLATFORM
|
155
151
|
platform =~ /mswin(?!ce)|mingw|cygwin|bccwin/
|
@@ -191,264 +187,6 @@ Rake::ExtensionTask.new("groonga", spec) do |ext|
|
|
191
187
|
end
|
192
188
|
end
|
193
189
|
|
194
|
-
include ERB::Util
|
195
|
-
|
196
|
-
def apply_template(content, paths, templates, language)
|
197
|
-
content = content.sub(/lang="en"/, "lang=\"#{language}\"")
|
198
|
-
|
199
|
-
title = nil
|
200
|
-
content = content.sub(/<title>(.+?)<\/title>/m) do
|
201
|
-
title = $1
|
202
|
-
templates[:head].result(binding)
|
203
|
-
end
|
204
|
-
|
205
|
-
content = content.sub(/<body(?:.*?)>/) do |body_start|
|
206
|
-
"#{body_start}\n#{templates[:header].result(binding)}\n"
|
207
|
-
end
|
208
|
-
|
209
|
-
content = content.sub(/<\/body/) do |body_end|
|
210
|
-
"\n#{templates[:footer].result(binding)}\n#{body_end}"
|
211
|
-
end
|
212
|
-
|
213
|
-
content
|
214
|
-
end
|
215
|
-
|
216
|
-
def erb_template(name)
|
217
|
-
file = File.join("doc/templates", "#{name}.html.erb")
|
218
|
-
template = File.read(file)
|
219
|
-
erb = ERB.new(template, nil, "-")
|
220
|
-
erb.filename = file
|
221
|
-
erb
|
222
|
-
end
|
223
|
-
|
224
|
-
def rsync_to_rubyforge(spec, source, destination, options={})
|
225
|
-
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
226
|
-
host = "#{config["username"]}@rubyforge.org"
|
227
|
-
|
228
|
-
rsync_args = "-av --exclude '*.erb' --chmod=ug+w"
|
229
|
-
rsync_args << " --delete" if options[:delete]
|
230
|
-
remote_dir = "/var/www/gforge-projects/#{spec.rubyforge_project}/"
|
231
|
-
sh("rsync #{rsync_args} #{source} #{host}:#{remote_dir}#{destination}")
|
232
|
-
end
|
233
|
-
|
234
|
-
def rake(*arguments)
|
235
|
-
ruby($0, *arguments)
|
236
|
-
end
|
237
|
-
|
238
|
-
namespace :reference do
|
239
|
-
translate_languages = [:ja]
|
240
|
-
supported_languages = [:en, *translate_languages]
|
241
|
-
html_files = FileList[doc_en_dir + "**/*.html"].to_a
|
242
|
-
|
243
|
-
directory reference_base_dir.to_s
|
244
|
-
CLOBBER.include(reference_base_dir.to_s)
|
245
|
-
|
246
|
-
po_dir = "doc/po"
|
247
|
-
namespace :pot do
|
248
|
-
pot_file = "#{po_dir}/#{spec.name}.pot"
|
249
|
-
|
250
|
-
directory po_dir
|
251
|
-
file pot_file => ["po", *html_files] do |t|
|
252
|
-
sh("xml2po", "--keep-entities", "--output", t.name, *html_files)
|
253
|
-
end
|
254
|
-
|
255
|
-
desc "Generates pot file."
|
256
|
-
task :generate => pot_file
|
257
|
-
end
|
258
|
-
|
259
|
-
namespace :po do
|
260
|
-
translate_languages.each do |language|
|
261
|
-
namespace language do
|
262
|
-
po_file = "#{po_dir}/#{language}.po"
|
263
|
-
|
264
|
-
file po_file => html_files do |t|
|
265
|
-
sh("xml2po", "--keep-entities", "--update", t.name, *html_files)
|
266
|
-
end
|
267
|
-
|
268
|
-
desc "Updates po file for #{language}."
|
269
|
-
task :update => po_file
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
desc "Updates po files."
|
274
|
-
task :update do
|
275
|
-
ruby($0, "clobber")
|
276
|
-
ruby($0, "yard")
|
277
|
-
translate_languages.each do |language|
|
278
|
-
ruby($0, "reference:po:#{language}:update")
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
namespace :translate do
|
284
|
-
translate_languages.each do |language|
|
285
|
-
po_file = "#{po_dir}/#{language}.po"
|
286
|
-
translate_doc_dir = "#{reference_base_dir}/#{language}"
|
287
|
-
|
288
|
-
desc "Translates documents to #{language}."
|
289
|
-
task language => [po_file, reference_base_dir, *html_files] do
|
290
|
-
doc_en_dir.find do |path|
|
291
|
-
base_path = path.relative_path_from(doc_en_dir)
|
292
|
-
translated_path = "#{translate_doc_dir}/#{base_path}"
|
293
|
-
if path.directory?
|
294
|
-
mkdir_p(translated_path)
|
295
|
-
next
|
296
|
-
end
|
297
|
-
case path.extname
|
298
|
-
when ".html"
|
299
|
-
sh("xml2po --keep-entities " +
|
300
|
-
"--po-file #{po_file} --language #{language} " +
|
301
|
-
"#{path} > #{translated_path}")
|
302
|
-
else
|
303
|
-
cp(path.to_s, translated_path, :preserve => true)
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
translate_task_names = translate_languages.collect do |language|
|
311
|
-
"reference:translate:#{language}"
|
312
|
-
end
|
313
|
-
desc "Translates references."
|
314
|
-
task :translate => translate_task_names
|
315
|
-
|
316
|
-
desc "Generates references."
|
317
|
-
task :generate => [:yard, :translate]
|
318
|
-
|
319
|
-
namespace :publication do
|
320
|
-
task :prepare do
|
321
|
-
supported_languages.each do |language|
|
322
|
-
raw_reference_dir = reference_base_dir + language.to_s
|
323
|
-
prepared_reference_dir = html_reference_dir + language.to_s
|
324
|
-
rm_rf(prepared_reference_dir.to_s)
|
325
|
-
head = erb_template("head.#{language}")
|
326
|
-
header = erb_template("header.#{language}")
|
327
|
-
footer = erb_template("footer.#{language}")
|
328
|
-
raw_reference_dir.find do |path|
|
329
|
-
relative_path = path.relative_path_from(raw_reference_dir)
|
330
|
-
prepared_path = prepared_reference_dir + relative_path
|
331
|
-
if path.directory?
|
332
|
-
mkdir_p(prepared_path.to_s)
|
333
|
-
else
|
334
|
-
case path.basename.to_s
|
335
|
-
when /(?:file|method|class)_list\.html\z/
|
336
|
-
cp(path.to_s, prepared_path.to_s)
|
337
|
-
when /\.html\z/
|
338
|
-
relative_dir_path = relative_path.dirname
|
339
|
-
current_path = relative_dir_path + path.basename
|
340
|
-
if current_path.basename.to_s == "index.html"
|
341
|
-
current_path = current_path.dirname
|
342
|
-
end
|
343
|
-
top_path = html_base_dir.relative_path_from(prepared_path.dirname)
|
344
|
-
paths = {
|
345
|
-
:top => top_path,
|
346
|
-
:current => current_path,
|
347
|
-
}
|
348
|
-
templates = {
|
349
|
-
:head => head,
|
350
|
-
:header => header,
|
351
|
-
:footer => footer
|
352
|
-
}
|
353
|
-
content = apply_template(File.read(path.to_s),
|
354
|
-
paths,
|
355
|
-
templates,
|
356
|
-
language)
|
357
|
-
File.open(prepared_path.to_s, "w") do |file|
|
358
|
-
file.print(content)
|
359
|
-
end
|
360
|
-
else
|
361
|
-
cp(path.to_s, prepared_path.to_s)
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
366
|
-
File.open("#{html_reference_dir}/.htaccess", "w") do |file|
|
367
|
-
file.puts("Redirect permanent /#{spec.name}/text/TUTORIAL_ja_rdoc.html " +
|
368
|
-
"#{spec.homepage}#{spec.name}/ja/file.tutorial.html")
|
369
|
-
file.puts("RedirectMatch permanent ^/#{spec.name}/$ " +
|
370
|
-
"#{spec.homepage}#{spec.name}/en/")
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
desc "Upload document to rubyforge."
|
376
|
-
task :publish => [:generate, "reference:publication:prepare"] do
|
377
|
-
rsync_to_rubyforge(spec, "#{html_reference_dir}/", spec.name)
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
namespace :html do
|
382
|
-
desc "Publish HTML to Web site."
|
383
|
-
task :publish do
|
384
|
-
rsync_to_rubyforge(spec, "#{html_base_dir}/", "")
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
desc "Upload document and HTML to rubyforge."
|
389
|
-
task :publish => ["html:publish", "reference:publish"]
|
390
|
-
|
391
|
-
desc "Tag the current revision."
|
392
|
-
task :tag do
|
393
|
-
sh("git tag -a #{version} -m 'release #{version}!!!'")
|
394
|
-
end
|
395
|
-
|
396
|
-
namespace :release do
|
397
|
-
namespace :info do
|
398
|
-
desc "update version in index HTML."
|
399
|
-
task :update do
|
400
|
-
old_version = ENV["OLD_VERSION"]
|
401
|
-
old_release_date = ENV["OLD_RELEASE_DATE"]
|
402
|
-
new_release_date = ENV["RELEASE_DATE"] || Time.now.strftime("%Y-%m-%d")
|
403
|
-
new_version = ENV["VERSION"]
|
404
|
-
|
405
|
-
empty_options = []
|
406
|
-
empty_options << "OLD_VERSION" if old_version.nil?
|
407
|
-
empty_options << "OLD_RELEASE_DATE" if old_release_date.nil?
|
408
|
-
|
409
|
-
unless empty_options.empty?
|
410
|
-
raise ArgumentError, "Specify option(s) of #{empty_options.join(",")}."
|
411
|
-
end
|
412
|
-
|
413
|
-
indexes = ["doc/html/index.html", "doc/html/index.html.ja"]
|
414
|
-
indexes.each do |index|
|
415
|
-
content = replaced_content = File.read(index)
|
416
|
-
[[old_version, new_version],
|
417
|
-
[old_release_date, new_release_date]].each do |old, new|
|
418
|
-
replaced_content = replaced_content.gsub(/#{Regexp.escape(old)}/, new)
|
419
|
-
if /\./ =~ old
|
420
|
-
old_undnerscore = old.gsub(/\./, '-')
|
421
|
-
new_underscore = new.gsub(/\./, '-')
|
422
|
-
replaced_content =
|
423
|
-
replaced_content.gsub(/#{Regexp.escape(old_underscore)}/,
|
424
|
-
new_underscore)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
|
-
next if replaced_content == content
|
429
|
-
File.open(index, "w") do |output|
|
430
|
-
output.print(replaced_content)
|
431
|
-
end
|
432
|
-
end
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
namespace :rubyforge do
|
437
|
-
desc "Upload tar.gz to RubyForge."
|
438
|
-
task :upload => "package" do
|
439
|
-
ruby("-S", "rubyforge",
|
440
|
-
"add_release",
|
441
|
-
spec.rubyforge_project,
|
442
|
-
spec.name,
|
443
|
-
spec.version.to_s,
|
444
|
-
"pkg/#{spec.name}-#{spec.version}.tar.gz")
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
desc "Release to RubyForge."
|
449
|
-
task :rubyforge => "release:rubyforge:upload"
|
450
|
-
end
|
451
|
-
|
452
190
|
namespace :test do
|
453
191
|
task :install do
|
454
192
|
gemspec_helper = Rake.application.jeweler.gemspec_helper
|
data/ext/groonga/Makefile
CHANGED
@@ -60,7 +60,7 @@ warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwri
|
|
60
60
|
CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 -fPIC -Wall -I/tmp/local/include/groonga
|
61
61
|
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
62
62
|
DEFS =
|
63
|
-
CPPFLAGS = -DRB_GRN_COMPILATION -DGRN_MAJOR_VERSION=1 -DGRN_MINOR_VERSION=2 -DGRN_MICRO_VERSION=
|
63
|
+
CPPFLAGS = -DRB_GRN_COMPILATION -DGRN_MAJOR_VERSION=1 -DGRN_MINOR_VERSION=2 -DGRN_MICRO_VERSION=5 -DHAVE_RB_ERRINFO -DHAVE_TYPE_ENUM_RUBY_VALUE_TYPE $(DEFS) $(cppflags)
|
64
64
|
CXXFLAGS = $(CFLAGS) -fno-strict-aliasing -g
|
65
65
|
ldflags = -L. -rdynamic -Wl,-export-dynamic -L/tmp/local/lib
|
66
66
|
dldflags =
|
data/ext/groonga/extconf.rb
CHANGED
@@ -158,7 +158,9 @@ checking_for(checking_message("debug flag")) do
|
|
158
158
|
debug
|
159
159
|
end
|
160
160
|
|
161
|
-
|
162
|
-
$INSTALLFILES
|
161
|
+
if ENV["INSTALL_RB"] == "yes"
|
162
|
+
$INSTALLFILES ||= []
|
163
|
+
$INSTALLFILES << ["../../lib/**/*.rb", "$(RUBYLIBDIR)", "../../lib"]
|
164
|
+
end
|
163
165
|
|
164
166
|
create_makefile(module_name)
|
data/ext/groonga/rb-grn-array.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby" -*- */
|
2
2
|
/*
|
3
|
-
Copyright (C) 2009-
|
3
|
+
Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
|
5
5
|
This library is free software; you can redistribute it and/or
|
6
6
|
modify it under the terms of the GNU Lesser General Public
|
@@ -192,10 +192,11 @@ rb_grn_array_add (int argc, VALUE *argv, VALUE self)
|
|
192
192
|
id = grn_table_add(context, table, NULL, 0, NULL);
|
193
193
|
rb_grn_context_check(context, self);
|
194
194
|
|
195
|
-
if (GRN_ID_NIL == id)
|
195
|
+
if (GRN_ID_NIL == id) {
|
196
196
|
return Qnil;
|
197
|
-
else
|
198
|
-
return
|
197
|
+
} else {
|
198
|
+
return rb_grn_record_new_added(self, id, values);
|
199
|
+
}
|
199
200
|
}
|
200
201
|
|
201
202
|
void
|
@@ -59,27 +59,12 @@ rb_grn_context_from_ruby_object (VALUE object)
|
|
59
59
|
return rb_grn_context->context;
|
60
60
|
}
|
61
61
|
|
62
|
-
static void
|
63
|
-
rb_grn_context_unlink_database (grn_ctx *context)
|
64
|
-
{
|
65
|
-
grn_obj *database;
|
66
|
-
|
67
|
-
database = grn_ctx_db(context);
|
68
|
-
debug("context:database: %p:%p\n", context, database);
|
69
|
-
if (database && database->header.type == GRN_DB) {
|
70
|
-
debug("context:database: %p:%p: unlink\n", context, database);
|
71
|
-
grn_obj_unlink(context, database);
|
72
|
-
}
|
73
|
-
debug("context:database: %p:%p: done\n", context, database);
|
74
|
-
}
|
75
|
-
|
76
62
|
void
|
77
63
|
rb_grn_context_fin (grn_ctx *context)
|
78
64
|
{
|
79
65
|
if (context->stat == GRN_CTX_FIN)
|
80
66
|
return;
|
81
67
|
|
82
|
-
rb_grn_context_unlink_database(context);
|
83
68
|
grn_ctx_fin(context);
|
84
69
|
}
|
85
70
|
|
@@ -122,8 +107,6 @@ rb_grn_context_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
|
|
122
107
|
|
123
108
|
rb_grn_context->context = NULL;
|
124
109
|
|
125
|
-
rb_grn_context_unlink_database(context);
|
126
|
-
|
127
110
|
debug("context-finalize: %p:%p:%p: done\n",
|
128
111
|
context, rb_grn_context, rb_grn_context->context);
|
129
112
|
|
@@ -315,7 +298,7 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
|
|
315
298
|
{
|
316
299
|
RbGrnContext *rb_grn_context;
|
317
300
|
grn_ctx *context;
|
318
|
-
int flags =
|
301
|
+
int flags = GRN_CTX_PER_DB;
|
319
302
|
VALUE options, default_options;
|
320
303
|
VALUE rb_encoding;
|
321
304
|
|
@@ -369,10 +352,12 @@ rb_grn_context_close (VALUE self)
|
|
369
352
|
RbGrnContext *rb_grn_context;
|
370
353
|
|
371
354
|
context = SELF(self);
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
355
|
+
if (context) {
|
356
|
+
rc = grn_ctx_fin(context);
|
357
|
+
Data_Get_Struct(self, RbGrnContext, rb_grn_context);
|
358
|
+
rb_grn_context->context = NULL;
|
359
|
+
rb_grn_rc_check(rc, self);
|
360
|
+
}
|
376
361
|
|
377
362
|
return Qnil;
|
378
363
|
}
|
@@ -195,7 +195,7 @@ rb_grn_database_s_create (int argc, VALUE *argv, VALUE klass)
|
|
195
195
|
grn_obj_unlink(context, old_database);
|
196
196
|
database = grn_db_create(context, path, &create_args);
|
197
197
|
rb_grn_context_check(context, rb_ary_new4(argc, argv));
|
198
|
-
rb_database = GRNOBJECT2RVAL(klass, context, database,
|
198
|
+
rb_database = GRNOBJECT2RVAL(klass, context, database, GRN_FALSE);
|
199
199
|
rb_iv_set(rb_database, "@context", rb_context);
|
200
200
|
if (!NIL_P(rb_context))
|
201
201
|
rb_iv_set(rb_context, "database", rb_database);
|
@@ -504,6 +504,47 @@ rb_grn_database_touch (VALUE self)
|
|
504
504
|
return Qnil;
|
505
505
|
}
|
506
506
|
|
507
|
+
/*
|
508
|
+
* Document-method: defrag
|
509
|
+
*
|
510
|
+
* call-seq:
|
511
|
+
* database.defrag(options={}) -> n_segments
|
512
|
+
*
|
513
|
+
* Defrags all variable size columns in the database.
|
514
|
+
*
|
515
|
+
* @return [Integer] the number of defraged segments
|
516
|
+
* @option options [Integer] :threshold (0) the threshold to
|
517
|
+
* determine whether a segment is defraged. Available
|
518
|
+
* values are -4..22. -4 means all segments are defraged.
|
519
|
+
* 22 means no segment is defraged.
|
520
|
+
* @since 1.2.6
|
521
|
+
*/
|
522
|
+
static VALUE
|
523
|
+
rb_grn_database_defrag (int argc, VALUE *argv, VALUE self)
|
524
|
+
{
|
525
|
+
RbGrnColumn *rb_grn_column;
|
526
|
+
grn_ctx *context;
|
527
|
+
grn_obj *database;
|
528
|
+
int n_segments;
|
529
|
+
VALUE options, rb_threshold;
|
530
|
+
int threshold = 0;
|
531
|
+
|
532
|
+
rb_scan_args(argc, argv, "01", &options);
|
533
|
+
rb_grn_scan_options(options,
|
534
|
+
"threshold", &rb_threshold,
|
535
|
+
NULL);
|
536
|
+
if (!NIL_P(rb_threshold)) {
|
537
|
+
threshold = NUM2INT(rb_threshold);
|
538
|
+
}
|
539
|
+
|
540
|
+
rb_grn_database_deconstruct(SELF(self), &database, &context,
|
541
|
+
NULL, NULL, NULL, NULL);
|
542
|
+
n_segments = grn_obj_defrag(context, database, threshold);
|
543
|
+
rb_grn_context_check(context, self);
|
544
|
+
|
545
|
+
return INT2NUM(n_segments);
|
546
|
+
}
|
547
|
+
|
507
548
|
void
|
508
549
|
rb_grn_init_database (VALUE mGrn)
|
509
550
|
{
|
@@ -534,4 +575,5 @@ rb_grn_init_database (VALUE mGrn)
|
|
534
575
|
rb_define_method(rb_cGrnDatabase, "locked?", rb_grn_database_is_locked, 0);
|
535
576
|
|
536
577
|
rb_define_method(rb_cGrnDatabase, "touch", rb_grn_database_touch, 0);
|
578
|
+
rb_define_method(rb_cGrnDatabase, "defrag", rb_grn_database_defrag, -1);
|
537
579
|
}
|
@@ -276,6 +276,7 @@ resolve_source_id (grn_ctx *context, grn_obj *column, grn_id range_id,
|
|
276
276
|
source_id = NUM2UINT(rb_source);
|
277
277
|
} else {
|
278
278
|
grn_obj *source;
|
279
|
+
grn_bool need_source_unlink = GRN_FALSE;
|
279
280
|
|
280
281
|
if (TYPE(rb_source) == T_STRING) {
|
281
282
|
grn_obj *table;
|
@@ -304,6 +305,7 @@ resolve_source_id (grn_ctx *context, grn_obj *column, grn_id range_id,
|
|
304
305
|
name = dot_point + 1;
|
305
306
|
}
|
306
307
|
source = grn_obj_column(context, table, name, length);
|
308
|
+
need_source_unlink = GRN_TRUE;
|
307
309
|
} else {
|
308
310
|
source = RVAL2GRNOBJECT(rb_source, &context);
|
309
311
|
}
|
@@ -321,6 +323,9 @@ resolve_source_id (grn_ctx *context, grn_obj *column, grn_id range_id,
|
|
321
323
|
} else {
|
322
324
|
source_id = grn_obj_id(context, source);
|
323
325
|
}
|
326
|
+
if (need_source_unlink) {
|
327
|
+
grn_obj_unlink(context, source);
|
328
|
+
}
|
324
329
|
}
|
325
330
|
|
326
331
|
return source_id;
|
data/ext/groonga/rb-grn-object.c
CHANGED
@@ -79,19 +79,13 @@ rb_grn_object_from_ruby_object (VALUE object, grn_ctx **context)
|
|
79
79
|
return rb_grn_object->object;
|
80
80
|
}
|
81
81
|
|
82
|
-
static
|
83
|
-
|
84
|
-
|
82
|
+
static void
|
83
|
+
rb_grn_object_run_finalizer (grn_ctx *context, grn_obj *grn_object,
|
84
|
+
RbGrnObject *rb_grn_object)
|
85
85
|
{
|
86
|
-
RbGrnObject *rb_grn_object;
|
87
|
-
grn_obj *grn_object = *grn_objects;
|
88
|
-
|
89
86
|
if (rb_grn_exited)
|
90
|
-
return
|
91
|
-
|
92
|
-
rb_grn_object = user_data->ptr;
|
87
|
+
return;
|
93
88
|
|
94
|
-
grn_obj_user_data(context, grn_object)->ptr = NULL;
|
95
89
|
grn_obj_set_finalizer(context, grn_object, NULL);
|
96
90
|
|
97
91
|
debug("finalize: %p:%p:%p:%p:%p 0x%x\n",
|
@@ -101,11 +95,10 @@ rb_grn_object_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
|
|
101
95
|
|
102
96
|
rb_grn_object->context = NULL;
|
103
97
|
rb_grn_object->object = NULL;
|
98
|
+
rb_grn_object->have_finalizer = GRN_FALSE;
|
104
99
|
|
105
100
|
switch (grn_object->header.type) {
|
106
101
|
case GRN_DB:
|
107
|
-
grn_ctx_use(context, NULL);
|
108
|
-
break;
|
109
102
|
case GRN_TYPE:
|
110
103
|
case GRN_PROC:
|
111
104
|
case GRN_CURSOR_TABLE_HASH_KEY:
|
@@ -148,6 +141,22 @@ rb_grn_object_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
|
|
148
141
|
grn_object->header.type);
|
149
142
|
break;
|
150
143
|
}
|
144
|
+
}
|
145
|
+
|
146
|
+
static grn_obj *
|
147
|
+
rb_grn_object_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
|
148
|
+
grn_user_data *user_data)
|
149
|
+
{
|
150
|
+
RbGrnObject *rb_grn_object;
|
151
|
+
grn_obj *grn_object = *grn_objects;
|
152
|
+
|
153
|
+
if (rb_grn_exited)
|
154
|
+
return NULL;
|
155
|
+
|
156
|
+
rb_grn_object = user_data->ptr;
|
157
|
+
|
158
|
+
grn_obj_user_data(context, grn_object)->ptr = NULL;
|
159
|
+
rb_grn_object_run_finalizer(context, grn_object, rb_grn_object);
|
151
160
|
|
152
161
|
return NULL;
|
153
162
|
}
|
@@ -160,19 +169,26 @@ rb_grn_object_free (RbGrnObject *rb_grn_object)
|
|
160
169
|
|
161
170
|
context = rb_grn_object->context;
|
162
171
|
grn_object = rb_grn_object->object;
|
163
|
-
debug("rb-free: %p:%p:%p; %d\n", context, grn_object, rb_grn_object,
|
164
|
-
rb_grn_object->have_finalizer);
|
165
|
-
if (!rb_grn_exited && context && grn_object &&
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
172
|
+
debug("rb-free: %p:%p:%p; %d:%d\n", context, grn_object, rb_grn_object,
|
173
|
+
rb_grn_object->have_finalizer, rb_grn_object->need_close);
|
174
|
+
if (!rb_grn_exited && context && grn_object &&
|
175
|
+
(rb_grn_object->have_finalizer || rb_grn_object->need_close)) {
|
176
|
+
grn_user_data *user_data = NULL;
|
177
|
+
|
178
|
+
if (rb_grn_object->have_finalizer) {
|
179
|
+
user_data = grn_obj_user_data(context, grn_object);
|
180
|
+
}
|
181
|
+
debug("type: %#x; need_close: %d; user_data: %p; ptr: %p\n",
|
170
182
|
grn_object->header.type,
|
171
183
|
rb_grn_object->need_close,
|
172
184
|
user_data,
|
173
185
|
user_data ? user_data->ptr : NULL);
|
174
|
-
if (
|
175
|
-
|
186
|
+
if (rb_grn_object->have_finalizer) {
|
187
|
+
if (user_data && user_data->ptr) {
|
188
|
+
rb_grn_object_finalizer(context, 1, &grn_object, user_data);
|
189
|
+
} else {
|
190
|
+
rb_grn_object_run_finalizer(context, grn_object, rb_grn_object);
|
191
|
+
}
|
176
192
|
}
|
177
193
|
if (rb_grn_object->need_close) {
|
178
194
|
grn_obj_unlink(context, grn_object);
|
@@ -297,15 +313,21 @@ rb_grn_object_bind_common (VALUE klass, VALUE self, VALUE rb_context,
|
|
297
313
|
|
298
314
|
user_data = grn_obj_user_data(context, object);
|
299
315
|
if (user_data) {
|
300
|
-
debug("set-finalizer: %p:%p:%p
|
316
|
+
debug("set-finalizer: %p:%p:%p %#x\n",
|
301
317
|
context, object, rb_grn_object,
|
302
318
|
object->header.type);
|
303
319
|
user_data->ptr = rb_grn_object;
|
304
320
|
grn_obj_set_finalizer(context, object, rb_grn_object_finalizer);
|
305
321
|
rb_grn_object->have_finalizer = GRN_TRUE;
|
322
|
+
} else if (object->header.type == GRN_ACCESSOR) {
|
323
|
+
debug("set-finalizer(implicit): %p:%p:%p %#x\n",
|
324
|
+
context, object, rb_grn_object,
|
325
|
+
object->header.type);
|
326
|
+
rb_grn_object->have_finalizer = GRN_TRUE;
|
306
327
|
}
|
307
328
|
|
308
329
|
switch (object->header.type) {
|
330
|
+
case GRN_DB:
|
309
331
|
case GRN_PROC:
|
310
332
|
case GRN_TYPE:
|
311
333
|
rb_grn_object->need_close = GRN_FALSE;
|
@@ -495,13 +517,17 @@ rb_grn_object_deconstruct (RbGrnObject *rb_grn_object,
|
|
495
517
|
VALUE
|
496
518
|
rb_grn_object_close (VALUE self)
|
497
519
|
{
|
520
|
+
RbGrnObject *rb_grn_object;
|
498
521
|
grn_obj *object;
|
499
522
|
grn_ctx *context;
|
500
523
|
|
501
|
-
|
524
|
+
rb_grn_object = SELF(self);
|
525
|
+
rb_grn_object_deconstruct(rb_grn_object, &object, &context,
|
502
526
|
NULL, NULL, NULL, NULL);
|
503
|
-
if (object && context)
|
527
|
+
if (object && context) {
|
528
|
+
rb_grn_object_run_finalizer(context, object, rb_grn_object);
|
504
529
|
grn_obj_close(context, object);
|
530
|
+
}
|
505
531
|
|
506
532
|
return Qnil;
|
507
533
|
}
|
@@ -517,13 +543,19 @@ rb_grn_object_close (VALUE self)
|
|
517
543
|
VALUE
|
518
544
|
rb_grn_object_unlink (VALUE self)
|
519
545
|
{
|
546
|
+
RbGrnObject *rb_grn_object;
|
520
547
|
grn_obj *object;
|
521
548
|
grn_ctx *context;
|
522
549
|
|
523
|
-
|
550
|
+
rb_grn_object = SELF(self);
|
551
|
+
rb_grn_object_deconstruct(rb_grn_object, &object, &context,
|
524
552
|
NULL, NULL, NULL, NULL);
|
525
|
-
if (object && context)
|
553
|
+
if (object && context) {
|
554
|
+
if (!(rb_grn_object->object->header.flags & GRN_OBJ_PERSISTENT)) {
|
555
|
+
rb_grn_object_run_finalizer(context, object, rb_grn_object);
|
556
|
+
}
|
526
557
|
grn_obj_unlink(context, object);
|
558
|
+
}
|
527
559
|
|
528
560
|
return Qnil;
|
529
561
|
}
|
@@ -798,6 +798,7 @@ rb_grn_patricia_trie_open_grn_near_cursor (int argc, VALUE *argv, VALUE self,
|
|
798
798
|
GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain);
|
799
799
|
if (key_p->header.domain != table->header.domain) {
|
800
800
|
grn_obj_cast(*context, key_p, &casted_key, 0);
|
801
|
+
grn_obj_unlink(*context, key_p);
|
801
802
|
key_p = &casted_key;
|
802
803
|
}
|
803
804
|
|
@@ -862,7 +863,7 @@ rb_grn_patricia_trie_open_near_cursor (int argc, VALUE *argv, VALUE self)
|
|
862
863
|
VALUE rb_cursor;
|
863
864
|
|
864
865
|
cursor = rb_grn_patricia_trie_open_grn_near_cursor(argc, argv,
|
865
|
-
|
866
|
+
self, &context, GRN_CURSOR_RK);
|
866
867
|
rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
|
867
868
|
rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
|
868
869
|
if (rb_block_given_p())
|
data/ext/groonga/rb-grn-record.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby" -*- */
|
2
2
|
/*
|
3
|
-
Copyright (C) 2009-
|
3
|
+
Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
|
5
5
|
This library is free software; you can redistribute it and/or
|
6
6
|
modify it under the terms of the GNU Lesser General Public
|
@@ -26,6 +26,16 @@ rb_grn_record_new (VALUE table, grn_id id, VALUE values)
|
|
26
26
|
return rb_grn_record_new_raw(table, UINT2NUM(id), values);
|
27
27
|
}
|
28
28
|
|
29
|
+
VALUE
|
30
|
+
rb_grn_record_new_added (VALUE table, grn_id id, VALUE values)
|
31
|
+
{
|
32
|
+
VALUE record;
|
33
|
+
|
34
|
+
record = rb_grn_record_new(table, id, values);
|
35
|
+
rb_funcall(record, rb_intern("added="), 1, Qtrue);
|
36
|
+
return record;
|
37
|
+
}
|
38
|
+
|
29
39
|
VALUE
|
30
40
|
rb_grn_record_new_raw (VALUE table, VALUE rb_id, VALUE values)
|
31
41
|
{
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby" -*- */
|
2
2
|
/*
|
3
|
-
Copyright (C) 2009-
|
3
|
+
Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
|
5
5
|
This library is free software; you can redistribute it and/or
|
6
6
|
modify it under the terms of the GNU Lesser General Public
|
@@ -88,7 +88,7 @@ rb_grn_table_key_support_bind (RbGrnTableKeySupport *rb_grn_table_key_support,
|
|
88
88
|
}
|
89
89
|
|
90
90
|
static grn_id
|
91
|
-
rb_grn_table_key_support_add_raw (VALUE self, VALUE rb_key)
|
91
|
+
rb_grn_table_key_support_add_raw (VALUE self, VALUE rb_key, int *added)
|
92
92
|
{
|
93
93
|
grn_ctx *context;
|
94
94
|
grn_obj *table;
|
@@ -103,7 +103,7 @@ rb_grn_table_key_support_add_raw (VALUE self, VALUE rb_key)
|
|
103
103
|
GRN_BULK_REWIND(key);
|
104
104
|
RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);
|
105
105
|
id = grn_table_add(context, table,
|
106
|
-
GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key),
|
106
|
+
GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key), added);
|
107
107
|
rb_grn_context_check(context, self);
|
108
108
|
|
109
109
|
return id;
|
@@ -116,6 +116,11 @@ rb_grn_table_key_support_add_raw (VALUE self, VALUE rb_key)
|
|
116
116
|
* 主キーが_key_のレコード追加し、追加したレコードを返す。レ
|
117
117
|
* コードの追加に失敗した場合は+nil+を返す。
|
118
118
|
*
|
119
|
+
* すでに同じキーのレコードが存在する場合は追加せずに同じレ
|
120
|
+
* コードを返す。追加されたかどうかは
|
121
|
+
* +Groonga::Record#added?+で調べることができる。+true+を返
|
122
|
+
* したら追加されたということを示す。
|
123
|
+
*
|
119
124
|
* _values_にはレコードのカラムに設定する値を指定する。省略
|
120
125
|
* した場合または+nil+を指定した場合はカラムは設定しない。カ
|
121
126
|
* ラムの値は<tt>{:カラム名1 => 値1, :カラム名2 => 値2,
|
@@ -126,13 +131,19 @@ rb_grn_table_key_support_add (int argc, VALUE *argv, VALUE self)
|
|
126
131
|
{
|
127
132
|
grn_id id;
|
128
133
|
VALUE key, values;
|
134
|
+
int added = GRN_FALSE;
|
129
135
|
|
130
136
|
rb_scan_args(argc, argv, "11", &key, &values);
|
131
|
-
id = rb_grn_table_key_support_add_raw(self, key);
|
132
|
-
if (GRN_ID_NIL == id)
|
137
|
+
id = rb_grn_table_key_support_add_raw(self, key, &added);
|
138
|
+
if (GRN_ID_NIL == id) {
|
133
139
|
return Qnil;
|
134
|
-
else
|
135
|
-
|
140
|
+
} else {
|
141
|
+
if (added) {
|
142
|
+
return rb_grn_record_new_added(self, id, values);
|
143
|
+
} else {
|
144
|
+
return rb_grn_record_new(self, id, values);
|
145
|
+
}
|
146
|
+
}
|
136
147
|
}
|
137
148
|
|
138
149
|
grn_id
|
@@ -364,7 +375,7 @@ rb_grn_table_key_support_array_set (VALUE self, VALUE rb_key, VALUE rb_values)
|
|
364
375
|
NULL, NULL, NULL,
|
365
376
|
NULL);
|
366
377
|
|
367
|
-
id = rb_grn_table_key_support_add_raw(self, rb_key);
|
378
|
+
id = rb_grn_table_key_support_add_raw(self, rb_key, NULL);
|
368
379
|
|
369
380
|
if (id == GRN_ID_NIL) {
|
370
381
|
rb_raise(rb_eGrnError,
|
@@ -409,7 +420,7 @@ rb_grn_table_key_support_set_column_value (int argc, VALUE *argv, VALUE self)
|
|
409
420
|
}
|
410
421
|
|
411
422
|
rb_key = rb_id_or_key;
|
412
|
-
id = rb_grn_table_key_support_add_raw(self, rb_key);
|
423
|
+
id = rb_grn_table_key_support_add_raw(self, rb_key, NULL);
|
413
424
|
if (id == GRN_ID_NIL) {
|
414
425
|
rb_raise(rb_eGrnError,
|
415
426
|
"failed to add record: %s",
|
@@ -533,7 +544,7 @@ rb_grn_table_key_support_set_value_by_key (VALUE self,
|
|
533
544
|
&value, NULL, NULL,
|
534
545
|
NULL);
|
535
546
|
|
536
|
-
id = rb_grn_table_key_support_add_raw(self, rb_key);
|
547
|
+
id = rb_grn_table_key_support_add_raw(self, rb_key, NULL);
|
537
548
|
if (GRN_ID_NIL == id) {
|
538
549
|
rb_raise(rb_eGrnError,
|
539
550
|
"failed to add new record with key: <%s>: <%s>",
|
data/ext/groonga/rb-grn-utils.c
CHANGED
@@ -243,6 +243,8 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
|
|
243
243
|
case T_NIL:
|
244
244
|
grn_obj_reinit(context, bulk, GRN_DB_VOID, 0);
|
245
245
|
break;
|
246
|
+
case T_SYMBOL:
|
247
|
+
object = rb_sym_to_s(object);
|
246
248
|
case T_STRING:
|
247
249
|
grn_obj_reinit(context, bulk, GRN_DB_TEXT, 0);
|
248
250
|
rb_grn_context_text_set(context, bulk, object);
|
@@ -306,7 +308,7 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
|
|
306
308
|
} else {
|
307
309
|
rb_raise(rb_eTypeError,
|
308
310
|
"bulked object should be one of "
|
309
|
-
"[nil, true, false, String, Integer, Float, Time, "
|
311
|
+
"[nil, true, false, String, Symbol, Integer, Float, Time, "
|
310
312
|
"Groonga::Object, Groonga::Record]: %s",
|
311
313
|
rb_grn_inspect(object));
|
312
314
|
}
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
#include "rb-grn.h"
|
20
20
|
|
21
|
-
#define SELF(object) ((
|
21
|
+
#define SELF(object) ((RbGrnColumn *)DATA_PTR(object))
|
22
22
|
|
23
23
|
VALUE rb_cGrnVariableSizeColumn;
|
24
24
|
|
@@ -28,9 +28,55 @@ VALUE rb_cGrnVariableSizeColumn;
|
|
28
28
|
* 可変長データ用のカラム。
|
29
29
|
*/
|
30
30
|
|
31
|
+
/*
|
32
|
+
* Document-method: defrag
|
33
|
+
*
|
34
|
+
* call-seq:
|
35
|
+
* column.defrag(options={}) -> n_segments
|
36
|
+
*
|
37
|
+
* Defrags the column.
|
38
|
+
*
|
39
|
+
* @return [Integer] the number of defraged segments
|
40
|
+
* @option options [Integer] :threshold (0) the threshold to
|
41
|
+
* determine whether a segment is defraged. Available
|
42
|
+
* values are -4..22. -4 means all segments are defraged.
|
43
|
+
* 22 means no segment is defraged.
|
44
|
+
* @since 1.2.6
|
45
|
+
*/
|
46
|
+
static VALUE
|
47
|
+
rb_grn_variable_size_column_defrag (int argc, VALUE *argv, VALUE self)
|
48
|
+
{
|
49
|
+
RbGrnColumn *rb_grn_column;
|
50
|
+
grn_ctx *context = NULL;
|
51
|
+
grn_obj *column;
|
52
|
+
int n_segments;
|
53
|
+
VALUE options, rb_threshold;
|
54
|
+
int threshold = 0;
|
55
|
+
|
56
|
+
rb_scan_args(argc, argv, "01", &options);
|
57
|
+
rb_grn_scan_options(options,
|
58
|
+
"threshold", &rb_threshold,
|
59
|
+
NULL);
|
60
|
+
if (!NIL_P(rb_threshold)) {
|
61
|
+
threshold = NUM2INT(rb_threshold);
|
62
|
+
}
|
63
|
+
|
64
|
+
rb_grn_column = SELF(self);
|
65
|
+
rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
|
66
|
+
NULL, NULL,
|
67
|
+
NULL, NULL);
|
68
|
+
n_segments = grn_obj_defrag(context, column, threshold);
|
69
|
+
rb_grn_context_check(context, self);
|
70
|
+
|
71
|
+
return INT2NUM(n_segments);
|
72
|
+
}
|
73
|
+
|
31
74
|
void
|
32
75
|
rb_grn_init_variable_size_column (VALUE mGrn)
|
33
76
|
{
|
34
77
|
rb_cGrnVariableSizeColumn =
|
35
78
|
rb_define_class_under(mGrn, "VariableSizeColumn", rb_cGrnColumn);
|
79
|
+
|
80
|
+
rb_define_method(rb_cGrnVariableSizeColumn, "defrag",
|
81
|
+
rb_grn_variable_size_column_defrag, -1);
|
36
82
|
}
|
data/ext/groonga/rb-grn.h
CHANGED
@@ -69,7 +69,7 @@ RB_GRN_BEGIN_DECLS
|
|
69
69
|
|
70
70
|
#define RB_GRN_MAJOR_VERSION 1
|
71
71
|
#define RB_GRN_MINOR_VERSION 2
|
72
|
-
#define RB_GRN_MICRO_VERSION
|
72
|
+
#define RB_GRN_MICRO_VERSION 6
|
73
73
|
|
74
74
|
#define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
|
75
75
|
|
@@ -474,6 +474,9 @@ VALUE rb_grn_posting_new (grn_posting *posting,
|
|
474
474
|
VALUE rb_grn_record_new (VALUE table,
|
475
475
|
grn_id id,
|
476
476
|
VALUE values);
|
477
|
+
VALUE rb_grn_record_new_added (VALUE table,
|
478
|
+
grn_id id,
|
479
|
+
VALUE values);
|
477
480
|
VALUE rb_grn_record_new_raw (VALUE table,
|
478
481
|
VALUE id,
|
479
482
|
VALUE values);
|
data/extconf.rb
CHANGED
@@ -34,6 +34,7 @@ Dir.chdir(source_ext_dir.to_s) do
|
|
34
34
|
end
|
35
35
|
ruby = "#{config['bindir']}/#{config['ruby_install_name']}#{config['EXEEXT']}"
|
36
36
|
message("checking in #{ext_dir}...\n")
|
37
|
+
ENV["INSTALL_RB"] = "yes"
|
37
38
|
system(ruby, (ext_dir + 'extconf.rb').to_s, *ARGV) or exit 1
|
38
39
|
message("checking in #{ext_dir}: done.\n")
|
39
40
|
File.open("Makefile") do |file|
|
data/lib/groonga/pagination.rb
CHANGED
@@ -78,7 +78,7 @@ module Groonga
|
|
78
78
|
# selected_entries = entries.select do |record|
|
79
79
|
# entry.description =~ query
|
80
80
|
# end
|
81
|
-
# paged_entries = selected_entries.paginate(["_score", :desc],
|
81
|
+
# paged_entries = selected_entries.paginate([["_score", :desc]],
|
82
82
|
# :page => 1,
|
83
83
|
# :size => 10)
|
84
84
|
#
|
data/lib/groonga/record.rb
CHANGED
@@ -32,6 +32,7 @@ module Groonga
|
|
32
32
|
def initialize(table, id, values=nil)
|
33
33
|
@table = table
|
34
34
|
@id = id
|
35
|
+
@added = false
|
35
36
|
if values
|
36
37
|
values.each do |name, value|
|
37
38
|
self[name] = value
|
@@ -380,6 +381,15 @@ module Groonga
|
|
380
381
|
super or !@table.column(name.to_s.sub(/=\z/, '')).nil?
|
381
382
|
end
|
382
383
|
|
384
|
+
def added?
|
385
|
+
@added
|
386
|
+
end
|
387
|
+
|
388
|
+
# @private
|
389
|
+
def added=(added)
|
390
|
+
@added = added
|
391
|
+
end
|
392
|
+
|
383
393
|
private
|
384
394
|
def normalize_column_name(name)
|
385
395
|
name.to_s
|
data/rroonga-build.rb
CHANGED
data/test/test-accessor.rb
CHANGED
data/test/test-array.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -91,4 +91,12 @@ class ArrayTest < Test::Unit::TestCase
|
|
91
91
|
users.set_column_value(morita_id, "name", "morita")
|
92
92
|
assert_equal("morita", users.column_value(morita_id, "name"))
|
93
93
|
end
|
94
|
+
|
95
|
+
def test_added?
|
96
|
+
users = Groonga::Array.create(:name => "Users")
|
97
|
+
first_user = users.add
|
98
|
+
assert_predicate(first_user, :added?)
|
99
|
+
second_user = users.add
|
100
|
+
assert_predicate(second_user, :added?)
|
101
|
+
end
|
94
102
|
end
|
data/test/test-database.rb
CHANGED
@@ -130,4 +130,20 @@ class DatabaseTest < Test::Unit::TestCase
|
|
130
130
|
database.touch
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
def test_defrag
|
135
|
+
setup_database
|
136
|
+
Groonga::Schema.define do |schema|
|
137
|
+
schema.create_table("Users") do |table|
|
138
|
+
table.short_text("name")
|
139
|
+
table.short_text("address")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
users = context["Users"]
|
143
|
+
1000.times do |i|
|
144
|
+
users.add(:name => "user #{i}" * 1000,
|
145
|
+
:address => "address #{i}" * 1000)
|
146
|
+
end
|
147
|
+
assert_equal(7, @database.defrag)
|
148
|
+
end
|
133
149
|
end
|
data/test/test-hash.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
#
|
2
|
+
#
|
3
|
+
# Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
3
4
|
#
|
4
5
|
# This library is free software; you can redistribute it and/or
|
5
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -75,7 +76,6 @@ class HashTest < Test::Unit::TestCase
|
|
75
76
|
assert_equal(bookmark, bookmarks["http://google.com/"])
|
76
77
|
end
|
77
78
|
|
78
|
-
|
79
79
|
def test_inspect_anonymous
|
80
80
|
path = @tables_dir + "anoymous.groonga"
|
81
81
|
anonymous_table = Groonga::Hash.create(:path => path.to_s)
|
@@ -308,4 +308,13 @@ class HashTest < Test::Unit::TestCase
|
|
308
308
|
}
|
309
309
|
end
|
310
310
|
end
|
311
|
+
|
312
|
+
def test_added?
|
313
|
+
users = Groonga::Hash.create(:name => "Users",
|
314
|
+
:key_type => "ShortText")
|
315
|
+
bob = users.add("bob")
|
316
|
+
assert_predicate(bob, :added?)
|
317
|
+
bob_again = users.add("bob")
|
318
|
+
assert_not_predicate(bob_again, :added?)
|
319
|
+
end
|
311
320
|
end
|
data/test/test-patricia-trie.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2009-
|
3
|
+
# Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -379,4 +379,13 @@ class PatriciaTrieTest < Test::Unit::TestCase
|
|
379
379
|
numbers.add(7)
|
380
380
|
assert_equal([1, 2, 5, 7], numbers.collect {|number| number.key})
|
381
381
|
end
|
382
|
+
|
383
|
+
def test_added?
|
384
|
+
users = Groonga::PatriciaTrie.create(:name => "Users",
|
385
|
+
:key_type => "ShortText")
|
386
|
+
bob = users.add("bob")
|
387
|
+
assert_predicate(bob, :added?)
|
388
|
+
bob_again = users.add("bob")
|
389
|
+
assert_not_predicate(bob_again, :added?)
|
390
|
+
end
|
382
391
|
end
|
data/test/test-table-select.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2009-
|
3
|
+
# Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -53,7 +53,7 @@ class TableSelectTest < Test::Unit::TestCase
|
|
53
53
|
:user => "darashi")
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
56
|
+
def test_sub_expression
|
57
57
|
result = @comments.select do |record|
|
58
58
|
record.match("Hello", "content") &
|
59
59
|
(record["created_at"] < Time.parse("2009-08-01"))
|
@@ -61,22 +61,22 @@ class TableSelectTest < Test::Unit::TestCase
|
|
61
61
|
assert_equal_select_result([@comment2], result)
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
64
|
+
def test_query
|
65
65
|
result = @comments.select("content:@Hello")
|
66
66
|
assert_equal_select_result([@comment1, @comment2], result)
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
69
|
+
def test_query_with_parser
|
70
70
|
result = @comments.select("content @ \"Hello\"", :syntax => :script)
|
71
71
|
assert_equal_select_result([@comment1, @comment2], result)
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
74
|
+
def test_query_with_default_column
|
75
75
|
result = @comments.select("Hello", {:default_column => 'content'})
|
76
76
|
assert_equal_select_result([@comment1, @comment2], result)
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def test_expression
|
80
80
|
expression = Groonga::Expression.new
|
81
81
|
variable = expression.define_variable(:domain => @comments)
|
82
82
|
expression.append_object(variable)
|
@@ -87,76 +87,90 @@ class TableSelectTest < Test::Unit::TestCase
|
|
87
87
|
assert_equal_select_result([@comment1, @comment2], result)
|
88
88
|
end
|
89
89
|
|
90
|
-
def
|
90
|
+
def test_query_with_block
|
91
91
|
result = @comments.select("content:@Hello") do |record|
|
92
92
|
record["created_at"] < Time.parse("2009-08-01")
|
93
93
|
end
|
94
94
|
assert_equal_select_result([@comment2], result)
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def test_query_with_block_match
|
98
98
|
result = @comments.select("content:@Hello") do |record|
|
99
99
|
record.match("World", "content")
|
100
100
|
end
|
101
101
|
assert_equal_select_result([@comment2], result)
|
102
102
|
end
|
103
103
|
|
104
|
-
def
|
104
|
+
def test_without_block
|
105
105
|
assert_equal_select_result([@comment1, @comment2,
|
106
106
|
@comment3, @japanese_comment],
|
107
107
|
@comments.select)
|
108
108
|
end
|
109
109
|
|
110
|
-
def
|
110
|
+
def test_query_japanese
|
111
111
|
result = @comments.select("content:@ボロTV")
|
112
112
|
assert_equal_select_result([@japanese_comment], result)
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
115
|
+
def test_but_query
|
116
116
|
result = @comments.select do |record|
|
117
117
|
record["content"].match "Hello -World"
|
118
118
|
end
|
119
119
|
assert_equal_select_result([@comment1], result)
|
120
120
|
end
|
121
121
|
|
122
|
-
def
|
122
|
+
def test_query_with_three_terms
|
123
123
|
result = @comments.select do |record|
|
124
124
|
record["content"].match "Say Hello World"
|
125
125
|
end
|
126
126
|
assert_equal_select_result([], result)
|
127
127
|
end
|
128
128
|
|
129
|
-
def
|
129
|
+
def test_query_with_brackets
|
130
130
|
result = @comments.select do |record|
|
131
131
|
record["content"].match "Say (Hello World)"
|
132
132
|
end
|
133
133
|
assert_equal_select_result([], result)
|
134
134
|
end
|
135
135
|
|
136
|
-
def
|
136
|
+
def test_equal_reference_column_by_key
|
137
137
|
result = @comments.select do |record|
|
138
138
|
record["user"] == "darashi"
|
139
139
|
end
|
140
140
|
assert_equal_select_result([@japanese_comment], result)
|
141
141
|
end
|
142
142
|
|
143
|
-
def
|
143
|
+
def test_not_equal_reference_column_by_key
|
144
144
|
result = @comments.select('user != "darashi"', :syntax => :script)
|
145
145
|
assert_equal_select_result([@comment1, @comment2, @comment3],
|
146
146
|
result)
|
147
147
|
end
|
148
148
|
|
149
|
-
def
|
149
|
+
def test_equal_reference_column_by_nonexistent_key
|
150
150
|
result = @comments.select do |record|
|
151
151
|
record["user"] == "nonexistent"
|
152
152
|
end
|
153
153
|
assert_equal_select_result([], result)
|
154
154
|
end
|
155
155
|
|
156
|
-
def
|
156
|
+
def test_query_key
|
157
157
|
result = @users.select do |record|
|
158
158
|
record["_key"] =~ "mori"
|
159
159
|
end
|
160
160
|
assert_equal_select_result([@users["morita"]], result)
|
161
161
|
end
|
162
|
+
|
163
|
+
def test_symbol
|
164
|
+
result = @comments.select do |record|
|
165
|
+
record[:content].match("Say Hello World")
|
166
|
+
end
|
167
|
+
assert_equal_select_result([], result)
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_method
|
171
|
+
result = @comments.select do |record|
|
172
|
+
record.content.match("Say Hello World")
|
173
|
+
end
|
174
|
+
assert_equal_select_result([], result)
|
175
|
+
end
|
162
176
|
end
|
data/test/test-type.rb
CHANGED
@@ -23,12 +23,12 @@ class TypeTest < Test::Unit::TestCase
|
|
23
23
|
assert_equal("user_id", type.name)
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def test_new_with_space_name
|
27
27
|
exception = assert_raise(Groonga::InvalidArgument) do
|
28
|
-
Groonga::Type.new("user
|
28
|
+
Groonga::Type.new("user id", :type => :integer)
|
29
29
|
end
|
30
30
|
message =
|
31
|
-
"name can't start with '_' and
|
31
|
+
"name can't start with '_' and contains only 0-9, A-Z, a-z, #, - or _"
|
32
32
|
assert_match(/#{Regexp.escape(message)}/,
|
33
33
|
exception.message)
|
34
34
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -107,4 +107,11 @@ class VariableSizeColumnTest < Test::Unit::TestCase
|
|
107
107
|
@morita.prepend("nick_names", "moritapo")
|
108
108
|
assert_equal(["moritapo", "morita"], @morita["nick_names"])
|
109
109
|
end
|
110
|
+
|
111
|
+
def test_defrag
|
112
|
+
1000.times do |i|
|
113
|
+
@users.add(:name => "user #{i}" * 1000)
|
114
|
+
end
|
115
|
+
assert_equal(3, @name.defrag)
|
116
|
+
end
|
110
117
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rroonga
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 6
|
10
|
+
version: 1.2.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kouhei Sutou
|
@@ -19,7 +19,7 @@ autorequire:
|
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
21
|
|
22
|
-
date: 2011-08-
|
22
|
+
date: 2011-08-28 00:00:00 Z
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
25
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -119,6 +119,20 @@ dependencies:
|
|
119
119
|
prerelease: false
|
120
120
|
type: :development
|
121
121
|
requirement: *id007
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
name: packnga
|
133
|
+
prerelease: false
|
134
|
+
type: :development
|
135
|
+
requirement: *id008
|
122
136
|
description: |-
|
123
137
|
rroonga is an extension library to use groonga's DB-API
|
124
138
|
layer. rroonga provides Rubyish readable and writable API
|