Search in sources :

Example 1 with MappedDatastoreException

use of org.datanucleus.store.rdbms.exceptions.MappedDatastoreException in project datanucleus-rdbms by datanucleus.

the class FKArrayStore method iterator.

/**
 * Accessor for an iterator for the set.
 * @param ownerOP ObjectProvider for the set.
 * @return Iterator for the set.
 */
public Iterator<E> iterator(ObjectProvider ownerOP) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    if (elementInfo == null || elementInfo.length == 0) {
        return null;
    }
    // Generate the statement, and statement mapping/parameter information
    IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ownerOP.getExecutionContext().getFetchPlan(), true);
    SelectStatement sqlStmt = iterStmt.getSelectStatement();
    StatementClassMapping iteratorMappingDef = iterStmt.getStatementClassMapping();
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    StatementParameterMapping iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    if (ec.getTransaction().getSerializeRead() != null && ec.getTransaction().getSerializeRead()) {
        sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
    }
    String stmt = sqlStmt.getSQLText().toSQL();
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            // Create the statement
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt);
            // Set the owner
            ObjectProvider stmtOwnerOP = BackingStoreHelper.getOwnerObjectProviderForBackingStore(ownerOP);
            int numParams = ownerIdx.getNumberOfParameterOccurrences();
            for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
                ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), stmtOwnerOP.getObject());
            }
            try {
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmt, ps);
                try {
                    ResultObjectFactory rof = null;
                    if (elementsAreEmbedded || elementsAreSerialised) {
                        throw new NucleusException("Cannot have FK array with non-persistent objects");
                    }
                    rof = new PersistentClassROF(ec, rs, false, iteratorMappingDef, elementCmd, clr.classForName(elementType));
                    return new ArrayStoreIterator(ownerOP, rs, rof, this);
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException | MappedDatastoreException e) {
        throw new NucleusDataStoreException(Localiser.msg("056006", stmt), e);
    }
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) SQLException(java.sql.SQLException) ResultObjectFactory(org.datanucleus.store.rdbms.query.ResultObjectFactory) PreparedStatement(java.sql.PreparedStatement) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) PersistentClassROF(org.datanucleus.store.rdbms.query.PersistentClassROF) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 2 with MappedDatastoreException

use of org.datanucleus.store.rdbms.exceptions.MappedDatastoreException in project datanucleus-rdbms by datanucleus.

the class FKListStore method internalAdd.

/**
 * Internal method for adding an item to the List.
 * @param ownerOP ObjectProvider for the owner
 * @param startAt The start position
 * @param atEnd Whether to add at the end
 * @param c The Collection of elements to add.
 * @param size Current size of list (if known). -1 if not known
 * @return Whether it was successful
 */
protected boolean internalAdd(ObjectProvider ownerOP, int startAt, boolean atEnd, Collection<E> c, int size) {
    if (c == null || c.size() == 0) {
        return true;
    }
    // Check what we have persistent already
    int currentListSize = (size < 0 ? size(ownerOP) : size);
    boolean shiftingElements = true;
    if (atEnd || startAt == currentListSize) {
        shiftingElements = false;
        // Not shifting so we insert from the end
        startAt = currentListSize;
    }
    boolean elementsNeedPositioning = false;
    int position = startAt;
    Iterator elementIter = c.iterator();
    while (elementIter.hasNext()) {
        // Persist any non-persistent objects optionally at their final list position (persistence-by-reachability)
        if (shiftingElements) {
            // We have to shift things so dont bother with positioning
            position = -1;
        }
        boolean inserted = validateElementForWriting(ownerOP, elementIter.next(), position);
        if (!inserted || shiftingElements) {
            // This element wasnt positioned in the validate so we need to set the positions later
            elementsNeedPositioning = true;
        }
        if (!shiftingElements) {
            position++;
        }
    }
    if (shiftingElements) {
        // all ids after the position we insert at
        try {
            // Calculate the amount we need to shift any existing elements by
            // This is used where inserting between existing elements and have to shift down all elements after the start point
            int shift = c.size();
            ExecutionContext ec = ownerOP.getExecutionContext();
            ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
            try {
                // shift up existing elements after start position by "shift"
                for (int i = currentListSize - 1; i >= startAt; i--) {
                    // Shift the index of this row by "shift"
                    internalShift(ownerOP, mconn, true, i, shift, false);
                }
            } finally {
                mconn.release();
            }
        } catch (MappedDatastoreException e) {
            // An error was encountered during the shift process so abort here
            throw new NucleusDataStoreException(Localiser.msg("056009", e.getMessage()), e.getCause());
        }
    }
    if (shiftingElements || elementsNeedPositioning) {
        // Some elements have been shifted so the new elements need positioning now, or we already had some
        // of the new elements persistent and so they need their positions setting now
        elementIter = c.iterator();
        while (elementIter.hasNext()) {
            Object element = elementIter.next();
            updateElementFk(ownerOP, element, ownerOP.getObject(), startAt);
            startAt++;
        }
    }
    return true;
}
Also used : MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) ListIterator(java.util.ListIterator) Iterator(java.util.Iterator) ManagedConnection(org.datanucleus.store.connection.ManagedConnection)

