Search in sources :

Example 1 with RowValue

use of org.firebirdsql.gds.ng.fields.RowValue in project jaybird by FirebirdSQL.

the class AbstractStatementTest method testInsertSelectUTF8Value.

@Test
public void testInsertSelectUTF8Value() throws Exception {
    allocateStatement();
    // Insert UTF8 columns
    statement.prepare(INSERT_THEUTFVALUE);
    final RowDescriptor parametersInsert = statement.getParameterDescriptor();
    final RowValue parameterValuesInsert = parametersInsert.createDefaultFieldValues();
    parameterValuesInsert.getFieldValue(0).setFieldData(db.getDatatypeCoder().encodeInt(1));
    final Encoding utf8Encoding = db.getEncodingFactory().getEncodingForFirebirdName("UTF8");
    final String aEuro = "a\u20AC";
    final byte[] insertFieldData = utf8Encoding.encodeToCharset(aEuro);
    parameterValuesInsert.getFieldValue(1).setFieldData(insertFieldData);
    parameterValuesInsert.getFieldValue(2).setFieldData(insertFieldData);
    statement.execute(parameterValuesInsert);
    // Retrieve the just inserted UTF8 values from the database for comparison
    statement.prepare(SELECT_THEUTFVALUE);
    final RowDescriptor parametersSelect = statement.getParameterDescriptor();
    final RowValue parameterValuesSelect = parametersSelect.createDefaultFieldValues();
    parameterValuesSelect.getFieldValue(0).setFieldData(db.getDatatypeCoder().encodeInt(1));
    final SimpleStatementListener statementListener = new SimpleStatementListener();
    statement.addStatementListener(statementListener);
    statement.execute(parameterValuesSelect);
    statement.fetchRows(1);
    final List<RowValue> rows = statementListener.getRows();
    assertEquals("Expected a row", 1, rows.size());
    final RowValue selectResult = rows.get(0);
    final byte[] selectVarcharFieldData = selectResult.getFieldValue(0).getFieldData();
    final byte[] selectCharFieldData = selectResult.getFieldValue(1).getFieldData();
    assertEquals("Length of selected varchar field data", 4, selectVarcharFieldData.length);
    assertEquals("Length of selected char field data", 20, selectCharFieldData.length);
    String decodedVarchar = utf8Encoding.decodeFromCharset(selectVarcharFieldData);
    String decodedChar = utf8Encoding.decodeFromCharset(selectCharFieldData);
    assertEquals("Unexpected value for varchar", aEuro, decodedVarchar);
    assertEquals("Unexpected value for trimmed char", aEuro, decodedChar.trim());
    // Note artificial result from the way UTF8 is handled
    assertEquals("Unexpected length for char", 18, decodedChar.length());
    char[] spaceChars16 = new char[16];
    Arrays.fill(spaceChars16, ' ');
    assertEquals("Unexpected trailing characters for char", new String(spaceChars16), decodedChar.substring(2));
}
Also used : SimpleStatementListener(org.firebirdsql.gds.ng.wire.SimpleStatementListener) RowValue(org.firebirdsql.gds.ng.fields.RowValue) Encoding(org.firebirdsql.encodings.Encoding) RowDescriptor(org.firebirdsql.gds.ng.fields.RowDescriptor) Test(org.junit.Test)

Example 2 with RowValue

use of org.firebirdsql.gds.ng.fields.RowValue in project jaybird by FirebirdSQL.

the class AbstractStatementTest method test_ExecuteExecutableStoredProcedure.

@Test
public void test_ExecuteExecutableStoredProcedure() throws Exception {
    allocateStatement();
    statement.addStatementListener(listener);
    statement.prepare(EXECUTE_EXECUTABLE_STORED_PROCEDURE);
    FieldValue parameter1 = statement.getParameterDescriptor().getFieldDescriptor(0).createDefaultFieldValue();
    // Byte representation of 1
    parameter1.setFieldData(db.getDatatypeCoder().encodeInt(1));
    statement.execute(RowValue.of(parameter1));
    assertTrue("Expected singleton result for executable stored procedure", listener.hasSingletonResult());
    assertFalse("Expected no result set for executable stored procedure", listener.hasResultSet());
    assertTrue("Expected all rows to have been fetched", listener.isAllRowsFetched());
    assertEquals("Expected 1 row", 1, listener.getRows().size());
    RowValue fieldValues = listener.getRows().get(0);
    assertEquals("Expected one field", 1, fieldValues.getCount());
    FieldValue value = fieldValues.getFieldValue(0);
    assertEquals("Expected byte representation of 2", 2, db.getDatatypeCoder().decodeInt(value.getFieldData()));
}
Also used : RowValue(org.firebirdsql.gds.ng.fields.RowValue) FieldValue(org.firebirdsql.gds.ng.fields.FieldValue) Test(org.junit.Test)

