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 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
@@ -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=1 -DHAVE_RB_ERRINFO -DHAVE_TYPE_ENUM_RUBY_VALUE_TYPE $(DEFS) $(cppflags)
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 =
@@ -158,7 +158,9 @@ checking_for(checking_message("debug flag")) do
158
158
  debug
159
159
  end
160
160
 
161
- $INSTALLFILES ||= []
162
- $INSTALLFILES << ["../../lib/**/*.rb", "$(RUBYLIBDIR)", "../../lib"]
161
+ if ENV["INSTALL_RB"] == "yes"
162
+ $INSTALLFILES ||= []
163
+ $INSTALLFILES << ["../../lib/**/*.rb", "$(RUBYLIBDIR)", "../../lib"]
164
+ end
163
165
 
164
166
  create_makefile(module_name)
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
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 rb_grn_record_new(self, id, values);
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 = 0;
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
- rc = grn_ctx_fin(context);
373
- Data_Get_Struct(self, RbGrnContext, rb_grn_context);
374
- rb_grn_context->context = NULL;
375
- rb_grn_rc_check(rc, self);
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, GRN_TRUE);
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;
@@ -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 grn_obj *
83
- rb_grn_object_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
84
- grn_user_data *user_data)
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 NULL;
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 && rb_grn_object->have_finalizer) {
166
- grn_user_data *user_data;
167
-
168
- user_data = grn_obj_user_data(context, grn_object);
169
- debug("type: %x; need_close: %d; user_data: %p; ptr: %p\n",
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 (user_data && user_data->ptr) {
175
- rb_grn_object_finalizer(context, 1, &grn_object, user_data);
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 0x%x\n",
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
- rb_grn_object_deconstruct(SELF(self), &object, &context,
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
- rb_grn_object_deconstruct(SELF(self), &object, &context,
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
- self, &context, GRN_CURSOR_RK);
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())
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
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-2010 Kouhei Sutou <kou@clear-code.com>
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), NULL);
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
- return rb_grn_record_new(self, id, values);
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>",
@@ -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) ((RbGrnVariableSizeColumn *)DATA_PTR(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
  }
@@ -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 5
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|
@@ -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
  #
@@ -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
@@ -19,7 +19,7 @@ module RroongaBuild
19
19
  module RequiredGroongaVersion
20
20
  MAJOR = 1
21
21
  MINOR = 2
22
- MICRO = 2
22
+ MICRO = 5
23
23
  VERSION = [MAJOR, MINOR, MICRO]
24
24
  end
25
25
 
@@ -22,6 +22,10 @@ class AccessorTest < Test::Unit::TestCase
22
22
  @id = @posts.column("_id")
23
23
  end
24
24
 
25
+ def teardown
26
+ @id = nil
27
+ end
28
+
25
29
  def test_name
26
30
  assert_nil(@id.name)
27
31
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2010 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
@@ -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
@@ -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
@@ -1,5 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
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
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
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
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
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 test_select_sub_expression
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 test_select_query
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 test_select_query_with_parser
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 test_select_query_with_default_column
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 test_select_expression
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 test_select_query_with_block
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 test_select_query_with_block_match
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 test_select_without_block
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 test_select_query_japanese
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 test_select_but_query
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 test_select_query_with_three_terms
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 test_select_query_with_brackets
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 test_select_equal_reference_column_by_key
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 test_select_not_equal_reference_column_by_key
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 test_select_equal_reference_column_by_nonexistent_key
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 test_select_query_key
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
@@ -23,12 +23,12 @@ class TypeTest < Test::Unit::TestCase
23
23
  assert_equal("user_id", type.name)
24
24
  end
25
25
 
26
- def test_new_with_hyphen_name
26
+ def test_new_with_space_name
27
27
  exception = assert_raise(Groonga::InvalidArgument) do
28
- Groonga::Type.new("user-id", :type => :integer)
28
+ Groonga::Type.new("user id", :type => :integer)
29
29
  end
30
30
  message =
31
- "name can't start with '_' and 0-9, and contains only 0-9, A-Z, a-z, or _"
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: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 5
10
- version: 1.2.5
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-05 00:00:00 Z
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