Search in sources :

Example 1 with GeneratedKeys

use of org.teiid.GeneratedKeys in project teiid by teiid.

the class TestODataIntegration method testCheckGeneratedColumns.

@Test
public void testCheckGeneratedColumns() throws Exception {
    HardCodedExecutionFactory hc = new HardCodedExecutionFactory() {

        @Override
        public UpdateExecution createUpdateExecution(org.teiid.language.Command command, ExecutionContext executionContext, RuntimeMetadata metadata, Object connection) throws TranslatorException {
            GeneratedKeys keys = executionContext.getCommandContext().returnGeneratedKeys(new String[] { "a" }, new Class[] { String.class });
            keys.addKey(Arrays.asList("ax"));
            return super.createUpdateExecution(command, executionContext, metadata, connection);
        }

        @Override
        public boolean supportsCompareCriteriaEquals() {
            return true;
        }
    };
    hc.addUpdate("INSERT INTO x (b, c) VALUES ('b', 5)", new int[] { 1 });
    // this gets called right after insert.
    hc.addData("SELECT x.a, x.b, x.c FROM x WHERE x.a = 'ax'", Arrays.asList(Arrays.asList("a", "b", 2)));
    teiid.addTranslator("x", hc);
    try {
        ModelMetaData mmd = new ModelMetaData();
        mmd.setName("m");
        mmd.addSourceMetadata("ddl", "create foreign table x (a string, b string, c integer, " + "primary key (a)) options (updatable true);");
        mmd.addSourceMapping("x", "x", null);
        teiid.deployVDB("northwind", mmd);
        localClient = getClient(teiid.getDriver(), "northwind", new Properties());
        ContentResponse response = http.newRequest(baseURL + "/northwind/m/x").method("POST").content(new StringContentProvider("{\"b\":\"b\", \"c\":5}"), "application/json").send();
        assertEquals(201, response.getStatus());
    } finally {
        localClient = null;
        teiid.undeployVDB("northwind");
    }
}
Also used : ExecutionContext(org.teiid.translator.ExecutionContext) Command(org.teiid.query.sql.lang.Command) ContentResponse(org.eclipse.jetty.client.api.ContentResponse) StringContentProvider(org.eclipse.jetty.client.util.StringContentProvider) HardCodedExecutionFactory(org.teiid.runtime.HardCodedExecutionFactory) GeneratedKeys(org.teiid.GeneratedKeys) RuntimeMetadata(org.teiid.metadata.RuntimeMetadata) Properties(java.util.Properties) ModelMetaData(org.teiid.adminapi.impl.ModelMetaData) Test(org.junit.Test)

Example 2 with GeneratedKeys

use of org.teiid.GeneratedKeys in project teiid by teiid.

the class ODataUpdateExecution method addAutoGeneretedKeys.

private void addAutoGeneretedKeys() {
    OEntity entity = this.response.getResultsIter().next().getEntity();
    Table table = this.visitor.getEnityTable();
    int cols = table.getPrimaryKey().getColumns().size();
    Class<?>[] columnDataTypes = new Class<?>[cols];
    String[] columnNames = new String[cols];
    // this is typically expected to be an int/long, but we'll be general here.  we may eventual need the type logic off of the metadata importer
    for (int i = 0; i < cols; i++) {
        columnDataTypes[i] = table.getPrimaryKey().getColumns().get(i).getJavaType();
        columnNames[i] = table.getPrimaryKey().getColumns().get(i).getName();
    }
    GeneratedKeys generatedKeys = this.executionContext.getCommandContext().returnGeneratedKeys(columnNames, columnDataTypes);
    List<Object> vals = new ArrayList<Object>(columnDataTypes.length);
    for (int i = 0; i < columnDataTypes.length; i++) {
        OProperty<?> prop = entity.getProperty(columnNames[i]);
        Object value = this.translator.retrieveValue(prop.getValue(), columnDataTypes[i]);
        vals.add(value);
    }
    generatedKeys.addKey(vals);
}
Also used : Table(org.teiid.metadata.Table) ArrayList(java.util.ArrayList) GeneratedKeys(org.teiid.GeneratedKeys) OEntity(org.odata4j.core.OEntity)

Example 3 with GeneratedKeys

use of org.teiid.GeneratedKeys in project teiid by teiid.

the class JDBCUpdateExecution method executeTranslatedCommand.

/**
 * @param translatedComm
 * @throws TranslatorException
 * @since 4.3
 */