Example 3 with RowValue

use of org.firebirdsql.gds.ng.fields.RowValue in project jaybird by FirebirdSQL.

the class FBManagedConnection method findSingleXid.

/**
 * Obtain a single prepared transaction branch from a resource manager, based on a Xid
 *
 * @param externalXid
 *            The Xid to find
 * @return The Xid if found, otherwise null.
 * @throws XAException
 *             An error has occurred. Possible values are XAER_RMERR,
 *             XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
 */
protected Xid findSingleXid(Xid externalXid) throws javax.transaction.xa.XAException {
    try {
        FbTransaction trHandle2 = database.startTransaction(tpb.getTransactionParameterBuffer());
        FbStatement stmtHandle2 = database.createStatement(trHandle2);
        GDSHelper gdsHelper2 = new GDSHelper(database);
        gdsHelper2.setCurrentTransaction(trHandle2);
        stmtHandle2.prepare(RECOVERY_QUERY_PARAMETRIZED);
        DataProvider dataProvider0 = new DataProvider(0);
        stmtHandle2.addStatementListener(dataProvider0);
        DataProvider dataProvider1 = new DataProvider(1);
        stmtHandle2.addStatementListener(dataProvider1);
        final RowValue parameters = stmtHandle2.getParameterDescriptor().createDefaultFieldValues();
        FBXid tempXid = new FBXid(externalXid);
        parameters.getFieldValue(0).setFieldData(tempXid.toBytes());
        stmtHandle2.execute(parameters);
        stmtHandle2.fetchRows(1);
        FBField field0 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(0), dataProvider0, gdsHelper2, false);
        FBField field1 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(1), dataProvider1, gdsHelper2, false);
        FBXid xid = null;
        if (dataProvider0.getRowCount() > 0) {
            dataProvider0.setRow(0);
            dataProvider1.setRow(0);
            long inLimboTxId = field0.getLong();
            byte[] inLimboMessage = field1.getBytes();
            try {
                xid = new FBXid(new ByteArrayInputStream(inLimboMessage), inLimboTxId);
            } catch (FBIncorrectXidException ex) {
                log.warn("ignoring XID stored with invalid format in RDB$TRANSACTIONS for RDB$TRANSACTION_ID=" + inLimboTxId);
            }
        }
        stmtHandle2.close();
        trHandle2.commit();
        return xid;
    } catch (SQLException | ResourceException e) {
        throw new FBXAException("can't perform query to fetch xids", XAException.XAER_RMFAIL, e);
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) SQLException(java.sql.SQLException) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FieldDataProvider(org.firebirdsql.jdbc.field.FieldDataProvider) ByteArrayInputStream(java.io.ByteArrayInputStream) RowValue(org.firebirdsql.gds.ng.fields.RowValue) ResourceException(javax.resource.ResourceException)

Example 4 with RowValue

use of org.firebirdsql.gds.ng.fields.RowValue in project jaybird by FirebirdSQL.

the class FBDatabaseMetaData method getTypeInfo.

/**
 * Gets a description of all the standard SQL types supported by
 * this database. They are ordered by DATA_TYPE and then by how
 * closely the data type maps to the corresponding JDBC SQL type.
 *
 * <P>Each type description has the following columns:
 *  <OL>
 *  <LI><B>TYPE_NAME</B> String => Type name
 *  <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
 *  <LI><B>PRECISION</B> int => maximum precision
 *  <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
 *      (may be null)
 *  <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
 *            (may be null)
 *  <LI><B>CREATE_PARAMS</B> String => parameters used in creating
 *      the type (may be null)
 *  <LI><B>NULLABLE</B> short => can you use NULL for this type?
 *      <UL>
 *      <LI> typeNoNulls - does not allow NULL values
 *      <LI> typeNullable - allows NULL values
 *      <LI> typeNullableUnknown - nullability unknown
 *      </UL>
 *  <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
 *  <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
 *      <UL>
 *      <LI> typePredNone - No support
 *      <LI> typePredChar - Only supported with WHERE .. LIKE
 *      <LI> typePredBasic - Supported except for WHERE .. LIKE
 *      <LI> typeSearchable - Supported for all WHERE ..
 *      </UL>
 *  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
 *  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
 *  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
 *      auto-increment value?
 *  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
 *      (may be null)
 *  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
 *  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
 *  <LI><B>SQL_DATA_TYPE</B> int => unused
 *  <LI><B>SQL_DATETIME_SUB</B> int => unused
 *  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
 *  </OL>
 *
 * @return <code>ResultSet</code> - each row is an SQL type description
 * @exception SQLException if a database access error occurs
 */
