Пример #1
0
 public String toString() {
   StringBuilder txt = new StringBuilder(256);
   txt.append("XID[Format=").append(fmtId).append(", Global=0x");
   txt.append(Support.toHex(gtran)).append(", Branch=0x");
   txt.append(Support.toHex(bqual)).append(']');
   return txt.toString();
 }
  public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
    BigDecimal bd =
        (BigDecimal)
            Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.DECIMAL, null);

    return bd.setScale(scale);
  }
 public byte[] getBytes(int parameterIndex) throws SQLException {
   return ((byte[])
       Support.convert(
           this,
           getOutputValue(parameterIndex),
           java.sql.Types.VARBINARY,
           connection.getCharset()));
 }
Пример #4
0
  /**
   * Substitute actual data for the parameter markers to simulate parameter substitution in a
   * PreparedStatement.
   *
   * @param sql The SQL containing parameter markers to substitute.
   * @param list The parameter descriptors.
   * @param connection The current connection.
   * @return The modified SQL statement.
   */
  static String substituteParameters(String sql, ParamInfo[] list, ConnectionJDBC2 connection)
      throws SQLException {
    int len = sql.length();

    for (int i = 0; i < list.length; i++) {
      if (!list[i].isRetVal && !list[i].isSet && !list[i].isOutput) {
        throw new SQLException(
            Messages.get("error.prepare.paramnotset", Integer.toString(i + 1)), "07000");
      }

      Object value = list[i].value;

      if (value instanceof java.io.InputStream || value instanceof java.io.Reader) {
        try {
          if (list[i].jdbcType == java.sql.Types.LONGVARCHAR
              || list[i].jdbcType == java.sql.Types.CLOB
              || list[i].jdbcType == java.sql.Types.VARCHAR) {
            // TODO: Should improve the character set handling here
            value = list[i].getString("US-ASCII");
          } else {
            value = list[i].getBytes("US-ASCII");
          }
          // Replace the stream/reader with the String/byte[]
          list[i].value = value;
        } catch (java.io.IOException e) {
          throw new SQLException(Messages.get("error.generic.ioerror", e.getMessage()), "HY000");
        }
      }

      if (value instanceof String) {
        len += ((String) value).length() + 5;
      } else if (value instanceof byte[]) {
        len += ((byte[]) value).length * 2 + 4;
      } else {
        len += 32; // Default size
      }
    }

    StringBuffer buf = new StringBuffer(len + 16);
    int start = 0;

    for (int i = 0; i < list.length; i++) {
      int pos = list[i].markerPos;

      if (pos > 0) {
        buf.append(sql.substring(start, list[i].markerPos));
        start = pos + 1;
        final boolean isUnicode = connection.getTdsVersion() >= Driver.TDS70 && list[i].isUnicode;
        Support.embedData(buf, list[i].value, isUnicode, connection);
      }
    }

    if (start < sql.length()) {
      buf.append(sql.substring(start));
    }

    return buf.toString();
  }
  public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
    java.sql.Date date = getDate(parameterIndex);

    if (date != null && cal != null) {
      date = new java.sql.Date(Support.timeToZone(date, cal));
    }

    return date;
  }
  public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
    java.sql.Time time = getTime(parameterIndex);

    if (time != null && cal != null) {
      time = new java.sql.Time(Support.timeToZone(time, cal));
    }

    return time;
  }
  public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
    Timestamp timestamp = getTimestamp(parameterIndex);

    if (timestamp != null && cal != null) {
      timestamp = new Timestamp(Support.timeToZone(timestamp, cal));
    }

    return timestamp;
  }
  public URL getURL(int parameterIndex) throws SQLException {
    String url =
        (String)
            Support.convert(
                this,
                getOutputValue(parameterIndex),
                java.sql.Types.VARCHAR,
                connection.getCharset());

    try {
      return new java.net.URL(url);
    } catch (MalformedURLException e) {
      throw new SQLException(Messages.get("error.resultset.badurl", url), "22000");
    }
  }
  /**
   * Copy the contents of a Reader stream to the server as bytes.
   *
   * <p>NB. Only reliable where the charset is single byte.
   *
   * @param in The Reader object with the data.
   * @param length The length of the data in bytes.
   * @throws IOException
   */
  void writeReaderBytes(Reader in, int length) throws IOException {
    char buffer[] = new char[1024];

    for (int i = 0; i < length; ) {
      int result = in.read(buffer);

      if (result == -1) {
        throw new java.io.IOException("Data in stream less than specified by length");
      } else if (i + result > length) {
        throw new java.io.IOException("More data in stream than specified by length");
      }

      write(Support.encodeString(socket.getCharset(), new String(buffer, 0, result)));
      i += result;
    }
  }
  public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
    ParamInfo pi = getParameter(parameterIndex);

    pi.isOutput = true;

    if (Support.getJdbcTypeName(sqlType).equals("ERROR")) {
      throw new SQLException(
          Messages.get("error.generic.badtype", Integer.toString(sqlType)), "HY092");
    }

    if (sqlType == java.sql.Types.CLOB) {
      pi.jdbcType = java.sql.Types.LONGVARCHAR;
    } else if (sqlType == java.sql.Types.BLOB) {
      pi.jdbcType = java.sql.Types.LONGVARBINARY;
    } else {
      pi.jdbcType = sqlType;
    }

    pi.scale = scale;
  }
  public void updateRow() throws SQLException {
    checkOpen();
    checkUpdateable();

    rowUpdated = false;
    rowDeleted = false;
    if (currentRow == null) {
      throw new SQLException(Messages.get("error.resultset.norow"), "24000");
    }

    if (onInsertRow) {
      throw new SQLException(Messages.get("error.resultset.insrow"), "24000");
    }

    if (updateRow == null) {
      // Nothing to update
      return;
    }
    boolean keysChanged = false;
    //
    // Construct an SQL UPDATE statement
    //
    StringBuffer sql = new StringBuffer(128);
    ArrayList params = new ArrayList();
    sql.append("UPDATE ");
    sql.append(tableName);
    //
    // OK now create assign new values
    //
    sql.append(" SET ");
    int count = 0;
    for (int i = 0; i < columnCount; i++) {
      if (updateRow[i] != null) {
        if (count > 0) {
          sql.append(", ");
        }
        sql.append(columns[i].realName);
        sql.append("=?");
        updateRow[i].markerPos = sql.length() - 1;
        params.add(updateRow[i]);
        count++;
        if (columns[i].isKey) {
          // Key is changing so in memory row will need to be deleted
          // and reinserted at end of row buffer.
          keysChanged = true;
        }
      }
    }
    if (count == 0) {
      // There are no columns to update in this table
      // so bail out now.
      return;
    }
    //
    // Now construct where clause
    //
    ParamInfo parameters[] = buildWhereClause(sql, params, false);
    //
    // Now execute update
    //
    updateTds.executeSQL(
        sql.toString(),
        null,
        parameters,
        false,
        0,
        statement.getMaxRows(),
        statement.getMaxFieldSize(),
        true);
    int updateCount = 0;
    while (!updateTds.isEndOfResponse()) {
      if (!updateTds.getMoreResults()) {
        if (updateTds.isUpdateCount()) {
          updateCount = updateTds.getUpdateCount();
        }
      }
    }
    updateTds.clearResponseQueue();
    statement.getMessages().checkErrors();

    if (updateCount == 0) {
      // No update. Possibly row was changed on database by another user?
      throw new SQLException(Messages.get("error.resultset.updatefail"), "24000");
    }
    //
    // Update local copy of data
    //
    if (resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE) {
      // Make in memory copy reflect database update
      // Could use refreshRow but this is much faster.
      ConnectionJDBC2 con = (ConnectionJDBC2) statement.getConnection();
      for (int i = 0; i < updateRow.length; i++) {
        if (updateRow[i] != null) {
          currentRow[i] =
              Support.convert(con, updateRow[i].value, columns[i].jdbcType, con.getCharset());
        }
      }
    }
    //
    // Update state of cached row data
    //
    if (keysChanged && resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
      // Leave hole at current position and add updated row to end of set
      rowData.add(currentRow);
      rowsInResult = rowData.size();
      rowData.set(pos - 1, null);
      currentRow = null;
      rowDeleted = true;
    } else {
      rowUpdated = true;
    }
    //
    // Clear update values
    //
    cancelRowUpdates();
  }
 public double getDouble(int parameterIndex) throws SQLException {
   return ((Double)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.DOUBLE, null))
       .doubleValue();
 }
 public byte getByte(int parameterIndex) throws SQLException {
   return ((Integer)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.TINYINT, null))
       .byteValue();
 }
 public Timestamp getTimestamp(int parameterIndex) throws SQLException {
   return (Timestamp)
       Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.TIMESTAMP, null);
 }
 public float getFloat(int parameterIndex) throws SQLException {
   return ((Double)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.FLOAT, null))
       .floatValue();
 }
 public int getInt(int parameterIndex) throws SQLException {
   return ((Integer)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.INTEGER, null))
       .intValue();
 }
 public Date getDate(int parameterIndex) throws SQLException {
   return (java.sql.Date)
       Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.DATE, null);
 }
 public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
   return (BigDecimal)
       Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.DECIMAL, null);
 }
  public void insertRow() throws SQLException {
    checkOpen();

    checkUpdateable();

    if (!onInsertRow) {
      throw new SQLException(Messages.get("error.resultset.notinsrow"), "24000");
    }

    if (!tempResultSet) {
      //
      // Construct an SQL INSERT statement
      //
      StringBuffer sql = new StringBuffer(128);
      String dbName = columns[0].catalog;
      String userName = columns[0].schema;
      String tableName = columns[0].tableName;
      ArrayList params = new ArrayList();
      sql.append("INSERT INTO ");
      if (dbName != null) {
        sql.append(dbName);
        sql.append('.');
        if (userName == null) {
          sql.append('.');
        }
      }
      if (userName != null) {
        sql.append(userName);
        sql.append('.');
      }
      sql.append(tableName);
      int sqlLen = sql.length();
      //
      // Create column list
      //
      sql.append(" (");
      int count = 0;
      for (int i = 0; i < columnCount; i++) {
        if (insertRow[i] != null) {
          if (count > 0) {
            sql.append(", ");
          }
          sql.append(columns[i].realName);
          count++;
        }
      }
      //
      // Create new values list
      //
      sql.append(") VALUES(");
      count = 0;
      for (int i = 0; i < columnCount; i++) {
        if (insertRow[i] != null) {
          if (count > 0) {
            sql.append(", ");
          }
          sql.append("?");
          insertRow[i].markerPos = sql.length() - 1;
          params.add(insertRow[i]);
          count++;
        }
      }
      sql.append(')');
      if (count == 0) {
        // Empty insert
        sql.setLength(sqlLen);
        sql.append(" DEFAULT VALUES");
      }
      ParamInfo parameters[] = (ParamInfo[]) params.toArray(new ParamInfo[params.size()]);
      //
      // execute the insert statement
      //
      updateTds.executeSQL(
          sql.toString(),
          null,
          parameters,
          false,
          0,
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);
      int updateCount = 0;
      while (!updateTds.isEndOfResponse()) {
        if (!updateTds.getMoreResults()) {
          if (updateTds.isUpdateCount()) {
            updateCount = updateTds.getUpdateCount();
          }
        }
      }
      updateTds.clearResponseQueue();
      statement.getMessages().checkErrors();
      if (updateCount < 1) {
        // No Insert. Probably will not get here as duplicate key etc
        // will have already been reported as an exception.
        throw new SQLException(Messages.get("error.resultset.insertfail"), "24000");
      }
    }
    //
    if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE
        || resultSetType == ResultSet.TYPE_FORWARD_ONLY && cursorName == null) {
      //
      // Now insert copy of row into result set buffer
      //
      ConnectionJDBC2 con = (ConnectionJDBC2) statement.getConnection();
      Object row[] = newRow();
      for (int i = 0; i < insertRow.length; i++) {
        if (insertRow[i] != null) {
          row[i] = Support.convert(con, insertRow[i].value, columns[i].jdbcType, con.getCharset());
        }
      }
      rowData.add(row);
    }
    rowsInResult++;
    initialRowCnt++;
    //
    // Clear row data
    //
    for (int i = 0; insertRow != null && i < insertRow.length; i++) {
      if (insertRow[i] != null) {
        insertRow[i].clearInValue();
      }
    }
  }
 public String getString(int parameterIndex) throws SQLException {
   return (String)
       Support.convert(
           this, getOutputValue(parameterIndex), java.sql.Types.VARCHAR, connection.getCharset());
 }
 public long getLong(int parameterIndex) throws SQLException {
   return ((Long)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.BIGINT, null))
       .longValue();
 }
  /**
   * Create a new scrollable result set in memory or a named server cursor.
   *
   * @param sql The SQL SELECT statement.
   * @param procName Optional procedure name for cursors based on a stored procedure.
   * @param parameters Optional stored procedure parameters.
   * @exception java.sql.SQLException
   */
  private void cursorCreate(String sql, String procName, ParamInfo[] parameters)
      throws SQLException {
    //
    boolean isSelect = false;
    SQLWarning warning = null;
    //
    // Validate the SQL statement to ensure we have a select.
    //
    if (resultSetType != ResultSet.TYPE_FORWARD_ONLY
        || concurrency == ResultSet.CONCUR_UPDATABLE
        || cursorName != null) {
      //
      // We are going to need access to a SELECT statement for
      // this to work. Reparse the SQL now and check.
      //
      ArrayList params = new ArrayList();
      String tmp[] =
          new SQLParser(sql, params, (ConnectionJDBC2) statement.getConnection()).parse(true);

      if (tmp[2].equals("select") && tmp[3] != null && tmp[3].length() > 0) {
        // OK We have a select with at least one table.
        tableName = tmp[3];
        isSelect = true;
      } else {
        // No good we can't update and we can't declare a cursor
        cursorName = null;
        if (concurrency == ResultSet.CONCUR_UPDATABLE) {
          concurrency = ResultSet.CONCUR_READ_ONLY;
          warning =
              new SQLWarning(Messages.get("warning.cursordowngraded", "CONCUR_READ_ONLY"), "01000");
        }
        if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
          resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;
          SQLWarning warning2 =
              new SQLWarning(
                  Messages.get("warning.cursordowngraded", "TYPE_SCROLL_INSENSITIVE"), "01000");
          if (warning != null) {
            warning.setNextWarning(warning2);
          } else {
            warning = warning2;
          }
        }
      }
    }
    //
    // If a cursor name is specified we try and declare a conventional cursor
    //
    if (cursorName != null) {
      //
      // We need to substitute any parameters now as the prepended DECLARE CURSOR
      // will throw the parameter positions off.
      //
      if (parameters != null && parameters.length > 0) {
        sql = Support.substituteParameters(sql, parameters, statement.getTds().getTdsVersion());
      }
      StringBuffer cursorSQL = new StringBuffer(sql.length() + cursorName.length() + 128);
      cursorSQL.append("DECLARE ").append(cursorName).append(" CURSOR FOR ").append(sql);
      cursorTds.executeSQL(
          cursorSQL.toString(),
          procName,
          parameters,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);
      cursorTds.clearResponseQueue();
      cursorSQL.setLength(0);
      cursorSQL.append("\r\nOPEN ").append(cursorName);
      if (fetchSize > 1 && isSybase) {
        cursorSQL.append("\r\nSET CURSOR ROWS ").append(fetchSize);
        cursorSQL.append(" FOR ").append(cursorName);
      }
      cursorSQL.append("\r\nFETCH ").append(cursorName);
      //
      // OK Declare cursor, open it and fetch first (fetchSize) rows.
      //
      cursorTds.executeSQL(
          cursorSQL.toString(),
          null,
          null,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);

      while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;

      if (!cursorTds.isResultSet()) {
        throw new SQLException(Messages.get("error.statement.noresult"), "24000");
      }
      columns = cursorTds.getColumns();
      columnCount = getColumnCount(columns);
    } else {
      //
      // Open a memory cached scrollable or forward only possibly updateable cursor
      //
      if (isSelect
          && (concurrency == ResultSet.CONCUR_UPDATABLE
              || resultSetType != ResultSet.TYPE_FORWARD_ONLY)) {
        // Need to execute SELECT .. FOR BROWSE to get
        // the MetaData we require for updates etc
        // OK Should have an SQL select statement
        // append " FOR BROWSE" to obtain table names
        // NB. We can't use any jTDS temporary stored proc
        cursorTds.executeSQL(
            sql + " FOR BROWSE",
            null,
            parameters,
            false,
            statement.getQueryTimeout(),
            statement.getMaxRows(),
            statement.getMaxFieldSize(),
            true);
        while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;
        if (!cursorTds.isResultSet()) {
          throw new SQLException(Messages.get("error.statement.noresult"), "24000");
        }
        columns = cursorTds.getColumns();
        columnCount = getColumnCount(columns);
        rowData = new ArrayList(INITIAL_ROW_COUNT);
        //
        // Load result set into buffer
        //
        while (super.next()) {
          rowData.add(copyRow(currentRow));
        }
        rowsInResult = rowData.size();
        initialRowCnt = rowsInResult;
        pos = POS_BEFORE_FIRST;
        //
        // If cursor is built over one table and the table has
        // key columns then the result set is updateable and / or
        // can be used as a scroll sensitive result set.
        //
        if (!isCursorUpdateable()) {
          // No so downgrade
          if (concurrency == ResultSet.CONCUR_UPDATABLE) {
            concurrency = ResultSet.CONCUR_READ_ONLY;
            statement.addWarning(
                new SQLWarning(
                    Messages.get("warning.cursordowngraded", "CONCUR_READ_ONLY"), "01000"));
          }
          if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
            resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;
            statement.addWarning(
                new SQLWarning(
                    Messages.get("warning.cursordowngraded", "TYPE_SCROLL_INSENSITIVE"), "01000"));
          }
        }
        return;
      }
      //
      // Create a read only cursor using direct SQL
      //
      cursorTds.executeSQL(
          sql,
          procName,
          parameters,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);
      while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;

      if (!cursorTds.isResultSet()) {
        throw new SQLException(Messages.get("error.statement.noresult"), "24000");
      }
      columns = cursorTds.getColumns();
      columnCount = getColumnCount(columns);
      rowData = new ArrayList(INITIAL_ROW_COUNT);
      //
      // Load result set into buffer
      //
      while (super.next()) {
        rowData.add(copyRow(currentRow));
      }
      rowsInResult = rowData.size();
      initialRowCnt = rowsInResult;
      pos = POS_BEFORE_FIRST;
      if (warning != null) {
        statement.addWarning(warning);
      }
    }
  }
 public boolean getBoolean(int parameterIndex) throws SQLException {
   return ((Boolean) Support.convert(this, getOutputValue(parameterIndex), BOOLEAN, null))
       .booleanValue();
 }
 public short getShort(int parameterIndex) throws SQLException {
   return ((Integer)
           Support.convert(this, getOutputValue(parameterIndex), java.sql.Types.SMALLINT, null))
       .shortValue();
 }