Search in sources :

Example 1 with BlobHandler

use of com.palantir.db.oracle.JdbcHandler.BlobHandler in project atlasdb by palantir.

the class BasicSQL method insertMany.

public boolean insertMany(final Connection c, final FinalSQLString sql, final Object[][] vs) throws PalantirSqlException {
    if (SqlLoggers.LOGGER.isTraceEnabled()) {
        SqlLoggers.LOGGER.trace("SQL insert many query: {}", sql.getQuery());
    }
    return BasicSQLUtils.runUninterruptably(() -> {
        int[] inserted = null;
        PreparedStatement ps = null;
        // $NON-NLS-1$ //$NON-NLS-2$
        SqlTimer.Handle timerKey = getSqlTimer().start("insertMany(" + vs.length + ")", sql.getKey(), sql.getQuery());
        List<BlobHandler> cleanups = Lists.newArrayList();
        try {
            ps = c.prepareStatement(sql.getQuery());
            for (int i = 0; i < vs.length; i++) {
                for (int j = 0; j < vs[i].length; j++) {
                    Object obj = vs[i][j];
                    BlobHandler cleanup = setObject(c, ps, j + 1, obj);
                    if (cleanup != null) {
                        cleanups.add(cleanup);
                    }
                }
                ps.addBatch();
            }
            inserted = ps.executeBatch();
        } catch (SQLException sqle) {
            SqlLoggers.SQL_EXCEPTION_LOG.debug("Caught SQLException", sqle);
            throw wrapSQLExceptionWithVerboseLogging(sqle, sql.getQuery(), vs);
        } finally {
            closeSilently(ps);
            timerKey.stop();
            for (BlobHandler cleanup : cleanups) {
                try {
                    cleanup.freeTemporary();
                } catch (Exception e) {
                    // $NON-NLS-1$
                    SqlLoggers.LOGGER.error("failed to free temp blob", e);
                }
            }
        }
        if (inserted == null || inserted.length != vs.length) {
            assert false;
            return false;
        }
        for (int numInsertedForRow : inserted) {
            if (numInsertedForRow == Statement.EXECUTE_FAILED) {
                // $NON-NLS-1$
                assert DBType.getTypeFromConnection(c) != DBType.ORACLE : "numInsertedForRow: " + numInsertedForRow;
                return false;
            }
        }
        return true;
    }, sql.toString(), c);
}
Also used : VerboseSQLException(com.palantir.util.sql.VerboseSQLException) SQLException(java.sql.SQLException) BlobHandler(com.palantir.db.oracle.JdbcHandler.BlobHandler) SqlTimer(com.palantir.nexus.db.monitoring.timer.SqlTimer) PreparedStatement(java.sql.PreparedStatement) PalantirSqlException(com.palantir.exception.PalantirSqlException) VerboseSQLException(com.palantir.util.sql.VerboseSQLException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PalantirInterruptedException(com.palantir.exception.PalantirInterruptedException) SQLException(java.sql.SQLException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with BlobHandler

use of com.palantir.db.oracle.JdbcHandler.BlobHandler in project atlasdb by palantir.

the class SQL method handlePtInputStream.

private BlobHandler handlePtInputStream(Connection c, PreparedStatement ps, int i, PTInputStream is) {
    if (is.getLength() <= ORACLE_BYTE_LOWER_LIMIT) {
        try {
            byte[] bytes = IOUtils.toByteArray(is, is.getLength());
            Preconditions.checkArgument(bytes.length == is.getLength(), // $NON-NLS-1$
            "incorrect length - bytes: %s, input stream: %s", bytes.length, is.getLength());
            PreparedStatements.setBytes(ps, i, bytes);
        } catch (IOException e) {
            // $NON-NLS-1$
            throw Throwables.chain(PalantirSqlException.createForChaining(), Throwables.chain(new SQLException("Internal IOException"), e));
        } finally {
            IOUtils.closeQuietly(is);
        }
        return null;
    } else if (is.getLength() <= Integer.MAX_VALUE) {
        if (DBType.getTypeFromConnection(c) == DBType.POSTGRESQL && is.getLength() > SQL.POSTGRES_BLOB_WRITE_LIMIT) {
            // $NON-NLS-1$
            Validate.isTrue(false, "Postgres only supports blobs up to 1G");
        }
        PreparedStatements.setBinaryStream(ps, i, is, (int) is.getLength());
        return null;
    } else {
        DBType dbType = DBType.getTypeFromConnection(c);
        // $NON-NLS-1$
        Validate.isTrue(dbType == DBType.ORACLE, "We only support blobs over 2GB on oracle (postgres only supports blobs up to 1G)");
        BlobHandler blobHandler;
        try {
            blobHandler = getJdbcHandler().createBlob(c);
        } catch (SQLException e) {
            // $NON-NLS-1$
            sqlExceptionlog.debug("Caught SQLException", e);
            throw PalantirSqlException.create(e);
        }
        OutputStream os = null;
        try {
            os = blobHandler.setBinaryStream(0);
            PTStreams.copy(is, os);
            os.close();
            ps.setBlob(i, blobHandler.getBlob());
        } catch (Exception e) {
            try {
                blobHandler.freeTemporary();
            } catch (Exception e1) {
                // $NON-NLS-1$
                SqlLoggers.LOGGER.error("failed to free temp blob", e1);
            }
            // $NON-NLS-1$
            throw Throwables.chain(PalantirSqlException.createForChaining(), Throwables.chain(new SQLException("failed to transfer blob over 2GB to the DB"), e));
        } finally {
            IOUtils.closeQuietly(os);
        }
        return blobHandler;
    }
}
Also used : SQLException(java.sql.SQLException) OutputStream(java.io.OutputStream) BlobHandler(com.palantir.db.oracle.JdbcHandler.BlobHandler) IOException(java.io.IOException) DBType(com.palantir.nexus.db.DBType) PalantirSqlException(com.palantir.exception.PalantirSqlException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 3 with BlobHandler

use of com.palantir.db.oracle.JdbcHandler.BlobHandler in project atlasdb by palantir.

the class BasicSQL method createPreparedStatement.

/**
 * Encapsulates the logic for creating a prepared statement with the arguments set
 */
private PreparedStatement createPreparedStatement(Connection c, String sql, Object[] vs) throws PalantirSqlException {
    PreparedStatement ps;
    ps = Connections.prepareStatement(c, sql);
    List<BlobHandler> toClean = Lists.newArrayList();
    if (vs != null) {
        try {
            for (int i = 0; i < vs.length; i++) {
                BlobHandler cleanup = setObject(c, ps, i + 1, vs[i]);
                if (cleanup != null) {
                    toClean.add(cleanup);
                }
            }
        } catch (Exception e) {
            // if we throw, we need to clean up any blobs we have already made
            for (BlobHandler cleanupBlob : toClean) {
                try {
                    cleanupBlob.freeTemporary();
                } catch (Exception e1) {
                    // $NON-NLS-1$
                    SqlLoggers.LOGGER.error("failed to free temp blob", e1);
                }
            }
            BasicSQLUtils.throwUncheckedIfSQLException(e);
            throw Throwables.throwUncheckedException(e);
        }
    }
    return BlobCleanupPreparedStatement.create(ps, toClean);
}
Also used : BlobHandler(com.palantir.db.oracle.JdbcHandler.BlobHandler) PreparedStatement(java.sql.PreparedStatement) PalantirSqlException(com.palantir.exception.PalantirSqlException) VerboseSQLException(com.palantir.util.sql.VerboseSQLException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PalantirInterruptedException(com.palantir.exception.PalantirInterruptedException) SQLException(java.sql.SQLException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

BlobHandler (com.palantir.db.oracle.JdbcHandler.BlobHandler)3 PalantirSqlException (com.palantir.exception.PalantirSqlException)3 IOException (java.io.IOException)3 SQLException (java.sql.SQLException)3 PalantirInterruptedException (com.palantir.exception.PalantirInterruptedException)2 VerboseSQLException (com.palantir.util.sql.VerboseSQLException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 PreparedStatement (java.sql.PreparedStatement)2 ExecutionException (java.util.concurrent.ExecutionException)2 DBType (com.palantir.nexus.db.DBType)1 SqlTimer (com.palantir.nexus.db.monitoring.timer.SqlTimer)1 OutputStream (java.io.OutputStream)1