Exemple #1
0
 @Ignore
 @Test
 public void shouldConnectToEmptyDatabase() throws SQLException {
   try (MySQLConnection conn = MySQLConnection.forTestDatabase("emptydb"); ) {
     conn.connect();
   }
 }
  @Override
  public Collection<Entry> findEntries(final String key, final String value) throws IOException {
    Debug.checkNull("key", key);
    Debug.checkNull("value", value);

    final MySQLConnection connection = this.db.obtainConnection();
    connection.checkIsOpen();
    try {
      final Connection mysql_connection = connection.getConnection();

      final String table_name = this.sql_table_name;
      final String stm = "SELECT * FROM " + table_name + " WHERE " + key + " = ?";
      final PreparedStatement statement =
          mysql_connection //
              .prepareStatement(stm);
      statement.setString(1, value);
      final ResultSet result = statement.executeQuery();
      final List<Entry> res = this.collectResult(result);
      return res;
    } catch (final SQLException e) {
      e.printStackTrace();
      throw new IOException(e);
    } finally {
      this.db.releaseConnection(connection);
    }
  }
 @Override
 public void replaceEntries(final List<Entry> batch) throws IOException {
   if (batch.size() == 0) {
     return;
   }
   final Entry entry0 = batch.getElementAt(0);
   final String table_name = this.sql_table_name;
   final List<String> keys = Collections.newList();
   final String stm = "REPLACE " + table_name + " " + this.paramString(entry0, keys, "(", ")");
   final MySQLConnection connection = this.db.obtainConnection();
   connection.checkIsOpen();
   try {
     final Connection mysql_connection = connection.getConnection();
     final PreparedStatement statement = mysql_connection.prepareStatement(stm);
     for (int b = 0; b < batch.size(); b++) {
       final Entry entry = batch.getElementAt(b);
       for (int i = 0; i < keys.size(); i++) {
         final String key = keys.getElementAt(i);
         final String value = entry.getValue(key);
         statement.setString(i + 1, value);
       }
       statement.addBatch();
     }
     statement.executeBatch();
   } catch (final SQLException e) {
     e.printStackTrace();
     throw new IOException(e);
   } finally {
     this.db.releaseConnection(connection);
   }
 }
  @Override
  public void addEntry(final Entry entry) throws IOException {

    final String table_name = this.sql_table_name;
    final List<String> keys = Collections.newList();
    final String stm = "INSERT INTO " + table_name + " " + this.paramString(entry, keys, "(", ")");
    final MySQLConnection connection = this.db.obtainConnection();
    connection.checkIsOpen();
    try {
      final Connection mysql_connection = connection.getConnection();

      final PreparedStatement statement = mysql_connection.prepareStatement(stm);

      for (int i = 0; i < keys.size(); i++) {
        final String key = keys.getElementAt(i);
        final String value = entry.getValue(key);
        statement.setString(i + 1, value);
      }

      statement.execute();
    } catch (final SQLException e) {
      e.printStackTrace();
      throw new IOException(e);
    } finally {
      this.db.releaseConnection(connection);
    }
  }
Exemple #5
0
 @Ignore
 @Test
 public void shouldConnectToDefaulDatabase() throws SQLException {
   try (MySQLConnection conn = MySQLConnection.forTestDatabase("mysql"); ) {
     conn.connect();
   }
 }
Exemple #6
0
  /**
   * Convenience method for turning a byte[] into a string with the given encoding.
   *
   * @param encoding the Java encoding name for the byte[] -> char conversion
   * @param conn the MySQLConnection that created the result set
   * @param value the String value as a series of bytes, encoded using "encoding"
   * @param offset where to start the decoding
   * @param length how many bytes to decode
   * @return the String as decoded from bytes with the given encoding
   * @throws SQLException if an error occurs
   */
  protected String getString(
      String encoding, MySQLConnection conn, byte[] value, int offset, int length)
      throws SQLException {
    String stringVal = null;

    if ((conn != null) && conn.getUseUnicode()) {
      try {
        if (encoding == null) {
          stringVal = StringUtils.toString(value);
        } else {
          SingleByteCharsetConverter converter = conn.getCharsetConverter(encoding);

          if (converter != null) {
            stringVal = converter.toString(value, offset, length);
          } else {
            stringVal = StringUtils.toString(value, offset, length, encoding);
          }
        }
      } catch (java.io.UnsupportedEncodingException E) {
        throw SQLError.createSQLException(
            Messages.getString("ResultSet.Unsupported_character_encoding____101") // $NON-NLS-1$
                + encoding
                + "'.",
            "0S100",
            this.exceptionInterceptor);
      }
    } else {
      stringVal = StringUtils.toAsciiString(value, offset, length);
    }

    return stringVal;
  }
 private void auth323(byte packetId) {
   // 发送323响应认证数据包
   Reply323Packet r323 = new Reply323Packet();
   r323.packetId = ++packetId;
   String pass = source.getPassword();
   if (pass != null && pass.length() > 0) {
     byte[] seed = source.getHandshake().seed;
     r323.seed = SecurityUtil.scramble323(pass, new String(seed)).getBytes();
   }
   r323.write(source);
 }