private void executeTranslatedCommand(TranslatedCommand translatedComm) throws TranslatorException {
    // create statement or PreparedStatement and execute
    String sql = translatedComm.getSql();
    boolean commitType = false;
    boolean succeeded = false;
    try {
        int updateCount = 0;
        Class<?>[] keyColumnDataTypes = null;
        String[] keyColumnNames = null;
        if (command instanceof Insert && context.getCommandContext().isReturnAutoGeneratedKeys() && executionFactory.supportsGeneratedKeys(context, command)) {
            Insert insert = (Insert) command;
            NamedTable nt = insert.getTable();
            if (nt.getMetadataObject() != null) {
                KeyRecord key = nt.getMetadataObject().getPrimaryKey();
                if (key != null) {
                    List<Column> cols = key.getColumns();
                    keyColumnDataTypes = new Class<?>[cols.size()];
                    keyColumnNames = new String[cols.size()];
                    for (int i = 0; i < cols.size(); i++) {
                        Column c = cols.get(i);
                        keyColumnDataTypes[i] = c.getJavaType();
                        // won't work in scenarios where the teiid name is changed or contains a .
                        keyColumnNames[i] = c.getName();
                    }
                }
            }
        }
        if (!translatedComm.isPrepared()) {
            statement = getStatement();
            // handle autoGeneratedKeys
            if (keyColumnDataTypes != null) {
                if (executionFactory.useColumnNamesForGeneratedKeys()) {
                    updateCount = statement.executeUpdate(sql, keyColumnNames);
                } else {
                    updateCount = statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
                }
            } else {
                updateCount = statement.executeUpdate(sql);
            }
            result = new int[] { updateCount };
            addStatementWarnings();
        } else {
            PreparedStatement pstatement = null;
            if (statement != null) {
                statement.close();
            }
            if (keyColumnDataTypes != null) {
                if (executionFactory.useColumnNamesForGeneratedKeys()) {
                    pstatement = connection.prepareStatement(sql, keyColumnNames);
                } else {
                    pstatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                }
            } else {
                pstatement = getPreparedStatement(sql);
            }
            statement = pstatement;
            Iterator<? extends List<?>> vi = null;
            if (command instanceof BulkCommand) {
                BulkCommand batchCommand = (BulkCommand) command;
                vi = batchCommand.getParameterValues();
            }
            int k = 0;
            int batchStart = 0;
            if (vi != null) {
                try {
                    commitType = getAutoCommit(translatedComm);
                    if (commitType) {
                        connection.setAutoCommit(false);
                    }
                    int maxBatchSize = (command instanceof Insert) ? maxPreparedInsertBatchSize : Integer.MAX_VALUE;
                    boolean done = false;
                    outer: while (!done) {
                        for (int i = 0; i < maxBatchSize; i++) {
                            if (vi.hasNext()) {
                                List<?> values = vi.next();
                                bind(pstatement, translatedComm.getPreparedValues(), values);
                                k++;
                            } else {
                                if (i == 0) {
                                    break outer;
                                }
                                done = true;
                                break;
                            }
                        }
                        int[] results = pstatement.executeBatch();
                        batchStart = k;
                        if (result == null) {
                            result = results;
                        } else {
                            int len = result.length;
                            result = Arrays.copyOf(result, len + results.length);
                            System.arraycopy(results, 0, result, len, results.length);
                        }
                    }
                } catch (SQLException e) {
                    int size = k + 1;
                    if (result == null) {
                        result = new int[size];
                    } else {
                        result = Arrays.copyOf(result, size);
                    }
                    // if there is a BatchUpdateException, there are more update counts to accumulate
                    if (e instanceof BatchUpdateException) {
                        BatchUpdateException bue = (BatchUpdateException) e;
                        int[] batchResults = bue.getUpdateCounts();
                        for (int j = 0; j < batchResults.length; j++) {
                            result[batchStart + j] = batchResults[j];
                        }
                        size = batchStart + batchResults.length;
                    } else {
                        size = batchStart;
                    }
                    // resize the result and throw exception
                    throw new TranslatorBatchException(e, Arrays.copyOf(result, size));
                }
            } else {
                bind(pstatement, translatedComm.getPreparedValues(), null);
                updateCount = pstatement.executeUpdate();
                result = new int[] { updateCount };
            }
            addStatementWarnings();
            succeeded = true;
        }
        if (keyColumnDataTypes != null) {
            try {
                ResultSet keys = statement.getGeneratedKeys();
                GeneratedKeys generatedKeys = context.getCommandContext().returnGeneratedKeys(keyColumnNames, keyColumnDataTypes);
                // many databases only support returning a single generated value, but we'll still attempt to gather all
                outer: while (keys.next()) {
                    List<Object> vals = new ArrayList<Object>(keyColumnDataTypes.length);
                    for (int i = 0; i < keyColumnDataTypes.length; i++) {
                        Object value = this.executionFactory.retrieveValue(keys, i + 1, keyColumnDataTypes[i]);
                        if (value != null && TypeFacility.getRuntimeType(value.getClass()) != keyColumnDataTypes[i]) {
                            // TODO we may need to let the engine to the final conversion
                            LogManager.logDetail(LogConstants.CTX_CONNECTOR, JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID11023, keyColumnDataTypes[i], keyColumnNames[i], value.getClass()));
                            continue outer;
                        }
                        vals.add(value);
                    }
                    generatedKeys.addKey(vals);
                }
            } catch (SQLException e) {
                context.addWarning(e);
                // $NON-NLS-1$
                LogManager.logDetail(LogConstants.CTX_CONNECTOR, e, "Exception determining generated keys, no keys will be returned");
            }
        }
    } catch (SQLException err) {
        throw new JDBCExecutionException(JDBCPlugin.Event.TEIID11013, err, translatedComm);
    } finally {
        if (commitType) {
            restoreAutoCommit(!succeeded, translatedComm);
        }
    }
}
Also used : NamedTable(org.teiid.language.NamedTable) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) GeneratedKeys(org.teiid.GeneratedKeys) Insert(org.teiid.language.Insert) TranslatorBatchException(org.teiid.translator.TranslatorBatchException) KeyRecord(org.teiid.metadata.KeyRecord) Column(org.teiid.metadata.Column) BulkCommand(org.teiid.language.BulkCommand) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) BatchUpdateException(java.sql.BatchUpdateException)

