Search in sources :

Example 91 with DatabaseException

use of liquibase.exception.DatabaseException in project candlepin by candlepin.

the class PerOrgProductsMigrationTask method bulkInsertProductData.

/**
 * Performs bulk insertion of product. Used by the migrateProductData method.
 * <p></p>
 * Each row present in the specified collection should include seven elements, representing the
 * following columns: uuid, created, updated, multiplier, product_id, name, locked
 *
 * @param productRows
 *  A collection of object arrays representing a row of product data to insert
 */
private void bulkInsertProductData(List<Object[]> productRows) throws DatabaseException, SQLException {
    if (productRows.size() > 0) {
        this.logger.info("  Performing bulk migration of %d product entities", productRows.size());
        PreparedStatement statement = this.generateBulkInsertStatement("cp2_products", productRows.size(), "uuid", "created", "updated", "multiplier", "product_id", "name", "locked");
        int index = 0;
        for (Object[] row : productRows) {
            for (Object col : row) {
                this.setParameter(statement, ++index, col);
            }
        }
        int count = statement.executeUpdate();
        if (count != productRows.size()) {
            String errmsg = String.format("Wrong number of products migrated. Expected: %s, Inserted: %s", productRows.size(), count);
            this.logger.error(errmsg);
            throw new DatabaseException(errmsg);
        }
        this.logger.info("  Migrated %d products", count);
        statement.close();
    }
}
Also used : PreparedStatement(java.sql.PreparedStatement) DatabaseException(liquibase.exception.DatabaseException)

Example 92 with DatabaseException

use of liquibase.exception.DatabaseException in project candlepin by candlepin.

the class PerOrgProductsMigrationTask method migrateProductData.

/**
 * Migrates product data. Must be called per-org.
 *
 * @param orgid
 *  The id of the owner/organization for which to migrate product data
 */
@SuppressWarnings("checkstyle:methodlength")
protected void migrateProductData(String orgid) throws DatabaseException, SQLException {
    this.logger.info("  Migrating product data...");
    List<Object[]> productRows = new LinkedList<>();
    Set<String> uuidCache = new HashSet<>();
    ResultSet productInfo = this.executeQuery("SELECT DISTINCT p.id, p.created, p.updated, p.multiplier, p.name " + "FROM cp_product p " + "JOIN (" + "  SELECT p.product_id_old AS product_id " + "    FROM cp_pool p " + "    WHERE p.owner_id = ? " + "      AND NOT NULLIF(p.product_id_old, '') IS NULL " + "  UNION " + "  SELECT p.derived_product_id_old " + "    FROM cp_pool p " + "    WHERE p.owner_id = ? " + "      AND NOT NULLIF(p.derived_product_id_old, '') IS NULL " + "  UNION " + "  SELECT pp.product_id " + "    FROM cp_pool p " + "    JOIN cp_pool_products pp ON p.id = pp.pool_id " + "    WHERE p.owner_id = ? " + "      AND NOT NULLIF(pp.product_id, '') IS NULL " + "  UNION " + "  SELECT s.product_id " + "    FROM cp_subscription s " + "    WHERE s.owner_id = ? " + "      AND NOT NULLIF(s.product_id, '') IS NULL " + "  UNION " + "  SELECT s.derivedproduct_id " + "    FROM cp_subscription s " + "    WHERE s.owner_id = ? " + "      AND NOT NULLIF(s.derivedproduct_id, '') IS NULL " + "  UNION " + "  SELECT sp.product_id " + "    FROM cp_subscription_products sp " + "    JOIN cp_subscription s ON s.id = sp.subscription_id " + "    WHERE s.owner_id = ? " + "      AND NOT NULLIF(sp.product_id, '') IS NULL " + "  UNION " + "  SELECT sdp.product_id " + "    FROM cp_sub_derivedprods sdp " + "    JOIN cp_subscription s ON s.id = sdp.subscription_id " + "    WHERE s.owner_id = ? " + "      AND NOT NULLIF(sdp.product_id, '') IS NULL " + "  UNION " + "  SELECT pc.product_id " + "    FROM cp_product_content pc " + "    JOIN cp_env_content ec ON pc.content_id = ec.contentid " + "    JOIN cp_environment e ON e.id = ec.environment_id" + "    WHERE e.owner_id = ? " + "      AND NOT NULLIF(pc.product_id, '') IS NULL " + "  UNION " + "  SELECT akp.product_id " + "    FROM cp_activationkey_product akp " + "    JOIN cp_activation_key ak ON ak.id = akp.key_id " + "    WHERE ak.owner_id = ? " + "      AND NOT NULLIF(akp.product_id, '') IS NULL " + ") u ON u.product_id = p.id", orgid, orgid, orgid, orgid, orgid, orgid, orgid, orgid, orgid);
    int maxrows = MAX_PARAMETERS_PER_STATEMENT / 7;
    while (productInfo.next()) {
        String productId = productInfo.getString(1);
        String productUuid = this.migratedProducts.get(productId);
        if (productUuid == null) {
            this.logger.info("    Migrating product: %s", productId);
            productUuid = this.generateUUID();
            productRows.add(new Object[] { productUuid, productInfo.getObject(2), productInfo.getObject(3), productInfo.getObject(4), productId, productInfo.getObject(5), 0 });
            // If we've collected a full "block" of content data, migrate the block
            if (productRows.size() > maxrows) {
                // Impl note: By some miracle, this doesn't close the outer result set.
                this.bulkInsertProductData(productRows);
                productRows.clear();
            }
            this.migratedProducts.put(productId, productUuid);
        }
        uuidCache.add(productUuid);
    }
    productInfo.close();
    // Do a bulk insert of any remaining unmigrated products we've encountered
    bulkInsertProductData(productRows);
    productRows.clear();
    // // Do a bulk insert for all the products for this orgs...
    if (uuidCache.size() > 0) {
        maxrows = MAX_PARAMETERS_PER_STATEMENT / 2;
        int lastBlock = 0;
        // 79999
        int blockSize = maxrows / 2;
        Iterator<String> uuidIterator = uuidCache.iterator();
        PreparedStatement statement = null;
        for (int offset = 0; offset < uuidCache.size(); offset += blockSize) {
            int remaining = Math.min(uuidCache.size() - offset, blockSize);
            if (remaining != lastBlock) {
                if (statement != null) {
                    statement.close();
                }
                statement = this.generateBulkInsertStatement("cp2_owner_products", remaining, "owner_id", "product_uuid");
                lastBlock = remaining;
            }
            int index = 0;
            while (remaining-- > 0) {
                this.setParameter(statement, ++index, orgid);
                this.setParameter(statement, ++index, uuidIterator.next());
            }
            int count = statement.executeUpdate();
            if (count != uuidCache.size()) {
                String errmsg = String.format("Wrong number of products assigned to org: %s. Expected: %s, Inserted: %s", orgid, uuidCache.size(), count);
                this.logger.error(errmsg);
                throw new DatabaseException(errmsg);
            }
        }
        this.logger.info("  Assigned %d products to org", uuidCache.size());
        statement.close();
    }
}
Also used : ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) DatabaseException(liquibase.exception.DatabaseException) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 93 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class DropAllForeignKeyConstraintsChange method generateChildren.