Exemple #8
0
  // Write a String using the specified character encoding
  final void writeLenString(
      String s,
      String encoding,
      String serverEncoding,
      SingleByteCharsetConverter converter,
      boolean parserKnowsUnicode,
      MySQLConnection conn)
      throws UnsupportedEncodingException, SQLException {
    byte[] b = null;

    if (converter != null) {
      b = converter.toBytes(s);
    } else {
      b =
          StringUtils.getBytes(
              s,
              encoding,
              serverEncoding,
              parserKnowsUnicode,
              conn,
              conn.getExceptionInterceptor());
    }

    int len = b.length;
    ensureCapacity(len + 9);
    writeFieldLength(len);
    System.arraycopy(b, 0, this.byteBuffer, this.position, len);
    this.position += len;
  }
Exemple #9
0
  /**
   * @param columnIndex
   * @param bits
   * @param offset
   * @param length
   * @param conn
   * @param rs
   * @param cal
   * @return
   * @throws SQLException
   */
  protected java.sql.Date getNativeDate(
      int columnIndex,
      byte[] bits,
      int offset,
      int length,
      MySQLConnection conn,
      ResultSetImpl rs,
      Calendar cal)
      throws SQLException {

    int year = 0;
    int month = 0;
    int day = 0;

    if (length != 0) {
      year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);

      month = bits[offset + 2];
      day = bits[offset + 3];
    }

    if (length == 0 || ((year == 0) && (month == 0) && (day == 0))) {
      if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
          conn.getZeroDateTimeBehavior())) {
        return null;
      } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
          conn.getZeroDateTimeBehavior())) {
        throw SQLError.createSQLException(
            "Value '0000-00-00' can not be represented as java.sql.Date",
            SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
            this.exceptionInterceptor);
      }

      year = 1;
      month = 1;
      day = 1;
    }

    if (!rs.useLegacyDatetimeCode) {
      return TimeUtil.fastDateCreate(year, month, day, cal);
    }

    return rs.fastDateCreate(
        cal == null ? rs.getCalendarInstanceForSessionOrNew() : cal, year, month, day);
  }
Exemple #10
0
 @Override
 public void clear() throws IOException {
   L.d("clear sql table", this.sql_table_name);
   final String request = "TRUNCATE " + this.sql_table_name;
   final MySQLConnection connection = this.db.obtainConnection();
   connection.checkIsOpen();
   try {
     final Connection mysql_connection = connection.getConnection();
     final PreparedStatement statement = mysql_connection.prepareStatement(request);
     statement.execute();
     L.d("         ", "done");
   } catch (final SQLException e) {
     e.printStackTrace();
     throw new IOException(e);
   } finally {
     this.db.releaseConnection(connection);
   }
 }
  public DatabaseQuery() {
    try {
      System.out.println("[TRACE] DATABASEQUERY: DatabaseQuery()");
      this.dbConnect = MySQLConnection.getInstance().getConnection();

    } catch (Exception ex) {
      System.out.println("[EXCEPTION]  DatabaseQuery: DatabaseQuery()");
    }
  }
  /** Closes all live connections. */
  private synchronized void closeAllConnections() {
    // close all underlying connections
    for (MySQLConnection c : this.liveConnections.values()) {
      try {
        this.activePhysicalConnections--;
        c.close();
      } catch (SQLException e) {
      }
    }

    if (!this.isClosed) {
      this.balancer.destroy();
      if (this.connectionGroup != null) {
        this.connectionGroup.closeConnectionProxy(this);
      }
    }

    this.liveConnections.clear();
    this.connectionsToHostsMap.clear();
  }
  @Override
  public void handle(byte[] data) {
    try {
      HandshakePacket packet = source.getHandshake();
      if (packet == null) {
        // 设置握手数据包
        packet = new HandshakePacket();
        packet.read(data);
        source.setHandshake(packet);

        source.setThreadId(packet.threadId);

        // 设置字符集编码
        int charsetIndex = (packet.serverCharsetIndex & 0xff);
        String charset = CharsetUtil.getCharset(charsetIndex);
        if (charset != null) {
          source.setCharsetIndex(charsetIndex);
          source.setCharset(charset);
        } else {
          throw new RuntimeException("Unknown charsetIndex:" + charsetIndex);
        }

        // 发送认证数据包
        source.authenticate();
      } else { // 处理认证结果
        switch (data[4]) {
          case OkPacket.FIELD_COUNT:
            source.setHandler(new MySQLConnectionHandler(source));
            source.setAuthenticated(true);
            if (listener != null) {
              listener.connectionAcquired(source);
            }
            break;
          case ErrorPacket.FIELD_COUNT:
            ErrorPacket err = new ErrorPacket();
            err.read(data);
            throw new RuntimeException(new String(err.message));
          case EOFPacket.FIELD_COUNT:
            auth323(data[3]);
            break;
          default:
            throw new RuntimeException("Unknown Packet!");
        }
      }
    } catch (RuntimeException e) {
      if (listener != null) {
        listener.connectionError(e, source);
      }
      throw e;
    }
  }