Example 4 with GeneratedKeys

use of org.teiid.GeneratedKeys in project teiid by teiid.

the class MongoDBUpdateExecution method addAutoGeneretedKeys.

private void addAutoGeneretedKeys(WriteResult result) throws TranslatorException {
    Table table = this.visitor.mongoDoc.getTargetTable();
    int cols = table.getPrimaryKey().getColumns().size();
    if (cols != 1) {
        // restrict to only primary keys based upon id
        return;
    }
    Class<?>[] columnDataTypes = new Class<?>[cols];
    String[] columnNames = new String[cols];
    // this is typically expected to be an int/long, but we'll be general here.  we may eventual need the type logic off of the metadata importer
    for (int i = 0; i < cols; i++) {
        columnDataTypes[i] = table.getPrimaryKey().getColumns().get(i).getJavaType();
        columnNames[i] = table.getPrimaryKey().getColumns().get(i).getName();
    }
    if (!columnNames[0].equals(MongoDBMetadataProcessor.ID)) {
        return;
    }
    GeneratedKeys generatedKeys = this.executionContext.getCommandContext().returnGeneratedKeys(columnNames, columnDataTypes);
    List<Object> vals = new ArrayList<Object>(columnDataTypes.length);
    for (int i = 0; i < columnDataTypes.length; i++) {
        Object value = this.executionFactory.retrieveValue(result.getUpsertedId(), columnDataTypes[i], this.mongoDB, columnNames[i], columnNames[i]);
        vals.add(value);
    }
    generatedKeys.addKey(vals);
}
Also used : Table(org.teiid.metadata.Table) ArrayList(java.util.ArrayList) GeneratedKeys(org.teiid.GeneratedKeys)

Example 5 with GeneratedKeys

use of org.teiid.GeneratedKeys in project teiid by teiid.

the class ODataUpdateExecution method addAutoGeneretedKeys.

private void addAutoGeneretedKeys(Table table, Entity entity) throws TranslatorException {
    int cols = table.getPrimaryKey().getColumns().size();
    Class<?>[] columnDataTypes = new Class<?>[cols];
    String[] columnNames = new String[cols];
    String[] odataTypes = new String[cols];
    // we may eventual need the type logic off of the metadata importer
    for (int i = 0; i < cols; i++) {
        columnDataTypes[i] = table.getPrimaryKey().getColumns().get(i).getJavaType();
        columnNames[i] = table.getPrimaryKey().getColumns().get(i).getName();
        odataTypes[i] = ODataMetadataProcessor.getNativeType(table.getPrimaryKey().getColumns().get(i));
    }
    GeneratedKeys generatedKeys = this.executionContext.getCommandContext().returnGeneratedKeys(columnNames, columnDataTypes);
    List<Object> vals = new ArrayList<Object>(columnDataTypes.length);
    for (int i = 0; i < columnDataTypes.length; i++) {
        Property prop = entity.getProperty(columnNames[i]);
        Object value;
        try {
            value = ODataTypeManager.convertToTeiidRuntimeType(columnDataTypes[i], prop.getValue(), odataTypes[i]);
        } catch (TeiidException e) {
            throw new TranslatorException(e);
        }
        vals.add(value);
    }
    generatedKeys.addKey(vals);
}
Also used : ArrayList(java.util.ArrayList) TranslatorException(org.teiid.translator.TranslatorException) GeneratedKeys(org.teiid.GeneratedKeys) Property(org.apache.olingo.commons.api.data.Property) TeiidException(org.teiid.core.TeiidException)

Aggregations

GeneratedKeys (org.teiid.GeneratedKeys)7 ArrayList (java.util.ArrayList)5 Test (org.junit.Test)2 ModelMetaData (org.teiid.adminapi.impl.ModelMetaData)2 RuntimeMetadata (org.teiid.metadata.RuntimeMetadata)2 Table (org.teiid.metadata.Table)2 ExecutionContext (org.teiid.translator.ExecutionContext)2 BatchUpdateException (java.sql.BatchUpdateException)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Properties (java.util.Properties)1 Property (org.apache.olingo.commons.api.data.Property)1 ContentResponse (org.eclipse.jetty.client.api.ContentResponse)1 StringContentProvider (org.eclipse.jetty.client.util.StringContentProvider)1 OEntity (org.odata4j.core.OEntity)1 TeiidException (org.teiid.core.TeiidException)1