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);
}
}
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;
}
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);
}
}
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);
}
}
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;
}
Aggregations