Exemple #14
0
  @Override
  public List<Entry> listAll() throws IOException {
    final MySQLConnection connection = this.db.obtainConnection();
    connection.checkIsOpen();

    try {
      final Connection mysql_connection = connection.getConnection();

      final Statement statement = mysql_connection.createStatement();
      final String request = "SELECT * FROM " + this.sql_table_name;
      final ResultSet result = statement.executeQuery(request);

      final List<Entry> resultList = this.collectResult(result);

      return resultList;
    } catch (final SQLException e) {
      e.printStackTrace();
      throw new IOException(e);
    } finally {
      this.db.releaseConnection(connection);
    }
  }
Exemple #15
0
  /**
   * @param columnIndex
   * @param bits
   * @param offset
   * @param length
   * @param targetCalendar
   * @param tz
   * @param rollForward
   * @param conn
   * @param rs
   * @return
   * @throws SQLException
   */
  protected Time getNativeTime(
      int columnIndex,
      byte[] bits,
      int offset,
      int length,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    int hour = 0;
    int minute = 0;
    int seconds = 0;

    if (length != 0) {
      // bits[0] // skip tm->neg
      // binaryData.readLong(); // skip daysPart
      hour = bits[offset + 5];
      minute = bits[offset + 6];
      seconds = bits[offset + 7];
    }

    if (!rs.useLegacyDatetimeCode) {
      return TimeUtil.fastTimeCreate(
          hour, minute, seconds, targetCalendar, this.exceptionInterceptor);
    }

    Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();

    synchronized (sessionCalendar) {
      Time time =
          TimeUtil.fastTimeCreate(
              sessionCalendar, hour, minute, seconds, this.exceptionInterceptor);

      Time adjustedTime =
          TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              time,
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);

      return adjustedTime;
    }
  }
Exemple #16
0
  // Write a String using the specified character encoding
  final void writeStringNoNull(
      String s,
      String encoding,
      String serverEncoding,
      boolean parserKnowsUnicode,
      MySQLConnection conn)
      throws UnsupportedEncodingException, SQLException {
    byte[] b =
        StringUtils.getBytes(
            s, encoding, serverEncoding, parserKnowsUnicode, conn, conn.getExceptionInterceptor());

    int len = b.length;
    ensureCapacity(len);
    System.arraycopy(b, 0, this.byteBuffer, this.position, len);
    this.position += len;
  }
Exemple #17
0
 @Test
 public void shouldDoStuffWithDatabase() throws SQLException {
   try (MySQLConnection conn = MySQLConnection.forTestDatabase("readbinlog_test"); ) {
     conn.connect();
     // Set up the table as one transaction and wait to see the events ...
     conn.execute(
         "DROP TABLE IF EXISTS person",
         "CREATE TABLE person ("
             + "  name VARCHAR(255) primary key,"
             + "  birthdate DATE NULL,"
             + "  age INTEGER NULL DEFAULT 10,"
             + "  salary DECIMAL(5,2),"
             + "  bitStr BIT(18)"
             + ")");
     conn.execute("SELECT * FROM person");
     try (ResultSet rs =
         conn.connection().getMetaData().getColumns("readbinlog_test", null, null, null)) {
       // if ( Testing.Print.isEnabled() ) conn.print(rs);
     }
   }
 }
