Search in sources :

Example 1 with ValueGenerationException

use of org.datanucleus.store.valuegenerator.ValueGenerationException in project datanucleus-rdbms by datanucleus.

the class MaxGenerator method reserveBlock.

/**
 * Method to reserve a block of identities.
 * Note : Only allocates a single id always.
 * @param size The block size
 * @return The reserved block
 */
public ValueGenerationBlock reserveBlock(long size) {
    try {
        // search an Id in the database
        ManagedConnection mconn = connectionProvider.retrieveConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        SQLController sqlControl = ((RDBMSStoreManager) storeMgr).getSQLController();
        try {
            String stmt = getStatement();
            ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
            rs = sqlControl.executeStatementQuery(null, mconn, stmt, ps);
            if (!rs.next()) {
                return new ValueGenerationBlock(new Object[] { Long.valueOf(1) });
            }
            return new ValueGenerationBlock(new Object[] { Long.valueOf(rs.getLong(1) + 1) });
        } catch (SQLException e) {
            NucleusLogger.VALUEGENERATION.warn("Exception thrown getting next value for MaxGenerator", e);
            throw new ValueGenerationException("Exception thrown getting next value for MaxGenerator", e);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    sqlControl.closeStatement(mconn, ps);
                }
            } catch (SQLException e) {
            // no recoverable error
            }
        }
    } finally {
        connectionProvider.releaseConnection();
    }
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) ValueGenerationBlock(org.datanucleus.store.valuegenerator.ValueGenerationBlock) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException) SQLController(org.datanucleus.store.rdbms.SQLController) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Example 2 with ValueGenerationException

use of org.datanucleus.store.valuegenerator.ValueGenerationException in project datanucleus-rdbms by datanucleus.

the class SequenceGenerator method reserveBlock.

/**
 * Reserve a block of ids.
 * @param size Block size
 * @return The reserved block
 */
protected synchronized ValueGenerationBlock<Long> reserveBlock(long size) {
    if (size < 1) {
        return null;
    }
    PreparedStatement ps = null;
    ResultSet rs = null;
    List oid = new ArrayList();
    RDBMSStoreManager srm = (RDBMSStoreManager) storeMgr;
    SQLController sqlControl = srm.getSQLController();
    try {
        // Get next available id
        DatastoreAdapter dba = srm.getDatastoreAdapter();
        String stmt = dba.getSequenceNextStmt(sequenceName);
        ps = sqlControl.getStatementForQuery(connection, stmt);
        rs = sqlControl.executeStatementQuery(null, connection, stmt, ps);
        Long nextId = Long.valueOf(0);
        if (rs.next()) {
            nextId = Long.valueOf(rs.getLong(1));
            oid.add(nextId);
        }
        for (int i = 1; i < size; i++) {
            // size must match key-increment-by otherwise it will
            // cause duplicates keys
            nextId = Long.valueOf(nextId.longValue() + 1);
            oid.add(nextId);
        }
        if (NucleusLogger.VALUEGENERATION.isDebugEnabled()) {
            NucleusLogger.VALUEGENERATION.debug(Localiser.msg("040004", "" + size));
        }
        return new ValueGenerationBlock<>(oid);
    } catch (SQLException e) {
        throw new ValueGenerationException(Localiser.msg("061001", e.getMessage()), e);
    } finally {
        try {
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                sqlControl.closeStatement(connection, ps);
            }
        } catch (SQLException e) {
        // non-recoverable error
        }
    }
}
Also used : SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) ValueGenerationBlock(org.datanucleus.store.valuegenerator.ValueGenerationBlock) PreparedStatement(java.sql.PreparedStatement) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SQLController(org.datanucleus.store.rdbms.SQLController) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter)

Example 3 with ValueGenerationException

use of org.datanucleus.store.valuegenerator.ValueGenerationException in project datanucleus-rdbms by datanucleus.

the class SequenceGenerator method createRepository.

/**
 * Method to create the sequence.
 * @return Whether it was created successfully.
 */