public ResultSet getTypeInfo() throws SQLException {
    final RowDescriptor rowDescriptor = new RowDescriptorBuilder(18, datatypeCoder).at(0).simple(SQL_VARYING, 31, "TYPE_NAME", "TYPEINFO").addField().at(1).simple(SQL_SHORT, 0, "DATA_TYPE", "TYPEINFO").addField().at(2).simple(SQL_LONG, 0, "PRECISION", "TYPEINFO").addField().at(3).simple(SQL_VARYING, 1, "LITERAL_PREFIX", "TYPEINFO").addField().at(4).simple(SQL_VARYING, 1, "LITERAL_SUFFIX", "TYPEINFO").addField().at(5).simple(SQL_VARYING, 31, "CREATE_PARAMS", "TYPEINFO").addField().at(6).simple(SQL_SHORT, 0, "NULLABLE", "TYPEINFO").addField().at(7).simple(SQL_TEXT, 1, "CASE_SENSITIVE", "TYPEINFO").addField().at(8).simple(SQL_SHORT, 0, "SEARCHABLE", "TYPEINFO").addField().at(9).simple(SQL_TEXT, 1, "UNSIGNED_ATTRIBUTE", "TYPEINFO").addField().at(10).simple(SQL_TEXT, 1, "FIXED_PREC_SCALE", "TYPEINFO").addField().at(11).simple(SQL_TEXT, 1, "AUTO_INCREMENT", "TYPEINFO").addField().at(12).simple(SQL_VARYING, 31, "LOCAL_TYPE_NAME", "TYPEINFO").addField().at(13).simple(SQL_SHORT, 0, "MINIMUM_SCALE", "TYPEINFO").addField().at(14).simple(SQL_SHORT, 0, "MAXIMUM_SCALE", "TYPEINFO").addField().at(15).simple(SQL_LONG, 0, "SQL_DATA_TYPE", "TYPEINFO").addField().at(16).simple(SQL_LONG, 0, "SQL_DATETIME_SUB", "TYPEINFO").addField().at(17).simple(SQL_LONG, 0, "NUM_PREC_RADIX", "TYPEINFO").addField().toRowDescriptor();
    final byte[] blobTypePred = firebirdSupportInfo.supportsFullSearchableBlobs() ? TYPE_SEARCHABLE : TYPE_PRED_BASIC;
    // dialect 3 only
    final List<RowValue> rows = new ArrayList<>(20);
    // DECFLOAT=-6001 (TODO Change when standardized)
    if (getDatabaseMajorVersion() >= 4) {
        rows.add(RowValue.of(rowDescriptor, getBytes("DECFLOAT"), createShort(JaybirdTypeCodes.DECFLOAT), DECFLOAT_34_PRECISION, null, null, getBytes("precision"), TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, VARIABLESCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_DEC34), null, RADIX_TEN));
    }
    // BIGINT=-5
    rows.add(RowValue.of(rowDescriptor, getBytes("BIGINT"), createShort(Types.BIGINT), BIGINT_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_INT64), null, RADIX_TEN));
    // LONGVARBINARY=-4
    rows.add(RowValue.of(rowDescriptor, getBytes("BLOB SUB_TYPE BINARY"), createShort(Types.LONGVARBINARY), INT_ZERO, null, null, null, TYPE_NULLABLE, CASESENSITIVE, blobTypePred, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_BLOB), null, RADIX_TEN));
    // VARBINARY=-3
    rows.add(RowValue.of(rowDescriptor, getBytes("VARCHAR"), createShort(Types.VARBINARY), createInt(32765), null, null, getBytes("length"), TYPE_NULLABLE, CASESENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_VARYING), null, RADIX_TEN));
    // BINARY=-2
    rows.add(RowValue.of(rowDescriptor, getBytes("CHAR"), createShort(Types.BINARY), createInt(32767), null, null, getBytes("length"), TYPE_NULLABLE, CASESENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_TEXT), null, RADIX_TEN));
    // LONGVARCHAR=-1
    rows.add(RowValue.of(rowDescriptor, getBytes("BLOB SUB_TYPE TEXT"), createShort(Types.LONGVARCHAR), INT_ZERO, getBytes("'"), getBytes("'"), null, TYPE_NULLABLE, CASESENSITIVE, blobTypePred, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_BLOB), null, RADIX_TEN));
    // CHAR=1
    rows.add(RowValue.of(rowDescriptor, getBytes("CHAR"), createShort(Types.CHAR), createInt(32767), getBytes("'"), getBytes("'"), getBytes("length"), TYPE_NULLABLE, CASESENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_TEXT), null, RADIX_TEN));
    // NUMERIC=2
    // TODO Handle DEC_FIXED
    rows.add(RowValue.of(rowDescriptor, getBytes("NUMERIC"), createShort(Types.NUMERIC), NUMERIC_PRECISION, null, null, getBytes("precision,scale"), TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, NUMERIC_PRECISION, createInt(SQL_INT64), null, RADIX_TEN));
    // DECIMAL=3
    // TODO Handle DEC_FIXED
    rows.add(RowValue.of(rowDescriptor, getBytes("DECIMAL"), createShort(Types.DECIMAL), DECIMAL_PRECISION, null, null, getBytes("precision,scale"), TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, DECIMAL_PRECISION, createInt(SQL_INT64), null, RADIX_TEN));
    // INTEGER=4
    rows.add(RowValue.of(rowDescriptor, getBytes("INTEGER"), createShort(Types.INTEGER), INTEGER_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_LONG), null, RADIX_TEN));
    // SMALLINT=5
    rows.add(RowValue.of(rowDescriptor, getBytes("SMALLINT"), createShort(Types.SMALLINT), SMALLINT_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_SHORT), null, RADIX_TEN));
    // FLOAT=6
    rows.add(RowValue.of(rowDescriptor, getBytes("FLOAT"), createShort(Types.FLOAT), FLOAT_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, VARIABLESCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_FLOAT), null, RADIX_TEN));
    // DOUBLE=8
    rows.add(RowValue.of(rowDescriptor, getBytes("DOUBLE PRECISION"), createShort(Types.DOUBLE), DOUBLE_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, SIGNED, VARIABLESCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_DOUBLE), null, RADIX_TEN));
    // VARCHAR=12
    rows.add(RowValue.of(rowDescriptor, getBytes("VARCHAR"), createShort(Types.VARCHAR), createInt(32765), getBytes("'"), getBytes("'"), getBytes("length"), TYPE_NULLABLE, CASESENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_VARYING), null, RADIX_TEN));
    // BOOLEAN=16
    if (getDatabaseMajorVersion() >= 3) {
        rows.add(RowValue.of(rowDescriptor, getBytes("BOOLEAN"), createShort(Types.BOOLEAN), BOOLEAN_PRECISION, null, null, null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_PRED_BASIC, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_BOOLEAN), null, RADIX_BINARY));
    }
    // DATE=91
    rows.add(RowValue.of(rowDescriptor, getBytes("DATE"), createShort(Types.DATE), DATE_PRECISION, getBytes("date'"), getBytes("'"), null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_TYPE_DATE), null, RADIX_TEN));
    // TIME=92
    rows.add(RowValue.of(rowDescriptor, getBytes("TIME"), createShort(Types.TIME), TIME_PRECISION, getBytes("time'"), getBytes("'"), null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_TYPE_TIME), null, RADIX_TEN));
    // TIMESTAMP=93
    rows.add(RowValue.of(rowDescriptor, getBytes("TIMESTAMP"), createShort(Types.TIMESTAMP), TIMESTAMP_PRECISION, getBytes("timestamp'"), getBytes("'"), null, TYPE_NULLABLE, CASEINSENSITIVE, TYPE_SEARCHABLE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_TIMESTAMP), null, RADIX_TEN));
    // OTHER=1111
    rows.add(RowValue.of(rowDescriptor, getBytes("ARRAY"), createShort(Types.OTHER), INT_ZERO, null, null, null, TYPE_NULLABLE, CASESENSITIVE, TYPE_PRED_NONE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_ARRAY), null, RADIX_TEN));
    // BLOB=2004
    // Should we split this into all negative blob types currently known in the DB?
    // Blob is potentially searchable with like, etc, acting as if it isn't.
    rows.add(RowValue.of(rowDescriptor, getBytes("BLOB SUB_TYPE <0 "), createShort(Types.BLOB), INT_ZERO, null, null, null, TYPE_NULLABLE, CASESENSITIVE, TYPE_PRED_NONE, UNSIGNED, FIXEDSCALE, NOTAUTOINC, null, SHORT_ZERO, SHORT_ZERO, createInt(SQL_BLOB), null, RADIX_TEN));
    return new FBResultSet(rowDescriptor, rows);
}
Also used : RowDescriptorBuilder(org.firebirdsql.gds.ng.fields.RowDescriptorBuilder) RowValue(org.firebirdsql.gds.ng.fields.RowValue) RowDescriptor(org.firebirdsql.gds.ng.fields.RowDescriptor)