Exemple #18
0
  protected final java.sql.Date getDateFast(
      int columnIndex,
      byte[] dateAsBytes,
      int offset,
      int length,
      MySQLConnection conn,
      ResultSetImpl rs,
      Calendar targetCalendar)
      throws SQLException {

    int year = 0;
    int month = 0;
    int day = 0;

    try {
      if (dateAsBytes == null) {
        return null;
      }

      boolean allZeroDate = true;

      boolean onlyTimePresent = false;

      for (int i = 0; i < length; i++) {
        if (dateAsBytes[offset + i] == ':') {
          onlyTimePresent = true;
          break;
        }
      }

      for (int i = 0; i < length; i++) {
        byte b = dateAsBytes[offset + i];

        if (b == ' ' || b == '-' || b == '/') {
          onlyTimePresent = false;
        }

        if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/' && b != '.') {
          allZeroDate = false;

          break;
        }
      }

      if (!onlyTimePresent && allZeroDate) {

        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
            conn.getZeroDateTimeBehavior())) {

          return null;
        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
            conn.getZeroDateTimeBehavior())) {
          throw SQLError.createSQLException(
              "Value '"
                  + StringUtils.toString(dateAsBytes)
                  + "' can not be represented as java.sql.Date",
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor);
        }

        // We're left with the case of 'round' to a date Java _can_
        // represent, which is '0001-01-01'.
        return rs.fastDateCreate(targetCalendar, 1, 1, 1);

      } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
        // Convert from TIMESTAMP
        switch (length) {
          case 29:
          case 21:
          case 19:
            { // java.sql.Timestamp format
              year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 4);
              month = StringUtils.getInt(dateAsBytes, offset + 5, offset + 7);
              day = StringUtils.getInt(dateAsBytes, offset + 8, offset + 10);

              return rs.fastDateCreate(targetCalendar, year, month, day);
            }

          case 14:
          case 8:
            {
              year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 4);
              month = StringUtils.getInt(dateAsBytes, offset + 4, offset + 6);
              day = StringUtils.getInt(dateAsBytes, offset + 6, offset + 8);

              return rs.fastDateCreate(targetCalendar, year, month, day);
            }

          case 12:
          case 10:
          case 6:
            {
              year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 2);

              if (year <= 69) {
                year = year + 100;
              }

              month = StringUtils.getInt(dateAsBytes, offset + 2, offset + 4);
              day = StringUtils.getInt(dateAsBytes, offset + 4, offset + 6);

              return rs.fastDateCreate(targetCalendar, year + 1900, month, day);
            }

          case 4:
            {
              year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 4);

              if (year <= 69) {
                year = year + 100;
              }

              month = StringUtils.getInt(dateAsBytes, offset + 2, offset + 4);

              return rs.fastDateCreate(targetCalendar, year + 1900, month, 1);
            }

          case 2:
            {
              year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 2);

              if (year <= 69) {
                year = year + 100;
              }

              return rs.fastDateCreate(targetCalendar, year + 1900, 1, 1);
            }

          default:
            throw SQLError.createSQLException(
                Messages.getString(
                    "ResultSet.Bad_format_for_Date",
                    new Object[] {
                      StringUtils.toString(dateAsBytes), Integer.valueOf(columnIndex + 1)
                    }),
                SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
                this.exceptionInterceptor); // $NON-NLS-1$
        } /* endswitch */
      } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {

        if (length == 2 || length == 1) {
          year = StringUtils.getInt(dateAsBytes, offset, offset + length);

          if (year <= 69) {
            year = year + 100;
          }

          year += 1900;
        } else {
          year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 4);
        }

        return rs.fastDateCreate(targetCalendar, year, 1, 1);
      } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
        return rs.fastDateCreate(targetCalendar, 1970, 1, 1); // Return EPOCH
      } else {
        if (length < 10) {
          if (length == 8) {
            return rs.fastDateCreate(targetCalendar, 1970, 1, 1); // Return
            // EPOCH for
            // TIME
          }

          throw SQLError.createSQLException(
              Messages.getString(
                  "ResultSet.Bad_format_for_Date",
                  new Object[] {
                    StringUtils.toString(dateAsBytes), Integer.valueOf(columnIndex + 1)
                  }),
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor); // $NON-NLS-1$
        }

        if (length != 18) {
          year = StringUtils.getInt(dateAsBytes, offset + 0, offset + 4);
          month = StringUtils.getInt(dateAsBytes, offset + 5, offset + 7);
          day = StringUtils.getInt(dateAsBytes, offset + 8, offset + 10);
        } else {
          // JDK-1.3 timestamp format, not real easy to parse
          // positionally :p
          StringTokenizer st =
              new StringTokenizer(
                  StringUtils.toString(dateAsBytes, offset, length, "ISO8859_1"), "- ");

          year = Integer.parseInt(st.nextToken());
          month = Integer.parseInt(st.nextToken());
          day = Integer.parseInt(st.nextToken());
        }
      }

      return rs.fastDateCreate(targetCalendar, year, month, day);
    } catch (SQLException sqlEx) {
      throw sqlEx; // don't re-wrap
    } catch (Exception e) {
      SQLException sqlEx =
          SQLError.createSQLException(
              Messages.getString(
                  "ResultSet.Bad_format_for_Date",
                  new Object[] {
                    StringUtils.toString(dateAsBytes), Integer.valueOf(columnIndex + 1)
                  }),
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor); // $NON-NLS-1$
      sqlEx.initCause(e);

      throw sqlEx;
    }
  }
