rroonga 1.2.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/Gemfile +1 -0
  2. data/Rakefile +1 -0
  3. data/bin/grntest-log-analyze +123 -0
  4. data/bin/groonga-query-log-extract +117 -0
  5. data/ext/groonga/rb-grn-accessor.c +7 -5
  6. data/ext/groonga/rb-grn-array-cursor.c +1 -1
  7. data/ext/groonga/rb-grn-array.c +34 -44
  8. data/ext/groonga/rb-grn-column.c +74 -38
  9. data/ext/groonga/rb-grn-context.c +19 -15
  10. data/ext/groonga/rb-grn-database.c +47 -42
  11. data/ext/groonga/rb-grn-double-array-trie-cursor.c +40 -0
  12. data/ext/groonga/rb-grn-double-array-trie.c +530 -0
  13. data/ext/groonga/rb-grn-encoding-support.c +1 -1
  14. data/ext/groonga/rb-grn-encoding.c +1 -1
  15. data/ext/groonga/rb-grn-exception.c +1 -1
  16. data/ext/groonga/rb-grn-expression-builder.c +1 -1
  17. data/ext/groonga/rb-grn-expression.c +63 -51
  18. data/ext/groonga/rb-grn-fix-size-column.c +7 -7
  19. data/ext/groonga/rb-grn-hash-cursor.c +1 -1
  20. data/ext/groonga/rb-grn-hash.c +42 -39
  21. data/ext/groonga/rb-grn-index-column.c +35 -31
  22. data/ext/groonga/rb-grn-index-cursor.c +1 -1
  23. data/ext/groonga/rb-grn-logger.c +23 -18
  24. data/ext/groonga/rb-grn-object.c +40 -27
  25. data/ext/groonga/rb-grn-operator.c +1 -1
  26. data/ext/groonga/rb-grn-patricia-trie-cursor.c +1 -1
  27. data/ext/groonga/rb-grn-patricia-trie.c +122 -90
  28. data/ext/groonga/rb-grn-plugin.c +8 -7
  29. data/ext/groonga/rb-grn-posting.c +1 -1
  30. data/ext/groonga/rb-grn-procedure.c +1 -1
  31. data/ext/groonga/rb-grn-query.c +12 -12
  32. data/ext/groonga/rb-grn-record.c +1 -1
  33. data/ext/groonga/rb-grn-snippet.c +26 -19
  34. data/ext/groonga/rb-grn-table-cursor-key-support.c +1 -1
  35. data/ext/groonga/rb-grn-table-cursor.c +4 -3
  36. data/ext/groonga/rb-grn-table-key-support.c +23 -23
  37. data/ext/groonga/rb-grn-table.c +268 -153
  38. data/ext/groonga/rb-grn-type.c +11 -7
  39. data/ext/groonga/rb-grn-utils.c +4 -1
  40. data/ext/groonga/rb-grn-variable-size-column.c +1 -1
  41. data/ext/groonga/rb-grn-variable.c +2 -2
  42. data/ext/groonga/rb-grn-view-accessor.c +1 -1
  43. data/ext/groonga/rb-grn-view-cursor.c +1 -1
  44. data/ext/groonga/rb-grn-view-record.c +1 -1
  45. data/ext/groonga/rb-grn-view.c +43 -34
  46. data/ext/groonga/rb-grn.h +6 -2
  47. data/ext/groonga/rb-groonga.c +1 -1
  48. data/lib/groonga.rb +4 -2
  49. data/lib/groonga/context.rb +16 -41
  50. data/lib/groonga/dumper.rb +6 -4
  51. data/lib/groonga/expression-builder.rb +52 -26
  52. data/lib/groonga/grntest-log.rb +206 -0
  53. data/lib/groonga/pagination.rb +21 -19
  54. data/lib/groonga/patricia-trie.rb +7 -10
  55. data/lib/groonga/posting.rb +1 -1
  56. data/lib/groonga/query-log.rb +348 -0
  57. data/lib/groonga/record.rb +47 -143
  58. data/lib/groonga/schema.rb +679 -406
  59. data/lib/groonga/view-record.rb +4 -10
  60. data/rroonga-build.rb +1 -1
  61. data/test/test-array.rb +25 -4
  62. data/test/test-column.rb +8 -8
  63. data/test/test-database.rb +2 -3
  64. data/test/test-double-array-trie.rb +164 -0
  65. data/test/test-expression-builder.rb +2 -2
  66. data/test/test-expression.rb +10 -9
  67. data/test/test-gqtp.rb +2 -2
  68. data/test/test-hash.rb +32 -8
  69. data/test/test-patricia-trie.rb +34 -10
  70. data/test/test-query-log.rb +258 -0
  71. data/test/test-record.rb +6 -5
  72. data/test/test-schema-create-table.rb +8 -0
  73. data/test/test-schema.rb +491 -234
  74. data/test/test-table.rb +17 -24
  75. metadata +123 -100
  76. data/ext/groonga/Makefile +0 -233