Example 5 with RowValue

use of org.firebirdsql.gds.ng.fields.RowValue in project jaybird by FirebirdSQL.

the class FBDatabaseMetaData method getCrossReference.

/**
 * Gets a description of the foreign key columns in the foreign key
 * table that reference the primary key columns of the primary key
 * table (describe how one table imports another's key). This
 * should normally return a single foreign key/primary key pair
 * (most tables only import a foreign key from a table once.)  They
 * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
 * KEY_SEQ.
 *
 * <P>Each foreign key column description has the following columns:
 *  <OL>
 *  <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
 *  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
 *  <LI><B>PKTABLE_NAME</B> String => primary key table name
 *  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
 *  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
 *      being exported (may be null)
 *  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
 *      being exported (may be null)
 *  <LI><B>FKTABLE_NAME</B> String => foreign key table name
 *      being exported
 *  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
 *      being exported
 *  <LI><B>KEY_SEQ</B> short => sequence number within foreign key
 *  <LI><B>UPDATE_RULE</B> short => What happens to
 *       foreign key when primary is updated:
 *      <UL>
 *      <LI> importedNoAction - do not allow update of primary
 *               key if it has been imported
 *      <LI> importedKeyCascade - change imported key to agree
 *               with primary key update
 *      <LI> importedKeySetNull - change imported key to NULL if
 *               its primary key has been updated
 *      <LI> importedKeySetDefault - change imported key to default values
 *               if its primary key has been updated
 *      <LI> importedKeyRestrict - same as importedKeyNoAction
 *                                 (for ODBC 2.x compatibility)
 *      </UL>
 *  <LI><B>DELETE_RULE</B> short => What happens to
 *      the foreign key when primary is deleted.
 *      <UL>
 *      <LI> importedKeyNoAction - do not allow delete of primary
 *               key if it has been imported
 *      <LI> importedKeyCascade - delete rows that import a deleted key
 *      <LI> importedKeySetNull - change imported key to NULL if
 *               its primary key has been deleted
 *      <LI> importedKeyRestrict - same as importedKeyNoAction
 *                                 (for ODBC 2.x compatibility)
 *      <LI> importedKeySetDefault - change imported key to default if
 *               its primary key has been deleted
 *      </UL>
 *  <LI><B>FK_NAME</B> String => foreign key name (may be null)
 *  <LI><B>PK_NAME</B> String => primary key name (may be null)
 *  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
 *      constraints be deferred until commit
 *      <UL>
 *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
 *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
 *      <LI> importedKeyNotDeferrable - see SQL92 for definition
 *      </UL>
 *  </OL>
 *
 * @param primaryCatalog a catalog name; "" retrieves those without a
 * catalog; null means drop catalog name from the selection criteria
 * @param primarySchema a schema name; "" retrieves those
 * without a schema
 * @param primaryTable the table name that exports the key
 * @param foreignCatalog a catalog name; "" retrieves those without a
 * catalog; null means drop catalog name from the selection criteria
 * @param foreignSchema a schema name; "" retrieves those
 * without a schema
 * @param foreignTable the table name that imports the key
 * @return <code>ResultSet</code> - each row is a foreign key column description
 * @exception SQLException if a database access error occurs
 * @see #getImportedKeys
 */
public ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
    final RowDescriptor rowDescriptor = new RowDescriptorBuilder(14, datatypeCoder).at(0).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PKTABLE_CAT", "COLUMNINFO").addField().at(1).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PKTABLE_SCHEM", "COLUMNINFO").addField().at(2).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PKTABLE_NAME", "COLUMNINFO").addField().at(3).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PKCOLUMN_NAME", "COLUMNINFO").addField().at(4).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FKTABLE_CAT", "COLUMNINFO").addField().at(5).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FKTABLE_SCHEM", "COLUMNINFO").addField().at(6).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FKTABLE_NAME", "COLUMNINFO").addField().at(7).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FKCOLUMN_NAME", "COLUMNINFO").addField().at(8).simple(SQL_SHORT, 0, "KEY_SEQ", "COLUMNINFO").addField().at(9).simple(SQL_SHORT, 0, "UPDATE_RULE", "COLUMNINFO").addField().at(10).simple(SQL_SHORT, 0, "DELETE_RULE", "COLUMNINFO").addField().at(11).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FK_NAME", "COLUMNINFO").addField().at(12).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PK_NAME", "COLUMNINFO").addField().at(13).simple(SQL_SHORT, 0, "DEFERRABILITY", "COLUMNINFO").addField().toRowDescriptor();
    final List<String> params = Arrays.asList(primaryTable, foreignTable);
    try (ResultSet rs = doQuery(GET_CROSS_KEYS, params)) {
        // return empty result set if nothing found
        if (!rs.next()) {
            return new FBResultSet(rowDescriptor, Collections.<RowValue>emptyList());
        }
        final List<RowValue> rows = new ArrayList<>();
        final RowValueBuilder valueBuilder = new RowValueBuilder(rowDescriptor);
        do {
            rows.add(valueBuilder.at(2).set(getBytes(rs.getString("PKTABLE_NAME"))).at(3).set(getBytes(rs.getString("PKCOLUMN_NAME"))).at(6).set(getBytes(rs.getString("FKTABLE_NAME"))).at(7).set(getBytes(rs.getString("FKCOLUMN_NAME"))).at(8).set(createShort(rs.getShort("KEY_SEQ"))).at(9).set(mapAction(rs.getString("UPDATE_RULE"))).at(10).set(mapAction(rs.getString("DELETE_RULE"))).at(11).set(getBytes(rs.getString("FK_NAME"))).at(12).set(getBytes(rs.getString("PK_NAME"))).at(13).set(IMPORTED_KEY_NOT_DEFERRABLE).toRowValue(true));
        } while (rs.next());
        return new FBResultSet(rowDescriptor, rows);
    }
}
Also used : RowDescriptorBuilder(org.firebirdsql.gds.ng.fields.RowDescriptorBuilder) RowValueBuilder(org.firebirdsql.gds.ng.fields.RowValueBuilder) RowValue(org.firebirdsql.gds.ng.fields.RowValue) RowDescriptor(org.firebirdsql.gds.ng.fields.RowDescriptor)