/**
 * Iterates through all the FOREIGN KEYs of the target table and outputs a list of DropForeignKeyConstraintChanges
 * for a given database type.
 *
 * @param database the database type for which subchanges need to be generated
 * @return the list of generated DropForeignKeyConstraintChanges
 */
private List<DropForeignKeyConstraintChange> generateChildren(Database database) {
    // Make a new list
    List<DropForeignKeyConstraintChange> childDropChanges = new ArrayList<>();
    try {
        SnapshotControl control = new SnapshotControl(database);
        control.getTypesToInclude().add(ForeignKey.class);
        CatalogAndSchema catalogAndSchema = new CatalogAndSchema(getBaseTableCatalogName(), getBaseTableSchemaName());
        catalogAndSchema = catalogAndSchema.standardize(database);
        Table target = SnapshotGeneratorFactory.getInstance().createSnapshot(new Table(catalogAndSchema.getCatalogName(), catalogAndSchema.getSchemaName(), database.correctObjectName(getBaseTableName(), Table.class)), database);
        List<ForeignKey> results = ((target == null) ? null : target.getOutgoingForeignKeys());
        Set<String> handledConstraints = new HashSet<>();
        if ((results != null) && (!results.isEmpty())) {
            for (ForeignKey fk : results) {
                Table baseTable = fk.getForeignKeyTable();
                String constraintName = fk.getName();
                if (DatabaseObjectComparatorFactory.getInstance().isSameObject(baseTable, target, null, database)) {
                    if (!handledConstraints.contains(constraintName)) {
                        DropForeignKeyConstraintChange dropForeignKeyConstraintChange = new DropForeignKeyConstraintChange();
                        dropForeignKeyConstraintChange.setBaseTableSchemaName(getBaseTableSchemaName());
                        dropForeignKeyConstraintChange.setBaseTableName(baseTableName);
                        dropForeignKeyConstraintChange.setConstraintName(constraintName);
                        childDropChanges.add(dropForeignKeyConstraintChange);
                        handledConstraints.add(constraintName);
                    }
                } else {
                    throw new UnexpectedLiquibaseException("Expected to return only foreign keys for base table name: " + getBaseTableName() + " and got results for table: " + baseTableName);
                }
            }
        }
        return childDropChanges;
    } catch (DatabaseException | InvalidExampleException e) {
        throw new UnexpectedLiquibaseException("Failed to find foreign keys for table: " + getBaseTableName(), e);
    }
}
Also used : Table(liquibase.structure.core.Table) CatalogAndSchema(liquibase.CatalogAndSchema) ForeignKey(liquibase.structure.core.ForeignKey) InvalidExampleException(liquibase.snapshot.InvalidExampleException) SnapshotControl(liquibase.snapshot.SnapshotControl) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Example 94 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class JdbcExecutor method executeDb2ZosComplexStatement.