Exemple #19
0
  protected Timestamp getTimestampFast(
      int columnIndex,
      byte[] timestampAsBytes,
      int offset,
      int length,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    try {
      Calendar sessionCalendar =
          conn.getUseJDBCCompliantTimezoneShift()
              ? conn.getUtcCalendar()
              : rs.getCalendarInstanceForSessionOrNew();

      synchronized (sessionCalendar) {
        boolean allZeroTimestamp = true;

        boolean onlyTimePresent = false;

        for (int i = 0; i < length; i++) {
          if (timestampAsBytes[offset + i] == ':') {
            onlyTimePresent = true;
            break;
          }
        }

        for (int i = 0; i < length; i++) {
          byte b = timestampAsBytes[offset + i];

          if (b == ' ' || b == '-' || b == '/') {
            onlyTimePresent = false;
          }

          if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/' && b != '.') {
            allZeroTimestamp = false;

            break;
          }
        }

        if (!onlyTimePresent && allZeroTimestamp) {

          if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
              conn.getZeroDateTimeBehavior())) {

            return null;
          } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
              conn.getZeroDateTimeBehavior())) {
            throw SQLError.createSQLException(
                "Value '"
                    + StringUtils.toString(timestampAsBytes)
                    + "' can not be represented as java.sql.Timestamp",
                SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
                this.exceptionInterceptor);
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(tz, 1, 1, 1, 0, 0, 0, 0);
          }
          // We're left with the case of 'round' to a date Java _can_
          // represent, which is '0001-01-01'.
          return rs.fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);

        } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(
                tz, StringUtils.getInt(timestampAsBytes, offset, 4), 1, 1, 0, 0, 0, 0);
          }

          return TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              rs.fastTimestampCreate(
                  sessionCalendar,
                  StringUtils.getInt(timestampAsBytes, offset, 4),
                  1,
                  1,
                  0,
                  0,
                  0,
                  0),
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);
        } else {
          if (timestampAsBytes[offset + length - 1] == '.') {
            length--;
          }

          // Convert from TIMESTAMP or DATE

          int year = 0;
          int month = 0;
          int day = 0;
          int hour = 0;
          int minutes = 0;
          int seconds = 0;
          int nanos = 0;

          switch (length) {
            case 29:
            case 26:
            case 25:
            case 24:
            case 23:
            case 22:
            case 21:
            case 20:
            case 19:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 5, offset + 7);
                day = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                hour = StringUtils.getInt(timestampAsBytes, offset + 11, offset + 13);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 14, offset + 16);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 17, offset + 19);

                nanos = 0;

                if (length > 19) {
                  int decimalIndex = -1;

                  for (int i = 0; i < length; i++) {
                    if (timestampAsBytes[offset + i] == '.') {
                      decimalIndex = i;
                    }
                  }

                  if (decimalIndex != -1) {
                    if ((decimalIndex + 2) <= length) {
                      nanos =
                          StringUtils.getInt(
                              timestampAsBytes, offset + decimalIndex + 1, offset + length);

                      int numDigits = (length) - (decimalIndex + 1);

                      if (numDigits < 9) {
                        int factor = (int) (Math.pow(10, 9 - numDigits));
                        nanos = nanos * factor;
                      }
                    } else {
                      throw new IllegalArgumentException(); // re-thrown
                      // further
                      // down
                      // with
                      // a
                      // much better error message
                    }
                  }
                }

                break;
              }

            case 14:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                day = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                hour = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 10, offset + 12);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 12, offset + 14);

                break;
              }

            case 12:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                hour = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 10, offset + 12);

                break;
              }

            case 10:
              {
                boolean hasDash = false;

                for (int i = 0; i < length; i++) {
                  if (timestampAsBytes[offset + i] == '-') {
                    hasDash = true;
                    break;
                  }
                }

                if ((this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
                    || hasDash) {
                  year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                  month = StringUtils.getInt(timestampAsBytes, offset + 5, offset + 7);
                  day = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                  hour = 0;
                  minutes = 0;
                } else {
                  year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                  if (year <= 69) {
                    year = (year + 100);
                  }

                  month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                  day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                  hour = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                  minutes = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);

                  year += 1900; // two-digit year
                }

                break;
              }

            case 8:
              {
                boolean hasColon = false;

                for (int i = 0; i < length; i++) {
                  if (timestampAsBytes[offset + i] == ':') {
                    hasColon = true;
                    break;
                  }
                }

                if (hasColon) {
                  hour = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);
                  minutes = StringUtils.getInt(timestampAsBytes, offset + 3, offset + 5);
                  seconds = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);

                  year = 1970;
                  month = 1;
                  day = 1;

                  break;
                }

                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                day = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);

                year -= 1900;
                month--;

                break;
              }

            case 6:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);

                break;
              }

            case 4:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);

                day = 1;

                break;
              }

            case 2:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;
                month = 1;
                day = 1;

                break;
              }

            default:
              throw new java.sql.SQLException(
                  "Bad format for Timestamp '"
                      + StringUtils.toString(timestampAsBytes)
                      + "' in column "
                      + (columnIndex + 1)
                      + ".",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(
                tz, year, month, day, hour, minutes, seconds, nanos);
          }

          return TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              rs.fastTimestampCreate(
                  sessionCalendar, year, month, day, hour, minutes, seconds, nanos),
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);
        }
      }
    } catch (RuntimeException e) {
      SQLException sqlEx =
          SQLError.createSQLException(
              "Cannot convert value '"
                  + getString(columnIndex, "ISO8859_1", conn)
                  + "' from column "
                  + (columnIndex + 1)
                  + " to TIMESTAMP.",
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor);
      sqlEx.initCause(e);

      throw sqlEx;
    }
  }
