/*
 * Table class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util.table;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * マップ・オブジェクトをレコードとするテーブルのインターフェイス。
 * <br>
 * キー構成が同じであるマップ・オブジェクトをレコードとして、そのレコードの集合
 * を構成要素として持つ。
 * <br>
 * テーブルの内容の取得や更新はレコード単位で行われる。
 * 取得や更新の条件とするカラム・キーとその値は、マップに格納して引数として
 * メソッドに渡す。
 * レコードを取得するメソッドには{@link #select(java.util.Map)}や
 * {@link #selectFirst(java.util.Map)}がある。
 * レコードを削除するメソッドには{@link #delete(java.util.Map)}がある。
 * レコードを更新するメソッドには{@link #update(java.util.Map,java.util.Map)}
 * がある。
 * <br>
 * レコードを追加するには、{@link #appendNew()}メソッドを用いる。
 * {@link #appendNew()}メソッドは、戻り値としてテーブルに追加されたレコードで
 * あるマップを返す。
 *
 * @param  <C> カラム・キーのタイプ。
 * @param  <V> カラムの値のタイプ。
 *
 * @author  佐藤隆之.
 * @version $Revision: 1.4 $, $Date: 2011-10-29 14:50:18 $
 */
public interface Table<C,V> extends MapAppender<C,V>, Serializable
{
  /**
   * テーブルを構成するカラム・キーの数を取得する。
   *
   * @return カラム・キーの数。
   */
  int columnCount();

  /**
   * テーブルに格納されているレコードの数を取得する。
   *
   * @return レコード数。
   */
  int recordCount();

  /**
   * このテーブルを構成するカラム・キーを列挙する。
   *
   * @return カラム・キーを格納した列挙オブジェクト。
   */
  Enumeration<C> columns();

  /**
   * このテーブルに格納されているレコードを順に取り出すためのイテレータを取得
   * する。
   *
   * @return レコードのイテレータ。
   */
  MapIterator<C,V> records();

  /**
   * このテーブルに格納されているレコードをソートして、順に取り出すための
   * イテレータを取得する。
   *
   * @param  comparator ソートに使用するレコード比較オブジェクト。
   * @return レコードのイテレータ。
   */
  MapIterator<C,V> records(MapComparator<C,V> comparator);

  /**
   * このテーブルに格納されている最初のレコードを取得する。
   *
   * @return このテーブルの最初のレコード。
   */
  Map<C,V> recordFirst();

  /**
   * このテーブルに格納されているレコードを全て削除する。
   */
  void deleteAll();

  /**
   * 指定されたカラムの値が指定された値と一致するレコードが存在するかどうかを
   * 確認する。
   *
   * @param  column 条件とするカラム・キー。
   * @param  value  条件とするカラムの値。
   * @return 該当するレコードが存在する場合は<tt>true</tt>を返す。
   */
  boolean exists(C column, V value);

  /**
   * 条件に該当するレコードが存在するかどうかを確認する。
   * <br>
   * 引数のマップに格納されているキーと値の組み合わせと同じ組み合わせを持つ
   * レコードを検索し、1件でも存在した場合は<tt>true</tt>を返す。
   * <br>
   * <br>
   * 引数のマップのキーの中に、このテーブルのカラム・キーに存在しないものが
   * あった場合は、常に<tt>false</tt>を返す。
   * <br>
   * 反対に、このテーブルのカラム・キーの中に、引数のマップに存在しないキーを
   * 持っていても、それらは無視される。それ以外のカラム・キーの値が等しい
   * レコードがあれば<tt>true</tt>を返す。
   * <br>
   * 引数のマップが空だった場合は条件なしとして、このテーブルにレコードが1件
   * でもあった場合は<tt>true</tt>を返す。
   *
   * @param  condition 条件のカラムとその値を格納したマップ・オブジェクト。
   * @return 該当するレコードが存在する場合は<tt>true</tt>を返す。
   */
  boolean exists(Map<C,V> condition);

  /**
   * 指定されたカラムの値が指定された値と最初に一致したレコードを返す。
   *
   * @param  column 条件とするカラム・キー。
   * @param  value  条件とするカラムの値。
   * @return 指定されたカラムの値と最初に一致したレコード。
   */
  Map<C,V> selectFirst(C column, V value);

  /**
   * 条件に最初に該当したレコードを取得する。
   * <br>
   * 引数のマップに格納されているキーと値の組み合わせと同じ組み合わせを持つ
   * レコードを検索し、その最初のレコードを返す。
   * <br>
   * 該当するレコードが1件も存在しない場合はヌルを返す。
   * <br>
   * <br>
   * 引数のマップのキーの中に、このテーブルのカラム・キーに存在しないものが
   * あった場合は、全てのレコードが該当しなくなり、ヌルが返される。
   * <br>
   * 反対に、このテーブルのカラム・キーの中に、引数のマップに存在しないキーを
   * 持っていても、それらは無視される。それ以外のカラム・キーの値が等しい
   * レコードがあれば、その最初のレコードを返す。
   * <br>
   * 引数のマップが空だった場合は条件なしとして、このテーブルに格納されている
   * 最初のレコードを返す。
   *
   * @param  condition 条件のカラムとその値を格納したマップ・オブジェクト。
   * @return 指定されたカラムの値と一致するレコード。
   */
  Map<C,V> selectFirst(Map<C,V> condition);