protected boolean createRepository() {
    PreparedStatement ps = null;
    RDBMSStoreManager srm = (RDBMSStoreManager) storeMgr;
    DatastoreAdapter dba = srm.getDatastoreAdapter();
    SQLController sqlControl = srm.getSQLController();
    if (!srm.getSchemaHandler().isAutoCreateTables()) {
        throw new NucleusUserException(Localiser.msg("040010", sequenceName));
    }
    Integer min = properties.containsKey(ValueGenerator.PROPERTY_KEY_MIN_VALUE) ? Integer.valueOf(properties.getProperty(ValueGenerator.PROPERTY_KEY_MIN_VALUE)) : null;
    Integer max = properties.containsKey(ValueGenerator.PROPERTY_KEY_MAX_VALUE) ? Integer.valueOf(properties.getProperty(ValueGenerator.PROPERTY_KEY_MAX_VALUE)) : null;
    Integer start = properties.containsKey(ValueGenerator.PROPERTY_KEY_INITIAL_VALUE) ? Integer.valueOf(properties.getProperty(ValueGenerator.PROPERTY_KEY_INITIAL_VALUE)) : null;
    Integer incr = properties.containsKey(ValueGenerator.PROPERTY_KEY_CACHE_SIZE) ? Integer.valueOf(properties.getProperty(ValueGenerator.PROPERTY_KEY_CACHE_SIZE)) : null;
    Integer cacheSize = properties.containsKey(ValueGenerator.PROPERTY_KEY_DATABASE_CACHE_SIZE) ? Integer.valueOf(properties.getProperty(ValueGenerator.PROPERTY_KEY_DATABASE_CACHE_SIZE)) : null;
    String stmt = dba.getSequenceCreateStmt(sequenceName, min, max, start, incr, cacheSize);
    try {
        ps = sqlControl.getStatementForUpdate(connection, stmt, false);
        sqlControl.executeStatementUpdate(null, connection, stmt, ps, true);
    } catch (SQLException e) {
        NucleusLogger.DATASTORE.error(e);
        throw new ValueGenerationException(Localiser.msg("061000", e.getMessage()) + stmt);
    } finally {
        try {
            if (ps != null) {
                sqlControl.closeStatement(connection, ps);
            }
        } catch (SQLException e) {
        // non-recoverable error
        }
    }
    return true;
}
Also used : SQLException(java.sql.SQLException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) PreparedStatement(java.sql.PreparedStatement) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SQLController(org.datanucleus.store.rdbms.SQLController)

Example 4 with ValueGenerationException

use of org.datanucleus.store.valuegenerator.ValueGenerationException in project datanucleus-rdbms by datanucleus.

the class SequenceTable method getNextVal.

/**
 * Accessor for the nextval of a sequence
 * @param conn Connection for this datastore.
 * @param sequenceName The sequence name (the key)
 * @param incrementBy The amount to increment (from the current value)
 * @param tableIdentifier Identifier for the table being incremented (used when there is no current value)
 * @param columnName Name of the column being incremented (used when there is no current value)
 * @param initialValue Initial value (if not using tableIdentifier/columnName to find the initial value)
 * @return The next value that should be used
 * @throws SQLException Thrown when an error occurs in the process.
 */
