2 * Created on 20.08.2004
4 * A Virtual Result Set. It's virtual because it doesn't has cache,
5 * but rather is tightly coupled with its RecordSet object,
6 * and mainly gives some added functionality, for use in
7 * virtual tables. It has SQLResults as a superclass mainly
8 * for conceptual reasons, it could be standalone.
10 package com.quantum.sql;
12 import java.sql.Connection;
13 import java.sql.ResultSet;
14 import java.sql.SQLException;
15 import java.sql.Statement;
17 import com.quantum.model.Column;
18 import com.quantum.model.Entity;
19 import com.quantum.model.NotConnectedException;
20 import com.quantum.util.StringMatrix;
21 import com.quantum.util.sql.SQLInstructionBuilder;
27 public class SQLVirtualResultSet extends SQLResults {
28 // The resultSet will be based on a query, that can be changed
29 private String query = "";
30 private ResultSet resultSet = null;
31 private int knownNumberOfRows = 0;
35 * @see com.quantum.sql.SQLResults#isResultSet()
37 public SQLVirtualResultSet(Entity entity) {
39 // Cannot use "SELECT *" because that is not updatable, at least in some JDBC drivers
40 Initialize(SQLInstructionBuilder.buildSelect(entity, entity.getColumns(), null),
41 entity.getBookmark().getConnection(),
42 ResultSet.TYPE_SCROLL_SENSITIVE,
43 ResultSet.CONCUR_UPDATABLE);
45 } catch (NotConnectedException e) {
47 } catch (SQLException e) {
51 public SQLVirtualResultSet(Entity entity, int type, int concurrency) {
53 // Cannot use "SELECT *" because that is not updatable, at least in some JDBC drivers
54 Initialize(SQLInstructionBuilder.buildSelect(entity, entity.getColumns(), null),
55 entity.getBookmark().getConnection(),
59 } catch (NotConnectedException e) {
61 } catch (SQLException e) {
69 private void Initialize(String query, Connection connection, int type, int concurrency) {
70 if (connection == null) return;
73 Statement statement = connection.createStatement(type, concurrency);
74 resultSet = statement.executeQuery(query);
75 // If the recordset is not empty, we know there is at least one row. This call may fall also
76 // because the recordset is not of the correct type to run isLast, so the resultSet may be valid.
77 if (!resultSet.isLast())
78 knownNumberOfRows = 1;
79 } catch (SQLException e) {
86 public boolean isResultSet() {
91 * @return If the resultSet is open, that is, connected to a data source
93 public boolean isOpen() {
94 return (resultSet != null);
99 * @return Returns the knowNumberOfRows.
101 public int getKnownNumberOfRows() {
102 return knownNumberOfRows;
109 public String getStringValue(int row, int column) {
110 if (resultSet == null) return null;
112 // Rows and columns in resultSets are 1-based
113 resultSet.absolute(row+1);
114 actKnownNumberOfRows();
115 return resultSet.getString(column+1);
116 } catch (SQLException e) {
124 private void actKnownNumberOfRows() {
125 if (resultSet == null) return;
128 nRowsNow = resultSet.getRow() + (resultSet.isLast() ? 0 : 1);
129 knownNumberOfRows = Math.max( nRowsNow, knownNumberOfRows);
130 } catch (SQLException e) {
131 // TODO Auto-generated catch block
139 public String[] getRowAsStringArray(int row) {
140 if (resultSet == null) return null;
142 resultSet.absolute(row+1);
143 actKnownNumberOfRows();
144 return getRowAsStringArray();
145 } catch (SQLException e) {
155 public String[] getRowAsStringArray() {
156 String[] resultArray = null;
159 numColumns = resultSet.getMetaData().getColumnCount();
160 resultArray = new String[numColumns];
161 for (int i = 0; i < numColumns; i++) {
162 // Rows and columns in resultSets are 1-based
163 resultArray[i] = resultSet.getString(i+1);
165 } catch (SQLException e) {
166 // TODO Auto-generated catch block
175 public boolean next(){
177 return resultSet.next();
178 } catch (SQLException e) {
179 // TODO Auto-generated catch block
184 public boolean isLast() {
186 return resultSet.isLast();
187 } catch (SQLException e) {
193 * @return Names of the Columns of the ResultSet, in the order given
195 public String[] getColumnNames() {
196 if (resultSet == null) return null;
197 String resultArray[] = null;
199 int numColumns = resultSet.getMetaData().getColumnCount();
200 resultArray = new String[numColumns];
201 for (int i = 0; i < numColumns; i++) {
202 // Rows and columns in resultSets are 1-based
203 resultArray[i] = resultSet.getMetaData().getColumnName(i+1);
205 } catch (SQLException e) {
214 public boolean update(int row, int columnIndex, String valueStr) {
215 if (row < 0 || columnIndex < 0 ) return false;
217 resultSet.absolute(row+1);
218 resultSet.updateString(columnIndex+1, valueStr);
219 resultSet.updateRow();
221 } catch (SQLException e) {
230 } catch (SQLException e) {