Search in sources :

Example 1 with DefaultValue

use of org.adbcj.support.DefaultValue in project adbcj by mheath.

the class JdbcConnection method executeQuery.

public <T> DbSessionFuture<T> executeQuery(final String sql, final ResultEventHandler<T> eventHandler, final T accumulator) {
    checkClosed();
    logger.trace("Scheduling query '{}'", sql);
    return enqueueTransactionalRequest(new CallableRequest<T>() {

        @Override
        protected T doCall() throws Exception {
            logger.debug("Executing query '{}'", sql);
            Statement jdbcStatement = jdbcConnection.createStatement();
            java.sql.ResultSet jdbcResultSet = null;
            try {
                // Execute query
                jdbcResultSet = jdbcStatement.executeQuery(sql);
                // Fetch meta data
                ResultSetMetaData metaData = jdbcResultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                List<Field> fields = new ArrayList<Field>(columnCount);
                eventHandler.startFields(accumulator);
                for (int i = 1; i <= columnCount; i++) {
                    Field field = new DefaultField(i - 1, metaData.getCatalogName(i), metaData.getSchemaName(i), metaData.getTableName(i), metaData.getTableName(i), Type.fromJdbcType(metaData.getColumnType(i)), metaData.getColumnLabel(i), metaData.getCatalogName(i), metaData.getPrecision(i), metaData.getScale(i), metaData.isAutoIncrement(i), metaData.isCaseSensitive(i), metaData.isCurrency(i), metaData.isDefinitelyWritable(i), metaData.isNullable(i) == 1, metaData.isReadOnly(i), metaData.isSearchable(i), metaData.isSigned(i), metaData.isWritable(i), metaData.getColumnClassName(i));
                    fields.add(field);
                    eventHandler.field(field, accumulator);
                }
                eventHandler.endFields(accumulator);
                eventHandler.startResults(accumulator);
                while (jdbcResultSet.next()) {
                    eventHandler.startRow(accumulator);
                    for (int i = 1; i <= columnCount; i++) {
                        Field field = fields.get(i - 1);
                        Object value = null;
                        switch(field.getColumnType()) {
                            case BIGINT:
                                value = jdbcResultSet.getLong(i);
                                break;
                            case INTEGER:
                                value = jdbcResultSet.getInt(i);
                                break;
                            case VARCHAR:
                                value = jdbcResultSet.getString(i);
                                break;
                            default:
                                throw new IllegalStateException("Don't know how to handle field to type " + field.getColumnType());
                        }
                        if (jdbcResultSet.wasNull()) {
                            value = null;
                        }
                        eventHandler.value(new DefaultValue(field, value), accumulator);
                    }
                    eventHandler.endRow(accumulator);
                }
                eventHandler.endResults(accumulator);
                return accumulator;
            } finally {
                if (jdbcResultSet != null) {
                    jdbcResultSet.close();
                }
                if (jdbcStatement != null) {
                    jdbcStatement.close();
                }
            }
        }
    });
}
Also used : PreparedStatement(org.adbcj.PreparedStatement) Statement(java.sql.Statement) DbException(org.adbcj.DbException) SQLException(java.sql.SQLException) DbSessionClosedException(org.adbcj.DbSessionClosedException) ResultSetMetaData(java.sql.ResultSetMetaData) DefaultField(org.adbcj.support.DefaultField) Field(org.adbcj.Field) DefaultValue(org.adbcj.support.DefaultValue) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) DefaultField(org.adbcj.support.DefaultField)

Example 2 with DefaultValue

use of org.adbcj.support.DefaultValue in project adbcj by mheath.

the class MySqlClientDecoder method doDecode.