  /**
   * 指定されたカラムの値が指定された値と一致するレコードを格納したリストを
   * を取得する。
   *
   * @param  column 条件とするカラム・キー。
   * @param  value  条件とするカラムの値。
   * @return 指定されたカラムの値と一致するレコードを格納したリスト。
   */
  List<Map<C,V>> select(C column, V value);

  /**
   * 条件に該当するレコードを格納したリストを取得する。
   * <br>
   * 引数のマップに格納されているキーと値の組み合わせと同じ組み合わせを持つ
   * レコードを検索し、そのレコードを格納したリストを返す。
   * <br>
   * 該当するレコードが1件も存在しない場合は空のリストを返す。
   * <br>
   * <br>
   * 引数のマップのキーの中に、このテーブルのカラム・キーに存在しないものが
   * あった場合は、全てのレコードが該当しなくなり、空のリストを返す。
   * <br>
   * 反対に、このテーブルのカラム・キーの中に、引数のマップに存在しないキーを
   * 持っていても、それらは無視される。それ以外のカラム・キーの値が等しい
   * レコードがあれば、それらをリストに格納して返す。
   * <br>
   * 引数のマップが空だった場合は条件なしとして、このテーブルに格納されている
   * 全てのレコードを格納したリストを返す。
   *
   * @param  condition 条件のカラムとその値を格納したマップ・オブジェクト。
   * @return 指定されたカラムの値と一致するレコードを格納したリスト。
   */
  List<Map<C,V>> select(Map<C,V> condition);

  /**
   * 条件に該当するレコードを、このテーブル・オブジェクトから削除する。
   * <br>
   * 引数のマップに格納されているキーと値の組み合わせと同じ組み合わせを持つ
   * レコードを検索して、このテーブルから削除する。
   * <br>
   * 削除されたレコードは、リストに格納されて戻り値として返される。
   * <br>
   * <br>
   * 引数のマップのキーの中に、このテーブルのカラム・キーに存在しないものが
   * あった場合は、全てのレコードが条件に該当しなくなり、1件も削除されない。
   * <br>
   * 反対に、このテーブルのカラム・キーの中に、引数のマップに存在しないキーを
   * 持っていても、それらは無視される。それ以外のカラム・キーの値が等しい
   * レコードがあれば、それらをこのテーブルから削除し、リストに格納して返す。
   * <br>
   * 引数のマップが空だった場合は条件なしとして、このテーブルに格納されている
   * 全てのレコードを削除し、リストに格納して返す。
   *
   * @param  condition 条件とするカラムとその値を格納したマップ・オブジェクト。
   * @return 削除されたレコードを格納したリスト。
   */
  List<Map<C,V>> delete(Map<C,V> condition);

  /**
   * 条件に該当するレコードを、指定されたマップの内容で更新する。
   * <br>
   * 第1引数のマップに格納されているキーと値の組み合わせと同じ組み合わせを持つ
   * レコードを検索して、その中の内容を第2引数のマップの内容で更新する。
   * <br>
   * 更新されたレコードは、新たに作成されたテーブル・オブジェクトに格納されて
   * 戻り値として返される。
   * <br>
   * <br>
   * 引数のマップのキーの中に、このテーブルのカラム・キーに存在しないものが
   * あった場合は、全てのレコードが条件に該当しなくなり、1件も更新されない。
   * <br>
   * 反対に、このテーブルのカラム・キーの中に、引数のマップに存在しないキーを
   * 持っていても、それらは無視される。それ以外のカラム・キーの値が等しい
   * レコードがあれば、それらの内容を更新し、リストに格納して返す。
   * <br>
   * 引数のマップが空だった場合は条件なしとして、このテーブルに格納されている
   * 全てのレコードの内容を更新し、リストに格納して返す。
   *
   * @param  condition 条件とするカラムとその値を格納したマップ・オブジェクト。
   * @param  destination 更新するカラムとその値を格納したマップ・オブジェクト。
   * @return 更新されたレコードを格納したリスト。
   */
  List<Map<C,V>> update(Map<C,V> condition, Map<C,V> destination);

  /**
   * 指定された配列の要素をインデックス・キーとするインデックスを取得する。
   * <br>
   * 該当するインデックスが存在しない場合は、インデックスを作成して返す。
   *
   * @param  indexKeys インデックス・キーの配列。
   * @return このテーブルのインデックス・オブジェクト。
   */
  Index<C,V> getIndex(C ... indexKeys);

  /**
   * トリガーを追加する。
   * <br>
   * 追加されたトリガーは、このテーブルの内容が変更される直前及び直後に
   * 呼び出され、テーブルの変更の種類と変更の前後に応じたメソッドが実行
   * される。
   *
   * @param  trigger トリガー・オブジェクト。
   */
  void addTrigger(Trigger<C,V> trigger);
}

