--- /dev/null
+/*
+ * Created on 20.08.2004
+ *
+ * A Virtual Result Set. It's virtual because it doesn't has cache,
+ * but rather is tightly coupled with its RecordSet object,
+ * and mainly gives some added functionality, for use in
+ * virtual tables. It has SQLResults as a superclass mainly
+ * for conceptual reasons, it could be standalone.
+ */
+package com.quantum.sql;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import com.quantum.model.Column;
+import com.quantum.model.Entity;
+import com.quantum.model.NotConnectedException;
+import com.quantum.util.StringMatrix;
+import com.quantum.util.sql.SQLInstructionBuilder;
+
+/**
+ * @author Julen
+ *
+ */
+public class SQLVirtualResultSet extends SQLResults {
+ // The resultSet will be based on a query, that can be changed
+ private String query = "";
+ private ResultSet resultSet = null;
+ private int knownNumberOfRows = 0;
+
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.SQLResults#isResultSet()
+ */
+ public SQLVirtualResultSet(Entity entity) {
+ try {
+ // Cannot use "SELECT *" because that is not updatable, at least in some JDBC drivers
+ Initialize(SQLInstructionBuilder.buildSelect(entity, entity.getColumns(), null),
+ entity.getBookmark().getConnection(),
+ ResultSet.TYPE_SCROLL_SENSITIVE,
+ ResultSet.CONCUR_UPDATABLE);
+
+ } catch (NotConnectedException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ public SQLVirtualResultSet(Entity entity, int type, int concurrency) {
+ try {
+ // Cannot use "SELECT *" because that is not updatable, at least in some JDBC drivers
+ Initialize(SQLInstructionBuilder.buildSelect(entity, entity.getColumns(), null),
+ entity.getBookmark().getConnection(),
+ type,
+ concurrency);
+
+ } catch (NotConnectedException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * @param string
+ * @param connection
+ */
+ private void Initialize(String query, Connection connection, int type, int concurrency) {
+ if (connection == null) return;
+ this.query = query;
+ try {
+ Statement statement = connection.createStatement(type, concurrency);
+ resultSet = statement.executeQuery(query);
+ // If the recordset is not empty, we know there is at least one row. This call may fall also
+ // because the recordset is not of the correct type to run isLast, so the resultSet may be valid.
+ if (!resultSet.isLast())
+ knownNumberOfRows = 1;
+ } catch (SQLException e) {
+ return;
+ }
+
+
+ }
+
+ public boolean isResultSet() {
+ return true;
+ }
+
+ /**
+ * @return If the resultSet is open, that is, connected to a data source
+ */
+ public boolean isOpen() {
+ return (resultSet != null);
+ }
+
+
+ /**
+ * @return Returns the knowNumberOfRows.
+ */
+ public int getKnownNumberOfRows() {
+ return knownNumberOfRows;
+ }
+ /**
+ * @param index
+ * @param i
+ * @return
+ */
+ public String getStringValue(int row, int column) {
+ if (resultSet == null) return null;
+ try {
+ // Rows and columns in resultSets are 1-based
+ resultSet.absolute(row+1);
+ actKnownNumberOfRows();
+ return resultSet.getString(column+1);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ /**
+ *
+ */
+ private void actKnownNumberOfRows() {
+ if (resultSet == null) return;
+ int nRowsNow;
+ try {
+ nRowsNow = resultSet.getRow() + (resultSet.isLast() ? 0 : 1);
+ knownNumberOfRows = Math.max( nRowsNow, knownNumberOfRows);
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ /**
+ * @param index
+ * @return
+ */
+ public String[] getRowAsStringArray(int row) {
+ if (resultSet == null) return null;
+ try {
+ resultSet.absolute(row+1);
+ actKnownNumberOfRows();
+ return getRowAsStringArray();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * @return
+ *
+ */
+ public String[] getRowAsStringArray() {
+ String[] resultArray = null;
+ int numColumns;
+ try {
+ numColumns = resultSet.getMetaData().getColumnCount();
+ resultArray = new String[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ // Rows and columns in resultSets are 1-based
+ resultArray[i] = resultSet.getString(i+1);
+ }
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return resultArray;
+ }
+
+ /**
+ *
+ */
+ public boolean next(){
+ try {
+ return resultSet.next();
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
+ }
+ }
+ public boolean isLast() {
+ try {
+ return resultSet.isLast();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return true;
+ }
+ }
+ /**
+ * @return Names of the Columns of the ResultSet, in the order given
+ */
+ public String[] getColumnNames() {
+ if (resultSet == null) return null;
+ String resultArray[] = null;
+ try {
+ int numColumns = resultSet.getMetaData().getColumnCount();
+ resultArray = new String[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ // Rows and columns in resultSets are 1-based
+ resultArray[i] = resultSet.getMetaData().getColumnName(i+1);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return resultArray;
+ }
+ /**
+ * @param columnIndex
+ * @param valueStr
+ */
+ public boolean update(int row, int columnIndex, String valueStr) {
+ if (row < 0 || columnIndex < 0 ) return false;
+ try {
+ resultSet.absolute(row+1);
+ resultSet.updateString(columnIndex+1, valueStr);
+ resultSet.updateRow();
+ return true;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+ public void close(){
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}