Exemple #20
0
  protected Object getNativeDateTimeValue(
      int columnIndex,
      byte[] bits,
      int offset,
      int length,
      Calendar targetCalendar,
      int jdbcType,
      int mysqlType,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    int year = 0;
    int month = 0;
    int day = 0;

    int hour = 0;
    int minute = 0;
    int seconds = 0;

    int nanos = 0;

    if (bits == null) {

      return null;
    }

    Calendar sessionCalendar =
        conn.getUseJDBCCompliantTimezoneShift()
            ? conn.getUtcCalendar()
            : rs.getCalendarInstanceForSessionOrNew();

    boolean populatedFromDateTimeValue = false;

    switch (mysqlType) {
      case MysqlDefs.FIELD_TYPE_DATETIME:
      case MysqlDefs.FIELD_TYPE_TIMESTAMP:
        populatedFromDateTimeValue = true;

        if (length != 0) {
          year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
          month = bits[offset + 2];
          day = bits[offset + 3];

          if (length > 4) {
            hour = bits[offset + 4];
            minute = bits[offset + 5];
            seconds = bits[offset + 6];
          }

          if (length > 7) {
            // MySQL uses microseconds
            nanos =
                ((bits[offset + 7] & 0xff)
                        | ((bits[offset + 8] & 0xff) << 8)
                        | ((bits[offset + 9] & 0xff) << 16)
                        | ((bits[offset + 10] & 0xff) << 24))
                    * 1000;
          }
        }

        break;
      case MysqlDefs.FIELD_TYPE_DATE:
        populatedFromDateTimeValue = true;

        if (bits.length != 0) {
          year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
          month = bits[offset + 2];
          day = bits[offset + 3];
        }

        break;
      case MysqlDefs.FIELD_TYPE_TIME:
        populatedFromDateTimeValue = true;

        if (bits.length != 0) {
          // bits[0] // skip tm->neg
          // binaryData.readLong(); // skip daysPart
          hour = bits[offset + 5];
          minute = bits[offset + 6];
          seconds = bits[offset + 7];
        }

        year = 1970;
        month = 1;
        day = 1;

        break;
      default:
        populatedFromDateTimeValue = false;
    }

    switch (jdbcType) {
      case Types.TIME:
        if (populatedFromDateTimeValue) {
          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimeCreate(
                hour, minute, seconds, targetCalendar, this.exceptionInterceptor);
          }

          Time time =
              TimeUtil.fastTimeCreate(
                  rs.getCalendarInstanceForSessionOrNew(),
                  hour,
                  minute,
                  seconds,
                  this.exceptionInterceptor);

          Time adjustedTime =
              TimeUtil.changeTimezone(
                  conn,
                  sessionCalendar,
                  targetCalendar,
                  time,
                  conn.getServerTimezoneTZ(),
                  tz,
                  rollForward);

          return adjustedTime;
        }

        return rs.getNativeTimeViaParseConversion(columnIndex + 1, targetCalendar, tz, rollForward);

      case Types.DATE:
        if (populatedFromDateTimeValue) {
          if ((year == 0) && (month == 0) && (day == 0)) {
            if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
                conn.getZeroDateTimeBehavior())) {

              return null;
            } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
                conn.getZeroDateTimeBehavior())) {
              throw new SQLException(
                  "Value '0000-00-00' can not be represented as java.sql.Date",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
            }

            year = 1;
            month = 1;
            day = 1;
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastDateCreate(year, month, day, targetCalendar);
          }

          return rs.fastDateCreate(rs.getCalendarInstanceForSessionOrNew(), year, month, day);
        }

        return rs.getNativeDateViaParseConversion(columnIndex + 1);
      case Types.TIMESTAMP:
        if (populatedFromDateTimeValue) {
          if ((year == 0) && (month == 0) && (day == 0)) {
            if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
                conn.getZeroDateTimeBehavior())) {

              return null;
            } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
                conn.getZeroDateTimeBehavior())) {
              throw new SQLException(
                  "Value '0000-00-00' can not be represented as java.sql.Timestamp",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
            }

            year = 1;
            month = 1;
            day = 1;
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minute, seconds, nanos);
          }

          Timestamp ts =
              rs.fastTimestampCreate(
                  rs.getCalendarInstanceForSessionOrNew(),
                  year,
                  month,
                  day,
                  hour,
                  minute,
                  seconds,
                  nanos);

          Timestamp adjustedTs =
              TimeUtil.changeTimezone(
                  conn,
                  sessionCalendar,
                  targetCalendar,
                  ts,
                  conn.getServerTimezoneTZ(),
                  tz,
                  rollForward);

          return adjustedTs;
        }

        return rs.getNativeTimestampViaParseConversion(
            columnIndex + 1, targetCalendar, tz, rollForward);

      default:
        throw new SQLException(
            "Internal error - conversion method doesn't support this type",
            SQLError.SQL_STATE_GENERAL_ERROR);
    }
  }
