Search in sources :

Example 6 with TableKeyMetaData

use of nl.topicus.jdbc.MetaDataStore.TableKeyMetaData in project spanner-jdbc by olavloite.

the class AbstractCloudSpannerStatement method createInsertSelectOnDuplicateKeyUpdateStatement.

/**
 * Transform the given UPDATE-statement into an "INSERT INTO TAB1 (...)
 * SELECT ... FROM TAB1 WHERE ... ON DUPLICATE KEY UPDATE"
 *
 * @param update
 *            The UPDATE-statement
 * @return An SQL-statement equal to the UPDATE-statement but in INSERT form
 * @throws SQLException
 *             if a database exception occurs while getting the table meta
 *             data or if the statement tries to update the primary key
 *             value
 */
protected String createInsertSelectOnDuplicateKeyUpdateStatement(Update update) throws SQLException {
    String tableName = unquoteIdentifier(update.getTables().get(0).getName());
    TableKeyMetaData table = getConnection().getTable(tableName);
    List<String> keyColumns = table.getKeyColumns();
    List<String> updateColumns = update.getColumns().stream().map(Column::getColumnName).map(String::toUpperCase).collect(Collectors.toList());
    List<String> quotedKeyColumns = keyColumns.stream().map(this::quoteIdentifier).collect(Collectors.toList());
    List<String> quotedAndQualifiedKeyColumns = keyColumns.stream().map(x -> quoteIdentifier(tableName) + "." + quoteIdentifier(x)).collect(Collectors.toList());
    List<String> quotedUpdateColumns = updateColumns.stream().map(this::quoteIdentifier).collect(Collectors.toList());
    List<String> expressions = update.getExpressions().stream().map(Object::toString).collect(Collectors.toList());
    if (updateColumns.stream().anyMatch(keyColumns::contains)) {
        String invalidCols = updateColumns.stream().filter(keyColumns::contains).collect(Collectors.joining());
        throw new CloudSpannerSQLException("UPDATE of a primary key value is not allowed, cannot UPDATE the column(s) " + invalidCols, Code.INVALID_ARGUMENT);
    }
    StringBuilder res = new StringBuilder();
    res.append("INSERT INTO ").append(quoteIdentifier(tableName)).append("\n(");
    res.append(String.join(", ", quotedKeyColumns)).append(", ");
    res.append(String.join(", ", quotedUpdateColumns)).append(")");
    res.append("\nSELECT ").append(String.join(", ", quotedAndQualifiedKeyColumns)).append(", ");
    res.append(String.join(", ", expressions));
    res.append("\nFROM ").append(quoteIdentifier(tableName));
    if (update.getWhere() != null)
        res.append("\n").append("WHERE ").append(update.getWhere().toString());
    res.append("\nON DUPLICATE KEY UPDATE");
    return res.toString();
}
Also used : TableKeyMetaData(nl.topicus.jdbc.MetaDataStore.TableKeyMetaData) TransactionCallable(com.google.cloud.spanner.TransactionRunner.TransactionCallable) ReadContext(com.google.cloud.spanner.ReadContext) SQLFeatureNotSupportedException(java.sql.SQLFeatureNotSupportedException) DatabaseClient(com.google.cloud.spanner.DatabaseClient) PlainSelect(net.sf.jsqlparser.statement.select.PlainSelect) TableKeyMetaData(nl.topicus.jdbc.MetaDataStore.TableKeyMetaData) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) Column(net.sf.jsqlparser.schema.Column) Update(net.sf.jsqlparser.statement.update.Update) SQLWarning(java.sql.SQLWarning) Code(com.google.rpc.Code) TransactionContext(com.google.cloud.spanner.TransactionContext) CloudSpannerConnection(nl.topicus.jdbc.CloudSpannerConnection) Table(net.sf.jsqlparser.schema.Table) CloudSpannerSQLException(nl.topicus.jdbc.exception.CloudSpannerSQLException) Collectors(java.util.stream.Collectors) AbstractCloudSpannerFetcher(nl.topicus.jdbc.AbstractCloudSpannerFetcher) SpannerException(com.google.cloud.spanner.SpannerException) List(java.util.List) Select(net.sf.jsqlparser.statement.select.Select) Statement(java.sql.Statement) CloudSpannerDriver(nl.topicus.jdbc.CloudSpannerDriver) SelectVisitorAdapter(net.sf.jsqlparser.statement.select.SelectVisitorAdapter) FromItemVisitorAdapter(net.sf.jsqlparser.statement.select.FromItemVisitorAdapter) Column(net.sf.jsqlparser.schema.Column) CloudSpannerSQLException(nl.topicus.jdbc.exception.CloudSpannerSQLException)