private void executeDb2ZosComplexStatement(SqlStatement sqlStatement) throws DatabaseException {
    DatabaseConnection con = database.getConnection();
    if (con instanceof OfflineConnection) {
        throw new DatabaseException("Cannot execute commands against an offline database");
    }
    Sql[] sqls = SqlGeneratorFactory.getInstance().generateSql(sqlStatement, database);
    for (Sql sql : sqls) {
        try {
            if (sql instanceof CallableSql) {
                CallableStatement call = null;
                ResultSet resultSet = null;
                try {
                    call = ((JdbcConnection) con).getUnderlyingConnection().prepareCall(sql.toSql());
                    resultSet = call.executeQuery();
                    checkCallStatus(resultSet, ((CallableSql) sql).getExpectedStatus());
                } finally {
                    JdbcUtil.close(resultSet, call);
                }
            } else {
                Statement stmt = null;
                try {
                    stmt = ((JdbcConnection) con).getUnderlyingConnection().createStatement();
                    stmt.execute(sql.toSql());
                    con.commit();
                } finally {
                    JdbcUtil.closeStatement(stmt);
                }
            }
        } catch (Exception e) {
            throw new DatabaseException(e.getMessage() + " [Failed SQL: " + getErrorCode(e) + sql.toSql() + "]", e);
        }
    }
}
Also used : CallableSql(liquibase.sql.CallableSql) CallableStatement(java.sql.CallableStatement) CompoundStatement(liquibase.statement.CompoundStatement) ExecutablePreparedStatement(liquibase.statement.ExecutablePreparedStatement) SqlStatement(liquibase.statement.SqlStatement) CallableSqlStatement(liquibase.statement.CallableSqlStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) ResultSet(java.sql.ResultSet) DatabaseConnection(liquibase.database.DatabaseConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) OfflineConnection(liquibase.database.OfflineConnection) DatabaseException(liquibase.exception.DatabaseException) SQLException(java.sql.SQLException) DatabaseException(liquibase.exception.DatabaseException) Sql(liquibase.sql.Sql) CallableSql(liquibase.sql.CallableSql)

Example 95 with DatabaseException

use of liquibase.exception.DatabaseException in project liquibase by liquibase.

the class JdbcExecutor method execute.

// Incorrect warning, at least at this point. The situation here is not that we inject some unsanitised parameter
// into a query. Instead, we process a whole query. The check should be performed at the places where
// the query is composed.
@SuppressWarnings("squid:S2077")
public Object execute(CallableStatementCallback action, List<SqlVisitor> sqlVisitors) throws DatabaseException {
    DatabaseConnection con = database.getConnection();
    if (con instanceof OfflineConnection) {
        throw new DatabaseException("Cannot execute commands against an offline database");
    }
    CallableStatement stmt = null;
    try {
        String sql = applyVisitors(action.getStatement(), sqlVisitors)[0];
        stmt = ((JdbcConnection) con).getUnderlyingConnection().prepareCall(sql);
        return action.doInCallableStatement(stmt);
    } catch (SQLException ex) {
        // Release Connection early, to avoid potential connection pool deadlock
        // in the case when the exception translator hasn't been initialized yet.
        JdbcUtil.closeStatement(stmt);
        stmt = null;
        throw new DatabaseException("Error executing SQL " + StringUtil.join(applyVisitors(action.getStatement(), sqlVisitors), "; on " + con.getURL()) + ": " + ex.getMessage(), ex);
    } finally {
        JdbcUtil.closeStatement(stmt);
    }
}
Also used : SQLException(java.sql.SQLException) CallableStatement(java.sql.CallableStatement) DatabaseConnection(liquibase.database.DatabaseConnection) JdbcConnection(liquibase.database.jvm.JdbcConnection) OfflineConnection(liquibase.database.OfflineConnection) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

DatabaseException (liquibase.exception.DatabaseException)139 SQLException (java.sql.SQLException)65 JdbcConnection (liquibase.database.jvm.JdbcConnection)34 PreparedStatement (java.sql.PreparedStatement)33 ResultSet (java.sql.ResultSet)28 Statement (java.sql.Statement)24 Database (liquibase.database.Database)24 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)24 CustomChangeException (liquibase.exception.CustomChangeException)22 CatalogAndSchema (liquibase.CatalogAndSchema)17 LiquibaseException (liquibase.exception.LiquibaseException)16 AbstractJdbcDatabase (liquibase.database.AbstractJdbcDatabase)14 InvalidExampleException (liquibase.snapshot.InvalidExampleException)14 RawSqlStatement (liquibase.statement.core.RawSqlStatement)14 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)13 CachedRow (liquibase.snapshot.CachedRow)13 SqlStatement (liquibase.statement.SqlStatement)13 DatabaseConnection (liquibase.database.DatabaseConnection)12 JdbcDatabaseSnapshot (liquibase.snapshot.JdbcDatabaseSnapshot)12 ArrayList (java.util.ArrayList)11