Exemple #21
0
  protected Timestamp getNativeTimestamp(
      byte[] bits,
      int offset,
      int length,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {
    int year = 0;
    int month = 0;
    int day = 0;

    int hour = 0;
    int minute = 0;
    int seconds = 0;

    int nanos = 0;

    if (length != 0) {
      year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
      month = bits[offset + 2];
      day = bits[offset + 3];

      if (length > 4) {
        hour = bits[offset + 4];
        minute = bits[offset + 5];
        seconds = bits[offset + 6];
      }

      if (length > 7) {
        // MySQL uses microseconds
        nanos =
            ((bits[offset + 7] & 0xff)
                    | ((bits[offset + 8] & 0xff) << 8)
                    | ((bits[offset + 9] & 0xff) << 16)
                    | ((bits[offset + 10] & 0xff) << 24))
                * 1000;
      }
    }

    if (length == 0 || ((year == 0) && (month == 0) && (day == 0))) {
      if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
          conn.getZeroDateTimeBehavior())) {

        return null;
      } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
          conn.getZeroDateTimeBehavior())) {
        throw SQLError.createSQLException(
            "Value '0000-00-00' can not be represented as java.sql.Timestamp",
            SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
            this.exceptionInterceptor);
      }

      year = 1;
      month = 1;
      day = 1;
    }

    if (!rs.useLegacyDatetimeCode) {
      return TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minute, seconds, nanos);
    }

    Calendar sessionCalendar =
        conn.getUseJDBCCompliantTimezoneShift()
            ? conn.getUtcCalendar()
            : rs.getCalendarInstanceForSessionOrNew();

    synchronized (sessionCalendar) {
      Timestamp ts =
          rs.fastTimestampCreate(sessionCalendar, year, month, day, hour, minute, seconds, nanos);

      Timestamp adjustedTs =
          TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              ts,
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);

      return adjustedTs;
    }
  }
Exemple #22
0
  protected Time getTimeFast(
      int columnIndex,
      byte[] timeAsBytes,
      int offset,
      int fullLength,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    int hr = 0;
    int min = 0;
    int sec = 0;
    int nanos = 0;

    int decimalIndex = -1;

    try {

      if (timeAsBytes == null) {
        return null;
      }

      boolean allZeroTime = true;
      boolean onlyTimePresent = false;

      for (int i = 0; i < fullLength; i++) {
        if (timeAsBytes[offset + i] == ':') {
          onlyTimePresent = true;
          break;
        }
      }

      for (int i = 0; i < fullLength; i++) {
        if (timeAsBytes[offset + i] == '.') {
          decimalIndex = i;
          break;
        }
      }

      for (int i = 0; i < fullLength; i++) {
        byte b = timeAsBytes[offset + i];

        if (b == ' ' || b == '-' || b == '/') {
          onlyTimePresent = false;
        }

        if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/' && b != '.') {
          allZeroTime = false;

          break;
        }
      }

      if (!onlyTimePresent && allZeroTime) {
        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
            conn.getZeroDateTimeBehavior())) {
          return null;
        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
            conn.getZeroDateTimeBehavior())) {
          throw SQLError.createSQLException(
              "Value '"
                  + StringUtils.toString(timeAsBytes)
                  + "' can not be represented as java.sql.Time",
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor);
        }

        // We're left with the case of 'round' to a time Java _can_
        // represent, which is '00:00:00'
        return rs.fastTimeCreate(targetCalendar, 0, 0, 0);
      }

      Field timeColField = this.metadata[columnIndex];

      int length = fullLength;

      if (decimalIndex != -1) {

        length = decimalIndex;

        if ((decimalIndex + 2) <= fullLength) {
          nanos = StringUtils.getInt(timeAsBytes, offset + decimalIndex + 1, offset + fullLength);

          int numDigits = (fullLength) - (decimalIndex + 1);

          if (numDigits < 9) {
            int factor = (int) (Math.pow(10, 9 - numDigits));
            nanos = nanos * factor;
          }
        } else {
          throw new IllegalArgumentException(); // re-thrown
          // further
          // down
          // with
          // a
          // much better error message
        }
      }

      if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {

        switch (length) {
          case 19:
            { // YYYY-MM-DD hh:mm:ss
              hr = StringUtils.getInt(timeAsBytes, offset + length - 8, offset + length - 6);
              min = StringUtils.getInt(timeAsBytes, offset + length - 5, offset + length - 3);
              sec = StringUtils.getInt(timeAsBytes, offset + length - 2, offset + length);
            }

            break;
          case 14:
          case 12:
            {
              hr = StringUtils.getInt(timeAsBytes, offset + length - 6, offset + length - 4);
              min = StringUtils.getInt(timeAsBytes, offset + length - 4, offset + length - 2);
              sec = StringUtils.getInt(timeAsBytes, offset + length - 2, offset + length);
            }

            break;

          case 10:
            {
              hr = StringUtils.getInt(timeAsBytes, offset + 6, offset + 8);
              min = StringUtils.getInt(timeAsBytes, offset + 8, offset + 10);
              sec = 0;
            }

            break;

          default:
            throw SQLError.createSQLException(
                Messages.getString(
                        "ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
                    + (columnIndex + 1)
                    + "("
                    + timeColField
                    + ").",
                SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
                this.exceptionInterceptor);
        } /* endswitch */

        @SuppressWarnings("unused")
        SQLWarning precisionLost =
            new SQLWarning(
                Messages.getString(
                        "ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
                    + columnIndex
                    + "("
                    + timeColField
                    + ").");
        /*
         * if (this.warningChain == null) { this.warningChain =
         * precisionLost; } else {
         * this.warningChain.setNextWarning(precisionLost); }
         */
      } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
        hr = StringUtils.getInt(timeAsBytes, offset + 11, offset + 13);
        min = StringUtils.getInt(timeAsBytes, offset + 14, offset + 16);
        sec = StringUtils.getInt(timeAsBytes, offset + 17, offset + 19);

        @SuppressWarnings("unused")
        SQLWarning precisionLost =
            new SQLWarning(
                Messages.getString(
                        "ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
                    + (columnIndex + 1)
                    + "("
                    + timeColField
                    + ").");

        /*
         * if (this.warningChain == null) { this.warningChain =
         * precisionLost; } else {
         * this.warningChain.setNextWarning(precisionLost); }
         */
      } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
        return rs.fastTimeCreate(null, 0, 0, 0); // midnight on the
        // given
        // date
      } else {
        // convert a String to a Time
        if ((length != 5) && (length != 8)) {
          throw SQLError.createSQLException(
              Messages.getString("ResultSet.Bad_format_for_Time____267") // $NON-NLS-1$
                  + StringUtils.toString(timeAsBytes)
                  + Messages.getString("ResultSet.___in_column__268")
                  + (columnIndex + 1),
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor);
        }

        hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2);
        min = StringUtils.getInt(timeAsBytes, offset + 3, offset + 5);
        sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes, offset + 6, offset + 8);
      }

      Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();

      if (!rs.useLegacyDatetimeCode) {
        // TODO: return rs.fastTimeCreate(targetCalendar, hr, min, sec, nanos);
        // java.sql.Time doesn't contain fractional part, so PreparedStatement.setTime/getTime can't
        // deal with TIME(n) fractional part.
        // There may be better mappings to high-precision time coming in JDBC-5 with the adoption of
        // JSR-310.
        return rs.fastTimeCreate(targetCalendar, hr, min, sec);
      }

      synchronized (sessionCalendar) {
        return TimeUtil.changeTimezone(
            conn,
            sessionCalendar,
            targetCalendar,
            rs.fastTimeCreate(sessionCalendar, hr, min, sec),
            conn.getServerTimezoneTZ(),
            tz,
            rollForward);
        // TODO: min, sec, nanos), conn.getServerTimezoneTZ(), tz,
        // java.sql.Time doesn't contain fractional part, so PreparedStatement.setTime/getTime can't
        // deal with TIME(n) fractional part.
        // There may be better mappings to high-precision time coming in JDBC-5 with the adoption of
        // JSR-310.
      }
    } catch (RuntimeException ex) {
      SQLException sqlEx =
          SQLError.createSQLException(
              ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
      sqlEx.initCause(ex);

      throw sqlEx;
    }
  }