Example 3 with MappedDatastoreException

use of org.datanucleus.store.rdbms.exceptions.MappedDatastoreException in project datanucleus-rdbms by datanucleus.

the class FKListStore method listIterator.

/**
 * Accessor for an iterator through the list elements.
 * @param ownerOP ObjectProvider for the owner.
 * @param startIdx The start index in the list (only for indexed lists)
 * @param endIdx The end index in the list (only for indexed lists)
 * @return The List Iterator
 */
protected ListIterator<E> listIterator(ObjectProvider ownerOP, int startIdx, int endIdx) {
    ExecutionContext ec = ownerOP.getExecutionContext();
    Transaction tx = ec.getTransaction();
    if (elementInfo == null || elementInfo.length == 0) {
        return null;
    }
    // Generate the statement. Note that this is not cached since depends on the current FetchPlan and other things
    IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ec.getFetchPlan(), true, startIdx, endIdx);
    SelectStatement sqlStmt = iterStmt.getSelectStatement();
    StatementClassMapping resultMapping = iterStmt.getStatementClassMapping();
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    if (tx.getSerializeRead() != null && tx.getSerializeRead()) {
        sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
    }
    String stmt = sqlStmt.getSQLText().toSQL();
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            // Create the statement
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt);
            // Set the owner
            ObjectProvider stmtOwnerOP = BackingStoreHelper.getOwnerObjectProviderForBackingStore(ownerOP);
            int numParams = ownerIdx.getNumberOfParameterOccurrences();
            for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
                ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), stmtOwnerOP.getObject());
            }
            try {
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmt, ps);
                try {
                    ResultObjectFactory rof = null;
                    if (elementsAreEmbedded || elementsAreSerialised) {
                        throw new NucleusException("Cannot have FK set with non-persistent objects");
                    }
                    rof = new PersistentClassROF(ec, rs, false, resultMapping, elementCmd, clr.classForName(elementType));
                    return new ListStoreIterator(ownerOP, rs, rof, this);
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException | MappedDatastoreException e) {
        throw new NucleusDataStoreException(Localiser.msg("056006", stmt), e);
    }
}
Also used : MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) SQLException(java.sql.SQLException) ResultObjectFactory(org.datanucleus.store.rdbms.query.ResultObjectFactory) PreparedStatement(java.sql.PreparedStatement) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) Transaction(org.datanucleus.Transaction) PersistentClassROF(org.datanucleus.store.rdbms.query.PersistentClassROF) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 4 with MappedDatastoreException

use of org.datanucleus.store.rdbms.exceptions.MappedDatastoreException in project datanucleus-rdbms by datanucleus.

the class JoinListStore method internalRemove.

private int[] internalRemove(ObjectProvider op, ManagedConnection conn, boolean batched, Object element, boolean executeNow) throws MappedDatastoreException {
    ExecutionContext ec = op.getExecutionContext();
    SQLController sqlControl = storeMgr.getSQLController();
    String removeStmt = getRemoveStmt(element);
    try {
        PreparedStatement ps = sqlControl.getStatementForUpdate(conn, removeStmt, batched);
        try {
            int jdbcPosition = 1;
            jdbcPosition = BackingStoreHelper.populateOwnerInStatement(op, ec, ps, jdbcPosition, this);
            jdbcPosition = BackingStoreHelper.populateElementForWhereClauseInStatement(ec, ps, element, jdbcPosition, elementMapping);
            if (relationDiscriminatorMapping != null) {
                jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
            }
            // Execute the statement
            return sqlControl.executeStatementUpdate(ec, conn, removeStmt, ps, executeNow);
        } finally {
            sqlControl.closeStatement(conn, ps);
        }
    } catch (SQLException sqle) {
        throw new MappedDatastoreException("SQLException", sqle);
    }
}
Also used : MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) ExecutionContext(org.datanucleus.ExecutionContext) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) SQLController(org.datanucleus.store.rdbms.SQLController)

Example 5 with MappedDatastoreException