protected ServerPacket doDecode(InputStream input, boolean block) throws IOException {
    // If we can't block, make sure there's enough data available to read
    if (!block) {
        if (input.available() < 3) {
            return null;
        }
    }
    // Read the packet length
    final int length = IoUtils.readUnsignedMediumInt(input);
    // If we can't block, make sure the stream has enough data
    if (!block) {
        // Make sure we have enough data for the packet length and the packet number
        if (input.available() < length + 1) {
            return null;
        }
    }
    final int packetNumber = IoUtils.safeRead(input);
    BoundedInputStream in = new BoundedInputStream(input, length);
    boolean threwException = false;
    try {
        logger.trace("Decoding in state {}", state);
        switch(state) {
            case CONNECTING:
                ServerGreeting serverGreeting = decodeServerGreeting(in, length, packetNumber);
                state = State.RESPONSE;
                return serverGreeting;
            case RESPONSE:
                int fieldCount = in.read();
                if (fieldCount == RESPONSE_OK) {
                    // Create Ok response
                    return decodeOkResponse(in, length, packetNumber);
                }
                if (fieldCount == RESPONSE_ERROR) {
                    // Create error response
                    ErrorResponse response = decodeErrorResponse(in, length, packetNumber);
                    return response;
                }
                if (fieldCount == RESPONSE_EOF) {
                    throw new IllegalStateException("Did not expect an EOF response from the server");
                }
                // Must be receiving result set header
                // Get the number of fields. The largest this can be is a 24-bit
                // integer so cast to int is ok
                expectedFieldPackets = (int) IoUtils.readBinaryLengthEncoding(in, fieldCount);
                fields = new MysqlField[expectedFieldPackets];
                logger.trace("Field count {}", expectedFieldPackets);
                Long extra = null;
                if (in.getRemaining() > 0) {
                    extra = IoUtils.readBinaryLengthEncoding(in);
                }
                state = State.FIELD;
                return new ResultSetResponse(length, packetNumber, expectedFieldPackets, extra);
            case FIELD:
                ResultSetFieldResponse resultSetFieldResponse = decodeFieldResponse(in, length, packetNumber);
                expectedFieldPackets--;
                logger.trace("fieldPacketCount: {}", expectedFieldPackets);
                if (expectedFieldPackets == 0) {
                    state = State.FIELD_EOF;
                }
                return resultSetFieldResponse;
            case FIELD_EOF:
                fieldCount = in.read();
                if (fieldCount != RESPONSE_EOF) {
                    throw new IllegalStateException("Expected an EOF response from the server");
                }
                EofResponse fieldEof = decodeEofResponse(in, length, packetNumber, EofResponse.Type.FIELD);
                state = State.ROW;
                fieldIndex = 0;
                return fieldEof;
            case ROW:
                // This is only for checking for EOF
                fieldCount = in.read();
                if (fieldCount == RESPONSE_EOF) {
                    EofResponse rowEof = decodeEofResponse(in, length, packetNumber, EofResponse.Type.ROW);
                    state = State.RESPONSE;
                    return rowEof;
                }
                Value[] values = new Value[fields.length];
                for (int i = 0; i < fields.length; ) {
                    MysqlField field = fields[i++];
                    Object value = null;
                    if (fieldCount != IoUtils.NULL_VALUE) {
                        // We will have to move this as some datatypes will not be sent across the wire as strings
                        String strVal = IoUtils.readLengthCodedString(in, fieldCount, charset);
                        // TODO add decoding for all column types
                        switch(field.getColumnType()) {
                            case TINYINT:
                                value = Byte.valueOf(strVal);
                                break;
                            case INTEGER:
                            case BIGINT:
                                value = Long.valueOf(strVal);
                                break;
                            case VARCHAR:
                                value = strVal;
                                break;
                            default:
                                throw new IllegalStateException("Don't know how to handle column type of " + field.getColumnType());
                        }
                    }
                    values[field.getIndex()] = new DefaultValue(field, value);
                    if (i < fields.length) {
                        fieldCount = in.read();
                    }
                }
                return new ResultSetRowResponse(length, packetNumber, values);
            default:
                throw new IllegalStateException("Unkown decoder state " + state);
        }
    } catch (IOException e) {
        threwException = true;
        throw e;
    } catch (RuntimeException e) {
        threwException = true;
        throw e;
    } finally {
        if (!threwException && in.getRemaining() > 0) {
            throw new IllegalStateException("Buffer underrun occured; remaining bytes: " + in.getRemaining());
        }
    }
}
Also used : IOException(java.io.IOException) DefaultValue(org.adbcj.support.DefaultValue) Value(org.adbcj.Value) DefaultValue(org.adbcj.support.DefaultValue)

Example 3 with DefaultValue

use of org.adbcj.support.DefaultValue in project adbcj by mheath.

the class BackendMessageDecoder method decodeDataRow.

private DataRowMessage decodeDataRow(DecoderInputStream input) throws IOException {
    Charset charset = connectionState.getBackendCharset();
    PgField[] fields = connectionState.getCurrentResultSetFields();
    if (fields == null) {
        throw new IllegalStateException("Received a data row without any field definitions in the request payload");
    }
    int fieldCount = input.readUnsignedShort();
    Value[] values = new Value[fieldCount];
    for (int i = 0; i < fieldCount; i++) {
        int valueLength = input.readInt();
        PgField field = fields[i];
        Value value;
        if (valueLength < 0) {
            value = new DefaultValue(field, null);
        } else {
            String strVal;
            switch(field.getColumnType()) {
                case INTEGER:
                    switch(field.getFormatCode()) {
                        case BINARY:
                            value = new DefaultValue(field, input.readInt());
                            break;
                        case TEXT:
                            strVal = input.readString(valueLength, charset);
                            value = new DefaultValue(field, Integer.valueOf(strVal));
                            break;
                        default:
                            throw new IllegalStateException("Unable to decode format of " + field.getFormatCode());
                    }
                    break;
                case BIGINT:
                    switch(field.getFormatCode()) {
                        case BINARY:
                            value = new DefaultValue(field, (long) input.readInt() << 32 | input.readInt());
                            break;
                        case TEXT:
                            strVal = input.readString(valueLength, charset);
                            value = new DefaultValue(field, Long.valueOf(strVal));
                            break;
                        default:
                            throw new IllegalStateException("Unable to decode format of " + field.getFormatCode());
                    }
                    break;
                case VARCHAR:
                    strVal = input.readString(valueLength, charset);
                    value = new DefaultValue(field, strVal);
                    break;
                default:
                    // Advance buffer
                    input.skip(valueLength);
                    // TODO Handle remaining ADBCJ types
                    throw new IllegalStateException("Unable to decode column of type " + field.getColumnType());
            }
        }
        values[i] = value;
    }
    return new DataRowMessage(values);
}
Also used : DefaultValue(org.adbcj.support.DefaultValue) PgField(org.adbcj.postgresql.codec.PgField) DefaultValue(org.adbcj.support.DefaultValue) Value(org.adbcj.Value) Charset(java.nio.charset.Charset)

Aggregations

DefaultValue (org.adbcj.support.DefaultValue)3 Value (org.adbcj.Value)2 IOException (java.io.IOException)1 Charset (java.nio.charset.Charset)1 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1 Statement (java.sql.Statement)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 DbException (org.adbcj.DbException)1 DbSessionClosedException (org.adbcj.DbSessionClosedException)1 Field (org.adbcj.Field)1 PreparedStatement (org.adbcj.PreparedStatement)1 PgField (org.adbcj.postgresql.codec.PgField)1 DefaultField (org.adbcj.support.DefaultField)1