@@ -17,22 +17,19 @@
17
17
 
18
18
  module Groonga
19
19
  class PatriciaTrie
20
- # call-seq:
21
- # patricia_trie.tag_keys(text, options={}) {|record, word| ...} -> String
22
- #
23
- # _text_を走査し、レコードのキーとマッチする部分文字列ごとに
24
- # そのレコードが_record_として、その部分文字列が_word_として、
20
+ # _text_ を走査し、レコードのキーとマッチする部分文字列ごとに
21
+ # そのレコードが _record_ として、その部分文字列が _word_ として、
25
22
  # ブロックが呼び出される。ブロックから返された文字列が元の部
26
23
  # 分文字列と置換される。全てのヒットに対してのその置換処理が
27
24
  # 行われた文字列が返される。
28
25
  #
29
- # _options_に指定可能な値は以下の通り。
26
+ # @param options [::Hash] The name and value
27
+ # pairs. Omitted names are initialized as the default value.
28
+ # @option options [Proc] :other_text_handler The other_text_handler
30
29
  #
31
- # [+:other_text_handler+]
32
- # マッチした部分文字列の前後の文字列を変換するProcを指
33
- # 定する。
30
+ # マッチした部分文字列の前後の文字列を変換するProcを指定する。
34
31
  #
35
- # 例:
32
+ # @example
36
33
  # include ERB::Util
37
34
  # Groonga::Context.default_options = {:encoding => "utf-8"}
38
35
  # words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
@@ -52,7 +52,7 @@ module Groonga
52
52
 
53
53
  # Updates all values.
54
54
  #
55
- # @param [Hash] parameters The name and value
55
+ # @param [::Hash] parameters The name and value
56
56
  # pairs. Omitted names are initialized as the default value.
57
57
  # @option parameters [Integer] :record_id The record_id.
58
58
  # @option parameters [Integer] :section_id The section_id.