use of org.datanucleus.store.rdbms.exceptions.MappedDatastoreException in project datanucleus-rdbms by datanucleus.

the class JoinListStore method removeAll.

/**
 * Remove all elements from a collection from the association owner vs
 * elements. Performs the removal in 3 steps. The first gets the indices
 * that will be removed (and the highest index present). The second step
 * removes these elements from the list. The third step updates the indices
 * of the remaining indices to fill the holes created.
 * @param op ObjectProvider
 * @param elements Collection of elements to remove
 * @return Whether the database was updated
 */
public boolean removeAll(ObjectProvider op, Collection elements, int size) {
    if (elements == null || elements.size() == 0) {
        return false;
    }
    // Get the current size of the list (and hence maximum index size)
    int currentListSize = size(op);
    // Get the indices of the elements we are going to remove (highest first)
    int[] indices = getIndicesOf(op, elements);
    if (indices == null) {
        return false;
    }
    boolean modified = false;
    SQLController sqlControl = storeMgr.getSQLController();
    ExecutionContext ec = op.getExecutionContext();
    // Remove the specified elements from the join table
    String removeAllStmt = getRemoveAllStmt(elements);
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        try {
            PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, removeAllStmt, false);
            try {
                int jdbcPosition = 1;
                Iterator iter = elements.iterator();
                while (iter.hasNext()) {
                    Object element = iter.next();
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(op, ec, ps, jdbcPosition, this);
                    jdbcPosition = BackingStoreHelper.populateElementForWhereClauseInStatement(ec, ps, element, jdbcPosition, elementMapping);
                    if (relationDiscriminatorMapping != null) {
                        jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
                    }
                }
                int[] number = sqlControl.executeStatementUpdate(ec, mconn, removeAllStmt, ps, true);
                if (number[0] > 0) {
                    modified = true;
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        NucleusLogger.DATASTORE.error(e);
        throw new NucleusDataStoreException(Localiser.msg("056012", removeAllStmt), e);
    }
    // Shift the remaining indices to remove the holes in ordering
    try {
        boolean batched = storeMgr.allowsBatching();
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        try {
            for (int i = 0; i < currentListSize; i++) {
                // Find the number of deleted indexes above this index
                int shift = 0;
                boolean removed = false;
                for (int j = 0; j < indices.length; j++) {
                    if (indices[j] == i) {
                        removed = true;
                        break;
                    }
                    if (indices[j] < i) {
                        shift++;
                    }
                }
                if (!removed && shift > 0) {
                    internalShift(op, mconn, batched, i, -1 * shift, (i == currentListSize - 1));
                }
            }
        } finally {
            mconn.release();
        }
    } catch (MappedDatastoreException e) {
        NucleusLogger.DATASTORE.error(e);
        throw new NucleusDataStoreException(Localiser.msg("056012", removeAllStmt), e);
    }
    // Dependent field
    boolean dependent = getOwnerMemberMetaData().getCollection().isDependentElement();
    if (getOwnerMemberMetaData().isCascadeRemoveOrphans()) {
        dependent = true;
    }
    if (dependent) {
        // "delete-dependent" : delete elements if the collection is marked as dependent
        // TODO What if the collection contains elements that are not in the List ? should not delete them
        op.getExecutionContext().deleteObjects(elements.toArray());
    }
    return modified;
}
Also used : MappedDatastoreException(org.datanucleus.store.rdbms.exceptions.MappedDatastoreException) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) ListIterator(java.util.ListIterator) Iterator(java.util.Iterator) ManagedConnection(org.datanucleus.store.connection.ManagedConnection)

Aggregations

ExecutionContext (org.datanucleus.ExecutionContext)27 MappedDatastoreException (org.datanucleus.store.rdbms.exceptions.MappedDatastoreException)27 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)21 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)21 SQLException (java.sql.SQLException)20 SQLController (org.datanucleus.store.rdbms.SQLController)20 PreparedStatement (java.sql.PreparedStatement)19 ResultSet (java.sql.ResultSet)9 ObjectProvider (org.datanucleus.state.ObjectProvider)9 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)9 PersistentClassROF (org.datanucleus.store.rdbms.query.PersistentClassROF)8 ResultObjectFactory (org.datanucleus.store.rdbms.query.ResultObjectFactory)8 StatementClassMapping (org.datanucleus.store.rdbms.query.StatementClassMapping)6 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)6 Iterator (java.util.Iterator)5 Transaction (org.datanucleus.Transaction)5 ArrayList (java.util.ArrayList)4 List (java.util.List)3 ListIterator (java.util.ListIterator)3 NucleusException (org.datanucleus.exceptions.NucleusException)3