rroonga 1.2.9 → 1.3.0
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/Gemfile +1 -0
- data/Rakefile +1 -0
- data/bin/grntest-log-analyze +123 -0
- data/bin/groonga-query-log-extract +117 -0
- data/ext/groonga/rb-grn-accessor.c +7 -5
- data/ext/groonga/rb-grn-array-cursor.c +1 -1
- data/ext/groonga/rb-grn-array.c +34 -44
- data/ext/groonga/rb-grn-column.c +74 -38
- data/ext/groonga/rb-grn-context.c +19 -15
- data/ext/groonga/rb-grn-database.c +47 -42
- data/ext/groonga/rb-grn-double-array-trie-cursor.c +40 -0
- data/ext/groonga/rb-grn-double-array-trie.c +530 -0
- data/ext/groonga/rb-grn-encoding-support.c +1 -1
- data/ext/groonga/rb-grn-encoding.c +1 -1
- data/ext/groonga/rb-grn-exception.c +1 -1
- data/ext/groonga/rb-grn-expression-builder.c +1 -1
- data/ext/groonga/rb-grn-expression.c +63 -51
- data/ext/groonga/rb-grn-fix-size-column.c +7 -7
- data/ext/groonga/rb-grn-hash-cursor.c +1 -1
- data/ext/groonga/rb-grn-hash.c +42 -39
- data/ext/groonga/rb-grn-index-column.c +35 -31
- data/ext/groonga/rb-grn-index-cursor.c +1 -1
- data/ext/groonga/rb-grn-logger.c +23 -18
- data/ext/groonga/rb-grn-object.c +40 -27
- data/ext/groonga/rb-grn-operator.c +1 -1
- data/ext/groonga/rb-grn-patricia-trie-cursor.c +1 -1
- data/ext/groonga/rb-grn-patricia-trie.c +122 -90
- data/ext/groonga/rb-grn-plugin.c +8 -7
- data/ext/groonga/rb-grn-posting.c +1 -1
- data/ext/groonga/rb-grn-procedure.c +1 -1
- data/ext/groonga/rb-grn-query.c +12 -12
- data/ext/groonga/rb-grn-record.c +1 -1
- data/ext/groonga/rb-grn-snippet.c +26 -19
- data/ext/groonga/rb-grn-table-cursor-key-support.c +1 -1
- data/ext/groonga/rb-grn-table-cursor.c +4 -3
- data/ext/groonga/rb-grn-table-key-support.c +23 -23
- data/ext/groonga/rb-grn-table.c +268 -153
- data/ext/groonga/rb-grn-type.c +11 -7
- data/ext/groonga/rb-grn-utils.c +4 -1
- data/ext/groonga/rb-grn-variable-size-column.c +1 -1
- data/ext/groonga/rb-grn-variable.c +2 -2
- data/ext/groonga/rb-grn-view-accessor.c +1 -1
- data/ext/groonga/rb-grn-view-cursor.c +1 -1
- data/ext/groonga/rb-grn-view-record.c +1 -1
- data/ext/groonga/rb-grn-view.c +43 -34
- data/ext/groonga/rb-grn.h +6 -2
- data/ext/groonga/rb-groonga.c +1 -1
- data/lib/groonga.rb +4 -2
- data/lib/groonga/context.rb +16 -41
- data/lib/groonga/dumper.rb +6 -4
- data/lib/groonga/expression-builder.rb +52 -26
- data/lib/groonga/grntest-log.rb +206 -0
- data/lib/groonga/pagination.rb +21 -19
- data/lib/groonga/patricia-trie.rb +7 -10
- data/lib/groonga/posting.rb +1 -1
- data/lib/groonga/query-log.rb +348 -0
- data/lib/groonga/record.rb +47 -143
- data/lib/groonga/schema.rb +679 -406
- data/lib/groonga/view-record.rb +4 -10
- data/rroonga-build.rb +1 -1
- data/test/test-array.rb +25 -4
- data/test/test-column.rb +8 -8
- data/test/test-database.rb +2 -3
- data/test/test-double-array-trie.rb +164 -0
- data/test/test-expression-builder.rb +2 -2
- data/test/test-expression.rb +10 -9
- data/test/test-gqtp.rb +2 -2
- data/test/test-hash.rb +32 -8
- data/test/test-patricia-trie.rb +34 -10
- data/test/test-query-log.rb +258 -0
- data/test/test-record.rb +6 -5
- data/test/test-schema-create-table.rb +8 -0
- data/test/test-schema.rb +491 -234
- data/test/test-table.rb +17 -24
- metadata +123 -100
- data/ext/groonga/Makefile +0 -233
| @@ -17,22 +17,19 @@ | |
| 17 17 |  | 
| 18 18 | 
             
            module Groonga
         | 
| 19 19 | 
             
              class PatriciaTrie
         | 
| 20 | 
            -
                #  | 
| 21 | 
            -
                # | 
| 22 | 
            -
                #
         | 
| 23 | 
            -
                # _text_を走査し、レコードのキーとマッチする部分文字列ごとに
         | 
| 24 | 
            -
                # そのレコードが_record_として、その部分文字列が_word_として、
         | 
| 20 | 
            +
                # _text_ を走査し、レコードのキーとマッチする部分文字列ごとに
         | 
| 21 | 
            +
                # そのレコードが _record_ として、その部分文字列が _word_ として、
         | 
| 25 22 | 
             
                # ブロックが呼び出される。ブロックから返された文字列が元の部
         | 
| 26 23 | 
             
                # 分文字列と置換される。全てのヒットに対してのその置換処理が
         | 
| 27 24 | 
             
                # 行われた文字列が返される。
         | 
| 28 25 | 
             
                #
         | 
| 29 | 
            -
                #  | 
| 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 | 
            -
                # | 
| 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",
         | 
    
        data/lib/groonga/posting.rb
    CHANGED
    
    | @@ -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
         | 
    
        data/lib/groonga/record.rb
    CHANGED
    
    | @@ -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 | 
            -
                #  | 
| 44 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 89 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 98 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 107 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 116 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 133 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 162 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 266 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 275 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 324 | 
            -
                # | 
| 325 | 
            -
                #    | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                #  | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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 | 
            +
             |