Exemple #23
0
  /**
   * We're done.
   *
   * @throws SQLException if a database error occurs
   */
  public void close() throws SQLException {
    // Belt and suspenders here - if we don't have a reference to the connection it's more than
    // likely dead/gone and we won't be able to consume rows anyway

    Object mutex = this;

    MySQLConnection conn = null;

    if (this.owner != null) {
      conn = this.owner.connection;

      if (conn != null) {
        mutex = conn.getConnectionMutex();
      }
    }

    boolean hadMore = false;
    int howMuchMore = 0;

    synchronized (mutex) {
      // drain the rest of the records.
      while (next() != null) {
        hadMore = true;
        howMuchMore++;

        if (howMuchMore % 100 == 0) {
          Thread.yield();
        }
      }

      if (conn != null) {
        if (!conn.getClobberStreamingResults() && conn.getNetTimeoutForStreamingResults() > 0) {
          String oldValue = conn.getServerVariable("net_write_timeout");

          if (oldValue == null || oldValue.length() == 0) {
            oldValue = "60"; // the current default
          }

          this.io.clearInputStream();

          java.sql.Statement stmt = null;

          try {
            stmt = conn.createStatement();
            ((com.mysql.jdbc.StatementImpl) stmt)
                .executeSimpleNonQuery(conn, "SET net_write_timeout=" + oldValue);
          } finally {
            if (stmt != null) {
              stmt.close();
            }
          }
        }

        if (conn.getUseUsageAdvisor()) {
          if (hadMore) {

            ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(conn);

            eventSink.consumeEvent(
                new ProfilerEvent(
                    ProfilerEvent.TYPE_WARN,
                    "",
                    this.owner.owningStatement == null
                        ? "N/A"
                        : this.owner.owningStatement.currentCatalog,
                    this.owner.connectionId,
                    this.owner.owningStatement == null ? -1 : this.owner.owningStatement.getId(),
                    -1,
                    System.currentTimeMillis(),
                    0,
                    Constants.MILLIS_I18N,
                    null,
                    null,
                    Messages.getString("RowDataDynamic.2")
                        + howMuchMore
                        + Messages.getString("RowDataDynamic.3")
                        + Messages.getString("RowDataDynamic.4")
                        + Messages.getString("RowDataDynamic.5")
                        + Messages.getString("RowDataDynamic.6")
                        + this.owner.pointOfOrigin));
          }
        }
      }
    }

    this.metadata = null;
    this.owner = null;
  }
 /**
  * Propagates the connection proxy down through all live connections.
  *
  * @param proxyConn The top level connection in the multi-host connections chain.
  */
 @Override
 protected void propagateProxyDown(MySQLConnection proxyConn) {
   for (MySQLConnection c : this.liveConnections.values()) {
     c.setProxy(proxyConn);
   }
 }