Example 7 with TableKeyMetaData

use of nl.topicus.jdbc.MetaDataStore.TableKeyMetaData in project spanner-jdbc by olavloite.

the class CloudSpannerTestObjects method createConnection.

public static CloudSpannerConnection createConnection() throws SQLException {
    CloudSpannerConnection connection = Mockito.mock(CloudSpannerConnection.class);
    Mockito.doCallRealMethod().when(connection).setAutoCommit(Mockito.anyBoolean());
    Mockito.when(connection.getAutoCommit()).thenCallRealMethod();
    connection.setAutoCommit(false);
    Mockito.when(connection.isAllowExtendedMode()).thenAnswer(new Returns(true));
    Mockito.when(connection.createArrayOf(Mockito.anyString(), Mockito.any())).thenCallRealMethod();
    CloudSpannerDatabaseMetaData metadata = createMetaData();
    Mockito.when(connection.getMetaData()).thenReturn(metadata);
    CloudSpannerTransaction transaction = Mockito.mock(CloudSpannerTransaction.class);
    Mockito.when(transaction.executeQuery(Mockito.any())).thenReturn(Mockito.mock(com.google.cloud.spanner.ResultSet.class));
    Mockito.when(connection.getTransaction()).thenReturn(transaction);
    TableKeyMetaData tableFoo = Mockito.mock(TableKeyMetaData.class);
    Mockito.when(tableFoo.getKeyColumns()).thenAnswer(new Returns(Arrays.asList("ID")));
    Mockito.when(connection.getTable(Mockito.matches(Pattern.compile("FOO", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)))).thenAnswer(new Returns(tableFoo));
    TableKeyMetaData tableBar = Mockito.mock(TableKeyMetaData.class);
    Mockito.when(tableBar.getKeyColumns()).thenAnswer(new Returns(Arrays.asList("ID1", "ID2")));
    Mockito.when(connection.getTable(Mockito.matches(Pattern.compile("BAR", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)))).thenAnswer(new Returns(tableBar));
    Mockito.when(connection.getLogger()).thenAnswer(new Returns(new Logger()));
    mockXAMethods(connection);
    return connection;
}
Also used : TableKeyMetaData(nl.topicus.jdbc.MetaDataStore.TableKeyMetaData) Returns(org.mockito.internal.stubbing.answers.Returns) CloudSpannerDatabaseMetaData(nl.topicus.jdbc.CloudSpannerDatabaseMetaData) CloudSpannerResultSet(nl.topicus.jdbc.resultset.CloudSpannerResultSet) ResultSet(java.sql.ResultSet) CloudSpannerConnection(nl.topicus.jdbc.CloudSpannerConnection) CloudSpannerTransaction(nl.topicus.jdbc.transaction.CloudSpannerTransaction) Logger(nl.topicus.jdbc.Logger)

Aggregations

TableKeyMetaData (nl.topicus.jdbc.MetaDataStore.TableKeyMetaData)7 CloudSpannerConnection (nl.topicus.jdbc.CloudSpannerConnection)4 Code (com.google.rpc.Code)2 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 Table (net.sf.jsqlparser.schema.Table)2 Select (net.sf.jsqlparser.statement.select.Select)2 CloudSpannerDatabaseMetaData (nl.topicus.jdbc.CloudSpannerDatabaseMetaData)2 CloudSpannerDriver (nl.topicus.jdbc.CloudSpannerDriver)2 CloudSpannerSQLException (nl.topicus.jdbc.exception.CloudSpannerSQLException)2 CloudSpannerResultSet (nl.topicus.jdbc.resultset.CloudSpannerResultSet)2 UnitTest (nl.topicus.jdbc.test.category.UnitTest)2 Test (org.junit.Test)2 Returns (org.mockito.internal.stubbing.answers.Returns)2 DatabaseClient (com.google.cloud.spanner.DatabaseClient)1 ReadContext (com.google.cloud.spanner.ReadContext)1 SpannerException (com.google.cloud.spanner.SpannerException)1 TransactionContext (com.google.cloud.spanner.TransactionContext)1