@@ -0,0 +1,348 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "English"
19
+ require "shellwords"
20
+ require "cgi"
21
+
22
+ module Groonga
23
+ module QueryLog
24
+ class Command
25
+ class << self
26
+ @@registered_commands = {}
27
+ def register(name, klass)
28
+ @@registered_commands[name] = klass
29
+ end
30
+
31
+ def parse(input)
32
+ if input.start_with?("/d/")
33
+ parse_uri_path(input)
34
+ else
35
+ parse_command_line(input)
36
+ end
37
+ end
38
+
39
+ private
40
+ def parse_uri_path(path)
41
+ name, parameters_string = path.split(/\?/, 2)
42
+ parameters = {}
43
+ if parameters_string
44
+ parameters_string.split(/&/).each do |parameter_string|
45
+ key, value = parameter_string.split(/\=/, 2)
46
+ parameters[key] = CGI.unescape(value)
47
+ end
48
+ end
49
+ name = name.gsub(/\A\/d\//, '')
50
+ name, output_type = name.split(/\./, 2)
51
+ parameters["output_type"] = output_type if output_type
52
+ command_class = @@registered_commands[name] || self
53
+ command = command_class.new(name, parameters)
54
+ command.original_format = :uri
55
+ command
56
+ end
57
+
58
+ def parse_command_line(command_line)
59
+ name, *options = Shellwords.shellwords(command_line)
60
+ parameters = {}
61
+ options.each_slice(2) do |key, value|
62
+ parameters[key.gsub(/\A--/, '')] = value
63
+ end
64
+ command_class = @@registered_commands[name] || self
65
+ command = command_class.new(name, parameters)
66
+ command.original_format = :command
67
+ command
68
+ end
69
+ end
70
+
71
+ attr_reader :name, :parameters
72
+ attr_accessor :original_format
73
+ def initialize(name, parameters)
74
+ @name = name
75
+ @parameters = parameters
76
+ @original_format = nil
77
+ end
78
+
79
+ def ==(other)
80
+ other.is_a?(self.class) and
81
+ @name == other.name and
82
+ @parameters == other.parameters
83
+ end
84
+
85
+ def uri_format?
86
+ @original_format == :uri
87
+ end
88
+
89
+ def command_format?
90
+ @original_format == :command
91
+ end
92
+
93
+ def to_uri_format
94
+ path = "/d/#{@name}"
95
+ parameters = @parameters.dup
96
+ output_type = parameters.delete("output_type")
97
+ path << ".#{output_type}" if output_type
98
+ unless parameters.empty?
99
+ sorted_parameters = parameters.sort_by do |name, _|
100
+ name.to_s
101
+ end
102
+ uri_parameters = sorted_parameters.collect do |name, value|
103
+ "#{CGI.escape(name)}=#{CGI.escape(value)}"
104
+ end
105
+ path << "?"
106
+ path << uri_parameters.join("&")
107
+ end
108
+ path
109
+ end
110
+
111
+ def to_command_format
112
+ command_line = [@name]
113
+ sorted_parameters = @parameters.sort_by do |name, _|
114
+ name.to_s
115
+ end
116
+ sorted_parameters.each do |name, value|
117
+ escaped_value = value.gsub(/[\n"\\]/) do
118
+ special_character = $MATCH
119
+ case special_character
120
+ when "\n"
121
+ "\\n"
122
+ else
123
+ "\\#{special_character}"
124
+ end
125
+ end
126
+ command_line << "--#{name}"
127
+ command_line << "\"#{escaped_value}\""
128
+ end
129
+ command_line.join(" ")
130
+ end
131
+ end
132
+
133
+ class SelectCommand < Command
134
+ register("select", self)
135
+
136
+ def sortby
137
+ @parameters["sortby"]
138
+ end
139
+
140
+ def scorer
141
+ @parameters["scorer"]
142
+ end
143
+
144
+ def query
145
+ @parameters["query"]
146
+ end
147
+
148
+ def filter
149
+ @parameters["filter"]
150
+ end
151
+
152
+ def conditions
153
+ @conditions ||= filter.split(/(?:&&|&!|\|\|)/).collect do |condition|
154
+ condition = condition.strip
155
+ condition = condition.gsub(/\A[\s\(]*/, '')
156
+ condition = condition.gsub(/[\s\)]*\z/, '') unless /\(/ =~ condition
157
+ condition
158
+ end
159
+ end
160
+
161
+ def drilldowns
162
+ @drilldowns ||= (@parameters["drilldown"] || "").split(/\s*,\s*/)
163
+ end
164
+
165
+ def output_columns
166
+ @parameters["output_columns"]
167
+ end
168
+ end
169
+
170
+ class Statistic
171
+ attr_reader :context_id, :start_time, :raw_command
172
+ attr_reader :elapsed, :return_code
173
+ attr_accessor :slow_operation_threshold, :slow_response_threshold
174
+ def initialize(context_id)
175
+ @context_id = context_id
176
+ @start_time = nil
177
+ @command = nil
178
+ @raw_command = nil
179
+ @operations = []
180
+ @elapsed = nil
181
+ @return_code = 0
182
+ @slow_operation_threshold = 0.1
183
+ @slow_response_threshold = 0.2
184
+ end
185
+
186
+ def start(start_time, command)
187
+ @start_time = start_time
188
+ @raw_command = command
189
+ end
190
+
191
+ def finish(elapsed, return_code)
192
+ @elapsed = elapsed
193
+ @return_code = return_code
194
+ end
195
+
196
+ def command
197
+ @command ||= Command.parse(@raw_command)
198
+ end
199
+
200
+ def elapsed_in_seconds
201
+ nano_seconds_to_seconds(@elapsed)
202
+ end
203
+
204
+ def last_time
205
+ @start_time + elapsed_in_seconds
206
+ end
207
+
208
+ def slow?
209
+ elapsed_in_seconds >= @slow_response_threshold
210
+ end
211
+
212
+ def each_operation
213
+ previous_elapsed = 0
214
+ ensure_parse_command
215
+ operation_context_context = {
216
+ :filter_index => 0,
217
+ :drilldown_index => 0,
218
+ }
219
+ @operations.each_with_index do |operation, i|
220
+ relative_elapsed = operation[:elapsed] - previous_elapsed
221
+ relative_elapsed_in_seconds = nano_seconds_to_seconds(relative_elapsed)
222
+ previous_elapsed = operation[:elapsed]
223
+ parsed_operation = {
224
+ :i => i,
225
+ :elapsed => operation[:elapsed],
226
+ :elapsed_in_seconds => nano_seconds_to_seconds(operation[:elapsed]),
227
+ :relative_elapsed => relative_elapsed,
228
+ :relative_elapsed_in_seconds => relative_elapsed_in_seconds,
229
+ :name => operation[:name],
230
+ :context => operation_context(operation[:name],
231
+ operation_context_context),
232
+ :n_records => operation[:n_records],
233
+ :slow? => slow_operation?(relative_elapsed_in_seconds),
234
+ }
235
+ yield parsed_operation
236
+ end
237
+ end
238
+
239
+ def add_operation(operation)
240
+ @operations << operation
241
+ end
242
+
243
+ def operations
244
+ _operations = []
245
+ each_operation do |operation|
246
+ _operations << operation
247
+ end
248
+ _operations
249
+ end
250
+
251
+ def select_command?
252
+ command.name == "select"
253
+ end
254
+
255
+ private
256
+ def nano_seconds_to_seconds(nano_seconds)
257
+ nano_seconds / 1000.0 / 1000.0 / 1000.0
258
+ end
259
+
260
+ def operation_context(label, context)
261
+ case label
262
+ when "filter"
263
+ if @select_command.query and context[:query_used].nil?
264
+ context[:query_used] = true
265
+ "query: #{@select_command.query}"
266
+ else
267
+ index = context[:filter_index]
268
+ context[:filter_index] += 1
269
+ @select_command.conditions[index]
270
+ end
271
+ when "sort"
272
+ @select_command.sortby
273
+ when "score"
274
+ @select_command.scorer
275
+ when "output"
276
+ @select_command.output_columns
277
+ when "drilldown"
278
+ index = context[:drilldown_index]
279
+ context[:drilldown_index] += 1
280
+ @select_command.drilldowns[index]
281
+ else
282
+ nil
283
+ end
284
+ end
285
+
286
+ def ensure_parse_command
287
+ return unless select_command?
288
+ @select_command = SelectCommand.parse(@raw_command)
289
+ end
290
+
291
+ def slow_operation?(elapsed)
292
+ elapsed >= @slow_operation_threshold
293
+ end
294
+ end
295
+
296
+ class Parser
297
+ def initialize
298
+ end
299
+
300
+ def parse(input, &block)
301
+ current_statistics = {}
302
+ input.each_line do |line|
303
+ case line
304
+ when /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\.(\d+)\|(.+?)\|([>:<])/
305
+ year, month, day, hour, minutes, seconds, micro_seconds =
306
+ $1, $2, $3, $4, $5, $6, $7
307
+ context_id = $8
308
+ type = $9
309
+ rest = $POSTMATCH.strip
310
+ time_stamp = Time.local(year, month, day, hour, minutes, seconds,
311
+ micro_seconds)
312
+ parse_line(current_statistics,
313
+ time_stamp, context_id, type, rest, &block)
314
+ end
315
+ end
316
+ end
317
+
318
+ private
319
+ def parse_line(current_statistics,
320
+ time_stamp, context_id, type, rest, &block)
321
+ case type
322
+ when ">"
323
+ statistic = Statistic.new(context_id)
324
+ statistic.start(time_stamp, rest)
325
+ current_statistics[context_id] = statistic
326
+ when ":"
327
+ return unless /\A(\d+) (.+)\((\d+)\)/ =~ rest
328
+ elapsed = $1
329
+ name = $2
330
+ n_records = $3.to_i
331
+ statistic = current_statistics[context_id]
332
+ return if statistic.nil?
333
+ statistic.add_operation(:name => name,
334
+ :elapsed => elapsed.to_i,
335
+ :n_records => n_records)
336
+ when "<"
337
+ return unless /\A(\d+) rc=(\d+)/ =~ rest
338
+ elapsed = $1
339
+ return_code = $2
340
+ statistic = current_statistics.delete(context_id)
341
+ return if statistic.nil?
342
+ statistic.finish(elapsed.to_i, return_code.to_i)
343
+ block.call(statistic)
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
@@ -21,7 +21,7 @@ module Groonga
21
21
  class Record
22
22
  # レコードが所属するテーブル
23
23
  attr_reader :table
24
- # _table_の_id_に対応するレコードを作成する。_values_には各
24
+ # _table_ _id_ に対応するレコードを作成する。_values_ には各
25
25
  # カラムに設定する値を以下のような形式で指定する。
26
26
  #
27
27
  # [
@@ -40,141 +40,96 @@ module Groonga
40
40
  end
41
41
  end
42
42
 
43
- # call-seq:
44
- # record == other -> true/false
45
- #
46
- # _record_と_other_が同じテーブルに属していて、さらに、
47
- # 同じレコードIDを持つなら+true+を返し、そうでなければ
48
- # +false+を返す。
43
+ # _record_ と _other_ が同じテーブルに属していて、さらに、
44
+ # 同じレコードIDを持つなら +true+ を返し、そうでなければ
45
+ # +false+ を返す。
49
46
  def ==(other)
50
47
  self.class == other.class and
51
48
  [table, id] == [other.table, other.id]
52
49
  end
53
50
 
54
- # call-seq:
55
- # record.eql?(other) -> true/false
56
- #
57
51
  # Groonga::Record#==と同じ。
58
52
  def eql?(other)
59
53
  self == other
60
54
  end
61
55
 
62
- # call-seq:
63
- # record.hash -> ハッシュ値
64
- #
65
56
  # 同じテーブルの同じIDのレコードに対しては常に同じハッシュ
66
57
  # 値を返す。
67
58
  def hash
68
59
  @table.hash ^ @id.hash
69
60
  end
70
61
 
71
- # call-seq:
72
- # record[column_name] -> 値
73
- #
74
- # このレコードの_column_name_で指定されたカラムの値を返す。
62
+ # このレコードの _column_name_ で指定されたカラムの値を返す。
75
63
  def [](column_name)
76
64
  @table.column_value(@id, column_name, :id => true)
77
65
  end
78
66
 
79
- # call-seq:
80
- # record[column_name] = 値
81
- #
82
- # このレコードの_column_name_で指定されたカラムの値を設定す
67
+ # このレコードの _column_name_ で指定されたカラムの値を設定す
83
68
  # る。
84
69
  def []=(column_name, value)
85
70
  @table.set_column_value(@id, column_name, value, :id => true)
86
71
  end
87
72
 
88
- # call-seq:
89
- # record.append(column_name, value)
90
- #
91
- # このレコードの_column_name_で指定されたカラムの値の最後に
92
- # _value_を追加する。
73
+ # このレコードの _column_name_ で指定されたカラムの値の最後に
74
+ # _value_ を追加する。
93
75
  def append(column_name, value)
94
76
  column(column_name).append(@id, value)
95
77
  end
96
78
 
97
- # call-seq:
98
- # record.prepend(column_name, value)
99
- #
100
- # このレコードの_column_name_で指定されたカラムの値の最初に
101
- # _value_を追加する。
79
+ # このレコードの _column_name_ で指定されたカラムの値の最初に
80
+ # _value_ を追加する。
102
81
  def prepend(column_name, value)
103
82
  column(column_name).prepend(@id, value)
104
83
  end
105
84
 
106
- # call-seq:
107
- # record.support_key? -> true/false
108
- #
109
- # _record_が所属するテーブルで主キーを使える場合は+true+
110
- # を返し、使えない場合は+false+を返す。
85
+ # _record_ が所属するテーブルで主キーを使える場合は +true+
86
+ # を返し、使えない場合は +false+ を返す。
111
87
  def support_key?
112
88
  @table.support_key?
113
89
  end
114
90
 
115
- # call-seq:
116
- # record.have_column?(name) -> true/false
117
- #
118
- # 名前が_name_のカラムがレコードの所属するテーブルで定義され
119
- # ているなら+true+を返す。
91
+ # 名前が _name_ のカラムがレコードの所属するテーブルで定義され
92
+ # ているなら +true+ を返す。
120
93
  def have_column?(name)
121
94
  not @table.column(normalize_column_name(name)).nil?
122
95
  end
123
96
 
124
- # call-seq:
125
- # record.reference_column?(name) -> true/false
126
- #
127
- # 名前が_name_のカラムが参照カラムであるなら+true+を返す。
97
+ # 名前が _name_ のカラムが参照カラムであるなら +true+ を返す。
128
98
  def reference_column?(name)
129
99
  column(name).reference?
130
100
  end
131
101
 
132
- # call-seq:
133
- # record.index_column?(name) -> true/false
134
- #
135
- # 名前が_name_のカラムが索引カラム
136
- # (Groonga::IndexColumn)であるなら+true+を返す。
102
+ # 名前が _name_ のカラムが索引カラム
103
+ # (Groonga::IndexColumn)であるなら +true+ を返す。
137
104
  def index_column?(name)
138
105
  column(name).index?
139
106
  end
140
107
 
141
- # call-seq:
142
- # record.vector_column?(name) -> true/false
143
- #
144
- # 名前が_name_のカラムの値がベクターであるなら+true+を返す。
108
+ # 名前が _name_ のカラムの値がベクターであるなら +true+ を返す。
145
109
  #
146
110
  # @since: 1.0.5
147
111
  def vector_column?(name)
148
112
  column(name).vector?
149
113
  end
150
114
 
151
- # call-seq:
152
- # record.scalar_column?(name) -> true/false
153
- #
154
- # 名前が_name_のカラムの値がスカラーであるなら+true+を返す。
115
+ # 名前が _name_ のカラムの値がスカラーであるなら +true+ を返す。
155
116
  #
156
117
  # @since: 1.0.5
157
118
  def scalar_column?(name)
158
119
  column(name).scalar?
159
120
  end
160
121
 
161
- # call-seq:
162
- # record.search(name, query, options={}) -> Groonga::Hash
163
- #
164
- # 名前が_name_のGroonga::IndexColumnのsearchメソッドを呼ぶ。
165
- # _query_と_options_はそのメソッドにそのまま渡される。詳しく
122
+ # 名前が _name_ のGroonga::IndexColumnの search メソッドを呼ぶ。
123
+ # _query_ _options_ はそのメソッドにそのまま渡される。詳しく
166
124
  # はGroonga::IndexColumn#searchを参照。
167
125
  def search(name, query, options={})
168
126
  column(name).search(query, options)
169
127
  end
170
128
 
171
- # call-seq:
172
- # record.key -> 主キー
173
- #
174
129
  # レコードの主キーを返す。
175
130
  #
176
- # _record_が所属するテーブルがGroonga:::Arrayの場合は常
177
- # に+nil+を返す。
131
+ # _record_ が所属するテーブルがGroonga:::Arrayの場合は常
132
+ # に +nil+ を返す。
178
133
  def key
179
134
  if support_key?
180
135
  @key ||= @table.key(@id)
@@ -182,13 +137,9 @@ module Groonga
182
137
  nil
183
138
  end
184
139
  end
185
-
186
- # call-seq:
187
- # record.record_id -> IDまたは主キー
188
- #
189
140
  # レコードを一意に識別するための情報を返す。
190
141
  #
191
- # _record_が所属するテーブルがGroonga:::Arrayの場合はID
142
+ # _record_ が所属するテーブルがGroonga:::Arrayの場合はID
192
143
  # を返し、それ以外の場合は主キーを返す。
193
144
  def record_id
194
145
  if support_key?
@@ -198,36 +149,24 @@ module Groonga
198
149
  end
199
150
  end
200
151
 
201
- # call-seq:
202
- # record.record_raw_id -> ID
203
- #
204
152
  # レコードのIDを返す。
205
153
  def record_raw_id
206
154
  @id
207
155
  end
208
156
  alias_method :id, :record_raw_id
209
157
 
210
- # call-seq:
211
- # record.score -> スコア値
212
- #
213
158
  # レコードのスコア値を返す。検索結果として生成されたテーブル
214
159
  # のみに定義される。
215
160
  def score
216
161
  self["_score"]
217
162
  end
218
163
 
219
- # call-seq:
220
- # record.support_score? -> true/false
221
- #
222
- # Groonga::Record#scoreが利用できる場合はtrueを
164
+ # Groonga::Record#scoreが利用できる場合は +true+ を
223
165
  # 返す。
224
166
  def support_score?
225
167
  @table.have_column?("_score") # TODO delegate to Table
226
168
  end
227
169
 
228
- # call-seq:
229
- # record.n_sub_records -> 件数
230
- #
231
170
  # 主キーの値が同一であったレコードの件数を返す。検索結果とし
232
171
  # て生成されたテーブルのみに定義される。
233
172
  #
@@ -237,60 +176,39 @@ module Groonga
237
176
  self["_nsubrecs"]
238
177
  end
239
178
 
240
- # call-seq:
241
- # record.support_sub_records? -> true/false
242
- #
243
- # Groonga::Record#n_sub_recordsが利用できる場合はtrueを
179
+ # Groonga::Record#n_sub_recordsが利用できる場合は +true+ を
244
180
  # 返す。
245
181
  def support_sub_records?
246
182
  @table.support_sub_records?
247
183
  end
248
184
 
249
- # call-seq:
250
- # record.value -> 値
251
- #
252
185
  # レコードの値を返す。
253
186
  def value
254
187
  @table.value(@id, :id => true)
255
188
  end
256
189
 
257
- # call-seq:
258
- # record.value = 値
259
- #
260
190
  # レコードの値を設定する。既存の値は上書きされる。
261
191
  def value=(value)
262
192
  @table.set_value(@id, value, :id => true)
263
193
  end
264
194
 
265
- # call-seq:
266
- # record.increment!(name, delta=nil)
267
- #
268
- # このレコードの_name_で指定されたカラムの値を_delta_だけ増
269
- # 加する。_delta_が+nil+の場合は1増加する。
195
+ # このレコードの _name_ で指定されたカラムの値を _delta_ だけ増
196
+ # 加する。 _delta_ が +nil+ の場合は1増加する。
270
197
  def increment!(name, delta=nil)
271
198
  column(name).increment!(@id, delta)
272
199
  end
273
200
 
274
- # call-seq:
275
- # record.decrement!(name, delta=nil)
276
- #
277
- # このレコードの_name_で指定されたカラムの値を_delta_だけ減
278
- # 少する。_delta_が+nil+の場合は1減少する。
201
+ # このレコードの _name_ で指定されたカラムの値を _delta_ だけ減
202
+ # 少する。 _delta_ が +nil+ の場合は1減少する。
279
203
  def decrement!(name, delta=nil)
280
204
  column(name).decrement!(@id, delta)
281
205
  end
282
206
 
283
- # call-seq:
284
- # record.columns -> Groonga::Columnの配列
285
- #
286
207
  # レコードが所属するテーブルの全てのカラムを返す。
287
208
  def columns
288
209
  @table.columns
289
210
  end
290
211
 
291
- # call-seq:
292
- # attributes -> Hash
293
- #
294
212
  # レコードが所属しているテーブルで定義されているインデックス
295
213
  # 型のカラムでない全カラムを対象とし、カラムの名前をキーとし
296
214
  # たこのレコードのカラムの値のハッシュを返す。
@@ -301,36 +219,26 @@ module Groonga
301
219
  accessor.build
302
220
  end
303
221
 
304
- # call-seq:
305
- # record.delete
306
- #
307
222
  # レコードを削除する。
308
223
  def delete
309
224
  @table.delete(@id)
310
225
  end
311
226
 
312
- # call-seq:
313
- # record.lock(options={})
314
- # record.lock(options={}) {...}
315
- #
316
227
  # レコードが所属するテーブルをロックする。ロックに失敗した場
317
228
  # 合はGroonga::ResourceDeadlockAvoided例外が発生する。
318
229
  #
319
230
  # ブロックを指定した場合はブロックを抜けたときにunlockする。
320
231
  #
321
- # 利用可能なオプションは以下の通り。
322
- #
323
- # [_:timeout_]
324
- # ロックを獲得できなかった場合は_:timeout_秒間ロックの獲
325
- # 得を試みる。_:timeout_秒以内にロックを獲得できなかった
326
- # 場合は例外が発生する。
232
+ # 利用可能な _option_ は以下の通り。
233
+ # @param [Hash] options The name and value
234
+ # pairs. Omitted names are initialized as the default value.
235
+ # @option options [Integer] :timeout The timeout
236
+ # ロックを獲得できなかった場合は _:timeout_ 秒間ロックの獲得を試みる。
237
+ # _:timeout_ 秒以内にロックを獲得できなかった場合は例外が発生する。
327
238
  def lock(options={}, &block)
328
239
  @table.lock(options.merge(:id => @id), &block)
329
240
  end
330
241
 
331
- # call-seq:
332
- # record.unlock(options={})
333
- #
334
242
  # レコードが所属するテーブルのロックを解除する。
335
243
  #
336
244
  # 利用可能なオプションは現在は無い。
@@ -338,9 +246,6 @@ module Groonga
338
246
  @table.unlock(options.merge(:id => @id))
339
247
  end
340
248
 
341
- # call-seq:
342
- # record.clear_lock(options={})
343
- #
344
249
  # レコードが所属するテーブルのロックを強制的に解除する。
345
250
  #
346
251
  # 利用可能なオプションは現在は無い。
@@ -348,25 +253,20 @@ module Groonga
348
253
  @table.clear_lock(options.merge(:id => @id))
349
254
  end
350
255
 
351
- # call-seq:
352
- # record.locked?(options={}) -> true/false
353
- #
354
- # レコードが所属するテーブルがロックされていれば+true+を返す。
256
+ # レコードが所属するテーブルがロックされていれば +true+ を返す。
355
257
  #
356
258
  # 利用可能なオプションは現在は無い。
357
259
  def locked?(options={})
358
260
  @table.locked?(options.merge(:id => @id))
359
261
  end
360
262
 
361
- # call-seq:
362
- # record.valid_id? -> true/false
363
- #
364
- # レコードが持つIDが有効なIDであれば+true+を返す。
263
+ # レコードが持つIDが有効なIDであれば +true+ を返す。
365
264
  def valid_id?
366
265
  @table.exist?(@id)
367
266
  end
368
267
 
369
- def methods(include_inherited=true) # :nodoc:
268
+ # @private
269
+ def methods(include_inherited=true)
370
270
  _methods = super
371
271
  return _methods unless include_inherited
372
272
  columns.each do |column|
@@ -377,7 +277,8 @@ module Groonga
377
277
  _methods
378
278
  end
379
279
 
380
- def respond_to?(name) # :nodoc:
280
+ # @private
281
+ def respond_to?(name)
381
282
  super or !@table.column(name.to_s.sub(/=\z/, '')).nil?
382
283
  end
383
284
 
@@ -395,7 +296,8 @@ module Groonga
395
296
  name.to_s
396
297
  end
397
298
 
398
- def column(name) # :nodoc:
299
+ # @private
300
+ def column(name)
399
301
  _column = @table.column(normalize_column_name(name))
400
302
  raise NoSuchColumn, "column(#{name.inspect}) is nil" if _column.nil?
401
303
  _column
@@ -421,7 +323,8 @@ module Groonga
421
323
  end
422
324
  end
423
325
 
424
- class AttributeHashBuilder # :nodoc:
326
+ # @private
327
+ class AttributeHashBuilder
425
328
  attr_reader :attributes
426
329
 
427
330
  def initialize(root_record)
@@ -510,3 +413,4 @@ module Groonga
510
413
  end
511
414
  end
512
415
  end
416
+