note description: "Result of a {DATABASE_SELECT_QUERY}" author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class SELECTION_RESULT create make feature {NONE} -- Creation make (a_db_results: like db_results) -- Create. require a_db_results_not_void: a_db_results /= Void do db_results := a_db_results end feature -- Status is_empty: BOOLEAN -- Was the result empty? do Result := db_results.is_empty end after: BOOLEAN -- Are we after the end of the list? do Result := db_results.after end cursor_valid: BOOLEAN -- Is the current cursor position valid? do Result := current_row /= Void end feature -- Access count: INTEGER -- Number of rows. do Result := db_results.count end feature -- Cursor movement start -- Go to the first result row. do db_results.start if not db_results.after then initialize_column_mapping update_current_row end end forth -- Go to the next result row. require not after do db_results.forth if db_results.after then current_row := Void else update_current_row end ensure current_row_or_after: not after implies current_row /= Void end feature -- Access column_names: HASH_TABLE [INTEGER, STRING] -- Mapping of the column names to the indices. feature -- Column access read_string (a_name: STRING): STRING -- Read field `a_name' and expect that it represents a string. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) do Result ?= read_string_ref (a_name) ensure Result_not_void: Result /= Void end read_string_ref (a_name: STRING): STRING -- Read field `a_name' and expect that it represents a string. -- Not that the result may be Void, in case a NULL value is read. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) do Result ?= current_row.item (column_names.item (a_name)) end read_integer (a_name: STRING): INTEGER -- Read field `a_name' and expect that it represents an integer. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) local l_int_ref: INTEGER_REF do l_int_ref ?= read_integer_ref (a_name) check retrieve_ok: l_int_ref /= Void end Result := l_int_ref.item end read_integer_ref (a_name: STRING): INTEGER_REF -- Read field `a_name' and expect that it represents an integer. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) do Result ?= current_row.item (column_names.item (a_name)) end read_double (a_name: STRING): DOUBLE -- Read field `a_name' and expect that it represents a double value. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) local l_dobule_ref: DOUBLE_REF do l_dobule_ref ?= read_double_ref (a_name) check retrieve_ok: l_dobule_ref /= Void end Result := l_dobule_ref.item end read_double_ref (a_name: STRING): DOUBLE_REF -- Read field `a_name' and expect that it represents a double. require cursor_valid: cursor_valid a_name_ok: column_names.has (a_name) do Result ?= current_row.item (column_names.item (a_name)) end feature {NONE} -- Implementation db_results: ARRAYED_LIST [DB_RESULT] -- DB Results. current_row: DB_TUPLE -- Current row of the result. initialize_column_mapping -- Initialize the mapping from the column names to the indices. require not_empty: not is_empty local l_tpl: DB_TUPLE i: INTEGER do -- retrieve first row to read the mapping create l_tpl.copy (db_results.first) create column_names.make (l_tpl.count) from i := 1 until i > l_tpl.count loop column_names.force (i, l_tpl.column_name (i)) i := i + 1 end ensure mapping_done: column_names /= Void end update_current_row -- Update current_row with the position the db_result is set to. require not_empty: not is_empty db_result_cursor_valid: not db_results.off and db_results.readable and db_results.valid_index (db_results.index) do create current_row.copy (db_results.item) ensure current_row_set: current_row /= Void end invariant db_results_not_void: db_results /= Void end