lib/groonga/record.rb in groonga-0.0.7 vs lib/groonga/record.rb in groonga-0.9.0

- old
+ new

@@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com> +# Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License version 2.1 as published by the Free Software Foundation. # @@ -15,117 +15,262 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA module Groonga class Record - attr_reader :table, :id + # レコードが所属するテーブル + attr_reader :table + # レコードのID + attr_reader :id + # _table_の_id_に対応するレコードを作成する。_values_には各 + # カラムに設定する値を以下のような形式で指定する。 + # + # [ + # ["カラム名", 値], + # ["カラム名", 値], + # ..., + # ] def initialize(table, id, values=nil) @table = table @id = id if values values.each do |name, value| self[name] = value end end end + # call-seq: + # record == other -> true/false + # + # _record_と_other_が同じgroongaのレコードなら+true+を返し、 + # そうでなければ+false+を返す。 def ==(other) self.class == other.class and [table, id] == [other.table, other.id] end + # call-seq: + # record[column_name] -> 値 + # + # このレコードの_column_name_で指定されたカラムの値を返す。 def [](column_name) - column(column_name)[@id] + @table.column_value(@id, column_name, :id => true) end + # call-seq: + # record[column_name] = 値 + # + # このレコードの_column_name_で指定されたカラムの値を設定す + # る。 def []=(column_name, value) - column(column_name)[@id] = value + @table.set_column_value(@id, column_name, value, :id => true) end + # call-seq: + # record.append(column_name, value) + # + # このレコードの_column_name_で指定されたカラムの値の最後に + # _value_を追加する。 def append(column_name, value) column(column_name).append(@id, value) end + # call-seq: + # record.prepend(column_name, value) + # + # このレコードの_column_name_で指定されたカラムの値の最初に + # _value_を追加する。 def prepend(column_name, value) column(column_name).prepend(@id, value) end + # call-seq: + # record.have_column?(name) -> true/false + # + # 名前が_name_のカラムがレコードの所属するテーブルで定義され + # ているなら+true+を返す。 def have_column?(name) column(name).is_a?(Groonga::Column) - rescue Groonga::InvalidArgument + rescue Groonga::NoSuchColumn false end + # call-seq: + # record.reference_column?(name) -> true/false + # + # 名前が_name_のカラムが参照カラムであるなら+true+を返す。 def reference_column?(name) column(name).range.is_a?(Groonga::Table) end + # call-seq: + # record.search(name, query, options={}) -> Groonga::Hash + # + # 名前が_name_のGroonga::IndexColumnのsearchメソッドを呼ぶ。 + # _query_と_options_はそのメソッドにそのまま渡される。詳しく + # はGroonga::IndexColumn#searchを参照。 def search(name, query, options={}) column(name).search(query, options) end + # call-seq: + # record.key -> 主キー + # + # レコードの主キーを返す。 + # + # _record_が所属するテーブルがGroonga:::Arrayの場合は常 + # に+nil+を返す。 def key - @table.key(@id) + if @table.is_a?(Groonga::Array) + nil + else + @key ||= @table.key(@id) + end end + # call-seq: + # record.score -> スコア値 + # + # レコードのスコア値を返す。検索結果として生成されたテーブル + # のみに定義される。 def score - self[".:score"] + self["._score"] end + # call-seq: + # record.n_sub_records -> 件数 + # + # 主キーの値が同一であったレコードの件数を返す。検索結果とし + # て生成されたテーブルのみに定義される。 + def n_sub_records + self["._nsubrecs"] + end + + # call-seq: + # record.value -> 値 + # + # レコードの値を返す。 def value - @table[@id] + @table.value(@id, :id => true) end + # call-seq: + # record.value = 値 + # + # レコードの値を設定する。既存の値は上書きされる。 def value=(value) - @table[@id] = value + @table.set_value(@id, value, :id => true) end + # call-seq: + # record.increment!(name, delta=nil) + # + # このレコードの_name_で指定されたカラムの値を_delta_だけ増 + # 加する。_delta_が+nil+の場合は1増加する。 def increment!(name, delta=nil) column(name).increment!(@id, delta) end + # call-seq: + # record.decrement!(name, delta=nil) + # + # このレコードの_name_で指定されたカラムの値を_delta_だけ減 + # 少する。_delta_が+nil+の場合は1減少する。 def decrement!(name, delta=nil) column(name).decrement!(@id, delta) end + # call-seq: + # record.columns -> Groonga::Columnの配列 + # + # レコードが所属するテーブルの全てのカラムを返す。 def columns @table.columns end + # call-seq: + # attributes -> Hash + # + # レコードが所属しているテーブルで定義されているインデックス + # 型のカラムでない全カラムを対象とし、カラムの名前をキーとし + # たこのレコードのカラムの値のハッシュを返す。 def attributes - attributes = {} + attributes = {"id" => id} + _key = key + attributes["key"] = _key if _key table_name = @table.name columns.each do |column| next if column.is_a?(Groonga::IndexColumn) - attributes[column.local_name] = column[@id] + value = column[@id] + # TODO: support recursive reference. + value = value.attributes if value.is_a?(Groonga::Record) + attributes[column.local_name] = value end attributes end + # call-seq: + # record.delete + # + # レコードを削除する。 def delete @table.delete(@id) end + # call-seq: + # record.lock(options={}) + # record.lock(options={}) {...} + # + # レコードが所属するテーブルをロックする。ロックに失敗した場 + # 合はGroonga::ResourceDeadlockAvoided例外が発生する。 + # + # ブロックを指定した場合はブロックを抜けたときにunlockする。 + # + # 利用可能なオプションは以下の通り。 + # + # [_:timeout_] + # ロックを獲得できなかった場合は_:timeout_秒間ロックの獲 + # 得を試みる。_:timeout_秒以内にロックを獲得できなかった + # 場合は例外が発生する。 def lock(options={}, &block) @table.lock(options.merge(:id => @id), &block) end + # call-seq: + # record.unlock(options={}) + # + # レコードが所属するテーブルのロックを解除する。 + # + # 利用可能なオプションは現在は無い。 def unlock(options={}) @table.unlock(options.merge(:id => @id)) end + # call-seq: + # record.clear_lock(options={}) + # + # レコードが所属するテーブルのロックを強制的に解除する。 + # + # 利用可能なオプションは現在は無い。 def clear_lock(options={}) @table.clear_lock(options.merge(:id => @id)) end + # call-seq: + # record.locked?(options={}) -> true/false + # + # レコードが所属するテーブルがロックされていれば+true+を返す。 + # + # 利用可能なオプションは現在は無い。 def locked?(options={}) @table.locked?(options.merge(:id => @id)) end private - def column(name) + def column(name) # :nodoc: _column = @table.column(name.to_s) - raise InvalidArgument, "column(#{name.inspect}) is nil" if _column.nil? + raise NoSuchColumn, "column(#{name.inspect}) is nil" if _column.nil? _column end end end