Aggregations

RowValue (org.firebirdsql.gds.ng.fields.RowValue)22 RowDescriptor (org.firebirdsql.gds.ng.fields.RowDescriptor)13 RowDescriptorBuilder (org.firebirdsql.gds.ng.fields.RowDescriptorBuilder)12 RowValueBuilder (org.firebirdsql.gds.ng.fields.RowValueBuilder)11 SQLException (java.sql.SQLException)3 FieldValue (org.firebirdsql.gds.ng.fields.FieldValue)3 FBField (org.firebirdsql.jdbc.field.FBField)3 Test (org.junit.Test)3 ArrayList (java.util.ArrayList)2 GDSHelper (org.firebirdsql.gds.impl.GDSHelper)2 SimpleStatementListener (org.firebirdsql.gds.ng.wire.SimpleStatementListener)2 FBFlushableField (org.firebirdsql.jdbc.field.FBFlushableField)2 FieldDataProvider (org.firebirdsql.jdbc.field.FieldDataProvider)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ResourceException (javax.resource.ResourceException)1 Encoding (org.firebirdsql.encodings.Encoding)1 DefaultStatementListener (org.firebirdsql.gds.ng.listeners.DefaultStatementListener)1 StatementListener (org.firebirdsql.gds.ng.listeners.StatementListener)1 CachedObject (org.firebirdsql.jdbc.field.FBFlushableField.CachedObject)1