public Long getNextVal(String sequenceName, ManagedConnection conn, int incrementBy, DatastoreIdentifier tableIdentifier, String columnName, int initialValue) throws SQLException {
    PreparedStatement ps = null;
    Long nextVal = null;
    SQLController sqlControl = storeMgr.getSQLController();
    try {
        ps = sqlControl.getStatementForQuery(conn, fetchStmt);
        sequenceNameMapping.setString(null, ps, new int[] { 1 }, sequenceName);
        ResultSet rs = sqlControl.executeStatementQuery(null, conn, fetchStmt, ps);
        try {
            if (!rs.next()) {
                // No data in the SEQUENCE_TABLE for this sequence currently
                boolean addedSequence = false;
                if (initialValue >= 0) {
                    // Just start at "initialValue" since value provided
                    addSequence(sequenceName, Long.valueOf(incrementBy + initialValue), conn);
                    nextVal = Long.valueOf(initialValue);
                } else {
                    if (columnName != null && tableIdentifier != null) {
                        // Table/Column specified so find the current max value for the field being generated
                        PreparedStatement ps2 = null;
                        ResultSet rs2 = null;
                        try {
                            String fetchInitStmt = "SELECT MAX(" + columnName + ") FROM " + tableIdentifier.getFullyQualifiedName(false);
                            ps2 = sqlControl.getStatementForQuery(conn, fetchInitStmt);
                            rs2 = sqlControl.executeStatementQuery(null, conn, fetchInitStmt, ps2);
                            if (rs2.next()) {
                                long val = rs2.getLong(1);
                                addSequence(sequenceName, Long.valueOf(incrementBy + 1 + val), conn);
                                nextVal = Long.valueOf(1 + val);
                                addedSequence = true;
                            }
                        } catch (Exception e) {
                        // Do nothing - since if the table is empty we get this
                        } finally {
                            if (rs2 != null) {
                                rs2.close();
                            }
                            if (ps2 != null) {
                                sqlControl.closeStatement(conn, ps2);
                            }
                        }
                    }
                    if (!addedSequence) {
                        // Just start at "initialValue"
                        addSequence(sequenceName, Long.valueOf(incrementBy + 0), conn);
                        nextVal = Long.valueOf(initialValue);
                    }
                }
            } else {
                // Data already exists in sequence table for this key so increment it
                nextVal = Long.valueOf(rs.getLong(1));
                incrementSequence(sequenceName, incrementBy, conn);
            }
        } finally {
            rs.close();
        }
    } catch (SQLException e) {
        throw new ValueGenerationException(Localiser.msg("061001", e.getMessage()), e);
    } finally {
        if (ps != null) {
            sqlControl.closeStatement(conn, ps);
        }
    }
    return nextVal;
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException) NucleusException(org.datanucleus.exceptions.NucleusException) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException) SQLException(java.sql.SQLException) SQLController(org.datanucleus.store.rdbms.SQLController)

Example 5 with ValueGenerationException

use of org.datanucleus.store.valuegenerator.ValueGenerationException in project datanucleus-rdbms by datanucleus.

the class TableGenerator method repositoryExists.

/**
 * Method to return if the repository already exists.
 * @return Whether the repository exists
 */
protected boolean repositoryExists() {
    if (repositoryExists) {
        return true;
    } else if (storeMgr.getBooleanProperty(RDBMSPropertyNames.PROPERTY_RDBMS_OMIT_DATABASEMETADATA_GETCOLUMNS) || storeMgr.getBooleanProperty(RDBMSPropertyNames.PROPERTY_RDBMS_OMIT_VALUE_GENERATION_GETCOLUMNS)) {
        // Assumed to exist if ignoring DMD.getColumns()
        NucleusLogger.VALUEGENERATION.debug("Omitting information schema call during the creation of value generation");
        repositoryExists = true;
        return true;
    }
    try {
        if (sequenceTable == null) {
            initialiseSequenceTable();
        }
        sequenceTable.exists((Connection) connection.getConnection(), true);
        repositoryExists = true;
        return true;
    } catch (SQLException sqle) {
        throw new ValueGenerationException("Exception thrown calling table.exists() for " + sequenceTable, sqle);
    }
}
Also used : SQLException(java.sql.SQLException) ValueGenerationException(org.datanucleus.store.valuegenerator.ValueGenerationException)

Aggregations

SQLException (java.sql.SQLException)8 ValueGenerationException (org.datanucleus.store.valuegenerator.ValueGenerationException)8 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)6 PreparedStatement (java.sql.PreparedStatement)5 SQLController (org.datanucleus.store.rdbms.SQLController)5 ResultSet (java.sql.ResultSet)4 ValueGenerationBlock (org.datanucleus.store.valuegenerator.ValueGenerationBlock)4 ArrayList (java.util.ArrayList)3 DatastoreAdapter (org.datanucleus.store.rdbms.adapter.DatastoreAdapter)3 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)2 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)2 List (java.util.List)1 NucleusException (org.datanucleus.exceptions.NucleusException)1 DatastoreIdentifier (org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)1