/*
 * Copyright (c) 2011-2014 The original author or authors
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 *     The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 *
 *     The Apache License v2.0 is available at
 *     http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

package io.vertx.ext.jdbc.impl.actions;

import io.vertx.core.Vertx;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.json.JsonArray;
import io.vertx.ext.sql.SQLOptions;
import io.vertx.ext.sql.UpdateResult;

import java.sql.*;

Author:Nick Scavelli, Paulo Lopes
/** * @author <a href="mailto:nscavell@redhat.com">Nick Scavelli</a> * @author <a href="mailto:plopes@redhat.com">Paulo Lopes</a> */
public class JDBCUpdate extends AbstractJDBCAction<UpdateResult> { private final String sql; private final JsonArray in; private boolean generateKeys; public JDBCUpdate(Vertx vertx, JDBCStatementHelper helper, SQLOptions options, ContextInternal ctx, String sql, JsonArray in) { super(vertx, helper, options, ctx); this.sql = sql; this.in = in; } private PreparedStatement prepareStatement(Connection conn) throws SQLException { if (options == null) { generateKeys = true; return conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); } if (!options.isAutoGeneratedKeys()) { generateKeys = false; return conn.prepareStatement(sql, Statement.NO_GENERATED_KEYS); } if (options.getAutoGeneratedKeysIndexes() == null) { generateKeys = true; return conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); } if (options.getAutoGeneratedKeysIndexes().getValue(0) instanceof String) { String[] columnNames = new String[options.getAutoGeneratedKeysIndexes().size()]; for (int i = 0; i < columnNames.length; i++) { columnNames[i] = options.getAutoGeneratedKeysIndexes().getString(i); } generateKeys = true; return conn.prepareStatement(sql, columnNames); } if (options.getAutoGeneratedKeysIndexes().getValue(0) instanceof Number) { int[] columnIndexes = new int[options.getAutoGeneratedKeysIndexes().size()]; for (int i = 0; i < columnIndexes.length; i++) { columnIndexes[i] = options.getAutoGeneratedKeysIndexes().getInteger(i); } generateKeys = true; return conn.prepareStatement(sql, columnIndexes); } // invalid type throw new SQLException("Invalid type for auto generated keys"); } @Override public UpdateResult execute(Connection conn) throws SQLException { try (PreparedStatement statement = prepareStatement(conn)) { // apply statement options applyStatementOptions(statement); helper.fillStatement(statement, in); int updated = statement.executeUpdate(); JsonArray keys = new JsonArray(); // Create JsonArray of keys if (generateKeys) { ResultSet rs = null; try { // the resource might also fail // specially on oracle DBMS rs = statement.getGeneratedKeys(); if (rs != null) { final ResultSetMetaData metaData = rs.getMetaData(); final int columns = metaData != null ? metaData.getColumnCount() : 1; while (rs.next()) { for (int i = 1; i <= columns; i++) { final Object key = rs.getObject(i); if (key == null) { keys.addNull(); } else { keys.add(helper.convertSqlValue(key)); } } } } } catch (SQLException e) { // do not crash if no permissions } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { // ignore close error } } } } return new UpdateResult(updated, keys); } } @Override protected String name() { return "update"; } }