use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class FKListStore method updateElementFk.
/**
* Utility to update a foreign-key in the element in the case of a unidirectional 1-N relationship.
* @param ownerOP ObjectProvider for the owner
* @param element The element to update
* @param owner The owner object to set in the FK
* @param index The index position (or -1 if not known)
* @return Whether it was performed successfully
*/
private boolean updateElementFk(ObjectProvider ownerOP, Object element, Object owner, int index) {
if (element == null) {
return false;
}
ExecutionContext ec = ownerOP.getExecutionContext();
String updateFkStmt = getUpdateFkStmt(element);
boolean retval;
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, updateFkStmt, false);
try {
ComponentInfo elemInfo = getComponentInfoForElement(element);
JavaTypeMapping ownerMapping = elemInfo.getOwnerMapping();
JavaTypeMapping elemMapping = elemInfo.getDatastoreClass().getIdMapping();
JavaTypeMapping orderMapping = elemInfo.getDatastoreClass().getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_INDEX);
int jdbcPosition = 1;
if (owner == null) {
if (ownerMemberMetaData != null) {
ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null, ownerOP, ownerMemberMetaData.getAbsoluteFieldNumber());
} else {
ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null);
}
jdbcPosition += ownerMapping.getNumberOfDatastoreMappings();
} else {
jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this);
}
if (orderMapping != null) {
jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, orderMapping);
}
if (relationDiscriminatorMapping != null) {
jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
}
jdbcPosition = BackingStoreHelper.populateElementForWhereClauseInStatement(ec, ps, element, jdbcPosition, elemMapping);
sqlControl.executeStatementUpdate(ec, mconn, updateFkStmt, ps, true);
retval = true;
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("056027", updateFkStmt), e);
}
return retval;
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class FKListStore method set.
/**
* Method to set an object in the List at a position.
* @param ownerOP ObjectProvider for the owner
* @param index The item index
* @param element What to set it to.
* @param allowDependentField Whether to enable dependent-field deletes during the set
* @return The value before setting.
*/
public E set(ObjectProvider ownerOP, int index, Object element, boolean allowDependentField) {
// Last argument means don't set the position on any INSERT
validateElementForWriting(ownerOP, element, -1);
// Find the original element at this position
E oldElement = null;
List fieldVal = (List) ownerOP.provideField(ownerMemberMetaData.getAbsoluteFieldNumber());
if (fieldVal != null && fieldVal instanceof BackedSCO && ((BackedSCO) fieldVal).isLoaded()) {
// Already loaded in the wrapper
oldElement = (E) fieldVal.get(index);
} else {
oldElement = get(ownerOP, index);
}
ManagedConnection mconn = null;
try {
ExecutionContext ec = ownerOP.getExecutionContext();
SQLController sqlControl = storeMgr.getSQLController();
mconn = storeMgr.getConnectionManager().getConnection(ec);
// Unset the existing object from this position
String theUnsetStmt = getUnsetStmt();
try {
PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, theUnsetStmt, false);
try {
int jdbcPosition = 1;
jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this);
if (orderMapping != null) {
jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, orderMapping);
}
if (relationDiscriminatorMapping != null) {
jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this);
}
sqlControl.executeStatementUpdate(ec, mconn, theUnsetStmt, ps, true);
} finally {
sqlControl.closeStatement(mconn, ps);
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("056015", theUnsetStmt), e);
} finally {
}
// Set the new object at this position
String theSetStmt = getSetStmt(element);
try {
PreparedStatement ps2 = sqlControl.getStatementForUpdate(mconn, theSetStmt, false);
try {
ComponentInfo elemInfo = getComponentInfoForElement(element);
JavaTypeMapping elemMapping = this.elementMapping;
JavaTypeMapping orderMapping = this.orderMapping;
if (elemInfo != null) {
elemMapping = elemInfo.getDatastoreClass().getIdMapping();
orderMapping = elemInfo.getDatastoreClass().getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_INDEX);
}
int jdbcPosition = 1;
jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps2, jdbcPosition, this);
if (orderMapping != null) {
jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps2, index, jdbcPosition, orderMapping);
}
if (relationDiscriminatorMapping != null) {
jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps2, jdbcPosition, this);
}
jdbcPosition = BackingStoreHelper.populateElementForWhereClauseInStatement(ec, ps2, element, jdbcPosition, elemMapping);
sqlControl.executeStatementUpdate(ec, mconn, theSetStmt, ps2, true);
} finally {
sqlControl.closeStatement(mconn, ps2);
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("056015", theSetStmt), e);
}
} finally {
if (mconn != null) {
mconn.release();
}
}
// Dependent field
boolean dependent = getOwnerMemberMetaData().getCollection().isDependentElement();
if (getOwnerMemberMetaData().isCascadeRemoveOrphans()) {
dependent = true;
}
if (dependent && allowDependentField) {
if (oldElement != null) {
// Delete the element if it is dependent and doesnt have a duplicate entry in the list
ownerOP.getExecutionContext().deleteObjectInternal(oldElement);
}
}
return oldElement;
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class JoinListStore method getIteratorStatement.
/**
* Method to return the SQLStatement and mapping for an iterator for this backing store.
* Create a statement of the form
* <pre>
* SELECT ELEM_COLS
* FROM JOIN_TBL
* [JOIN ELEM_TBL ON ELEM_TBL.ID = JOIN_TBL.ELEM_ID]
* [WHERE]
* [JOIN_TBL.OWNER_ID = {value}] [AND]
* [JOIN_TBL.DISCRIM = {discrimValue}]
* [ORDER BY {orderClause}]
* </pre>
* @param ec ExecutionContext
* @param fp FetchPlan to use in determing which fields of element to select
* @param addRestrictionOnOwner Whether to restrict to a particular owner (otherwise functions as bulk fetch for many owners).
* @param startIdx Start index for the iterator (or -1)
* @param endIdx End index for the iterator (or -1)
* @return The SQLStatement and its associated StatementClassMapping
*/
public IteratorStatement getIteratorStatement(ExecutionContext ec, FetchPlan fp, boolean addRestrictionOnOwner, int startIdx, int endIdx) {
SelectStatement sqlStmt = null;
StatementClassMapping stmtClassMapping = new StatementClassMapping();
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
if (elementsAreEmbedded || elementsAreSerialised) {
// Element = embedded, serialised (maybe Non-PC)
// Just select the join table since we're going to return the embedded/serialised columns from it
sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
// Select the element column - first select is assumed by ListStoreIterator
sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
// TODO If embedded element and it includes 1-1/N-1 in FetchPlan then select its fields also
} else if (elementMapping instanceof ReferenceMapping) {
// Element = Reference type (interface/Object)
// Just select the join table since we're going to return the implementation id columns only
sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
// Select the reference column(s) - first select is assumed by ListStoreIterator
sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
} else {
// Join to the element table(s)
if (elementInfo != null) {
for (int i = 0; i < elementInfo.length; i++) {
// TODO This will only work if all element types have a discriminator
final int elementNo = i;
final Class elementCls = clr.classForName(elementInfo[elementNo].getClassName());
SelectStatement elementStmt = null;
if (elementInfo[elementNo].getDiscriminatorStrategy() != null && elementInfo[elementNo].getDiscriminatorStrategy() != DiscriminatorStrategy.NONE) {
// The element uses a discriminator so just use that in the SELECT
String elementType = ownerMemberMetaData.getCollection().getElementType();
if (ClassUtils.isReferenceType(clr.classForName(elementType))) {
String[] clsNames = storeMgr.getNucleusContext().getMetaDataManager().getClassesImplementingInterface(elementType, clr);
Class[] cls = new Class[clsNames.length];
for (int j = 0; j < clsNames.length; j++) {
cls[j] = clr.classForName(clsNames[j]);
}
SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null, containerTable, null, elementMapping);
if (allowNulls) {
stmtGen.setOption(SelectStatementGenerator.OPTION_ALLOW_NULLS);
}
elementStmt = stmtGen.getStatement(ec);
} else {
SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, elementCls, true, null, null, containerTable, null, elementMapping);
if (allowNulls) {
stmtGen.setOption(SelectStatementGenerator.OPTION_ALLOW_NULLS);
}
elementStmt = stmtGen.getStatement(ec);
}
iterateUsingDiscriminator = true;
} else {
// No discriminator, but subclasses so use UNIONs
SelectStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, elementCls, true, null, null, containerTable, null, elementMapping);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
stmtClassMapping.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
elementStmt = stmtGen.getStatement(ec);
}
if (sqlStmt == null) {
sqlStmt = elementStmt;
} else {
sqlStmt.union(elementStmt);
}
}
if (sqlStmt == null) {
throw new NucleusException("Error in generation of SQL statement for iterator over (Join) list. Statement is null");
}
// Select the required fields
SQLTable elementSqlTbl = sqlStmt.getTable(elementInfo[0].getDatastoreClass(), sqlStmt.getPrimaryTable().getGroupName());
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, stmtClassMapping, fp, elementSqlTbl, elementCmd, fp.getMaxFetchDepth());
} else {
throw new NucleusException("Unable to create SQL statement to retrieve elements of List");
}
}
if (addRestrictionOnOwner) {
// Apply condition on join-table owner field to filter by owner
SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
}
if (relationDiscriminatorMapping != null) {
// Apply condition on distinguisher field to filter by distinguisher (when present)
SQLTable distSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), relationDiscriminatorMapping);
SQLExpression distExpr = exprFactory.newExpression(sqlStmt, distSqlTbl, relationDiscriminatorMapping);
SQLExpression distVal = exprFactory.newLiteral(sqlStmt, relationDiscriminatorMapping, relationDiscriminatorValue);
sqlStmt.whereAnd(distExpr.eq(distVal), true);
}
if (indexedList) {
// "Indexed List" so allow restriction on returned indexes
boolean needsOrdering = true;
if (startIdx == -1 && endIdx == -1) {
// Just restrict to >= 0 so we don't get any disassociated elements
SQLExpression indexExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression indexVal = exprFactory.newLiteral(sqlStmt, orderMapping, 0);
sqlStmt.whereAnd(indexExpr.ge(indexVal), true);
} else if (startIdx >= 0 && endIdx == startIdx) {
// Particular index required so add restriction
needsOrdering = false;
SQLExpression indexExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression indexVal = exprFactory.newLiteral(sqlStmt, orderMapping, startIdx);
sqlStmt.whereAnd(indexExpr.eq(indexVal), true);
} else {
// Add restrictions on start/end indices as required
if (startIdx >= 0) {
SQLExpression indexExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression indexVal = exprFactory.newLiteral(sqlStmt, orderMapping, startIdx);
sqlStmt.whereAnd(indexExpr.ge(indexVal), true);
} else {
// Just restrict to >= 0 so we don't get any disassociated elements
SQLExpression indexExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression indexVal = exprFactory.newLiteral(sqlStmt, orderMapping, 0);
sqlStmt.whereAnd(indexExpr.ge(indexVal), true);
}
if (endIdx >= 0) {
SQLExpression indexExpr2 = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression indexVal2 = exprFactory.newLiteral(sqlStmt, orderMapping, endIdx);
sqlStmt.whereAnd(indexExpr2.lt(indexVal2), true);
}
}
if (needsOrdering) {
// Order by the ordering column, when present
SQLTable orderSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression[] orderExprs = new SQLExpression[orderMapping.getNumberOfDatastoreMappings()];
boolean[] descendingOrder = new boolean[orderMapping.getNumberOfDatastoreMappings()];
orderExprs[0] = exprFactory.newExpression(sqlStmt, orderSqlTbl, orderMapping);
sqlStmt.setOrdering(orderExprs, descendingOrder);
}
} else {
if (elementInfo != null) {
// Apply ordering defined by <order-by>
DatastoreClass elementTbl = elementInfo[0].getDatastoreClass();
FieldOrder[] orderComponents = ownerMemberMetaData.getOrderMetaData().getFieldOrders();
SQLExpression[] orderExprs = new SQLExpression[orderComponents.length];
boolean[] orderDirs = new boolean[orderComponents.length];
for (int i = 0; i < orderComponents.length; i++) {
String fieldName = orderComponents[i].getFieldName();
JavaTypeMapping fieldMapping = elementTbl.getMemberMapping(elementInfo[0].getAbstractClassMetaData().getMetaDataForMember(fieldName));
orderDirs[i] = !orderComponents[i].isForward();
SQLTable fieldSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), fieldMapping);
orderExprs[i] = exprFactory.newExpression(sqlStmt, fieldSqlTbl, fieldMapping);
}
sqlStmt.setOrdering(orderExprs, orderDirs);
}
}
return new IteratorStatement(this, sqlStmt, stmtClassMapping);
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class JoinPersistableRelationStore method getUpdateStmt.
/**
* Generates the statement for updating items.
* <PRE>
* UPDATE JOINTABLE SET RELATED_COL = ? WHERE OWNER_COL = ?
* </PRE>
* @return The Statement for updating an item
*/
protected String getUpdateStmt() {
if (updateStmt == null) {
JavaTypeMapping ownerMapping = joinTable.getOwnerMapping();
JavaTypeMapping relatedMapping = joinTable.getRelatedMapping();
StringBuilder stmt = new StringBuilder("UPDATE ");
stmt.append(joinTable.toString());
stmt.append(" SET ");
for (int i = 0; i < relatedMapping.getNumberOfDatastoreMappings(); i++) {
if (i > 0) {
stmt.append(",");
}
stmt.append(relatedMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString());
stmt.append("=");
stmt.append(ownerMapping.getDatastoreMapping(i).getInsertionInputParameter());
}
stmt.append(" WHERE ");
BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, null, true);
updateStmt = stmt.toString();
}
return updateStmt;
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class JoinPersistableRelationStore method getAddStmt.
/**
* Generates the statement for adding items.
* <PRE>
* INSERT INTO JOINTABLE (OWNER_COL, RELATED_COL) VALUES (?,?)
* </PRE>
* @return The Statement for adding an item
*/
protected String getAddStmt() {
if (addStmt == null) {
JavaTypeMapping ownerMapping = joinTable.getOwnerMapping();
JavaTypeMapping relatedMapping = joinTable.getRelatedMapping();
StringBuilder stmt = new StringBuilder("INSERT INTO ");
stmt.append(joinTable.toString());
stmt.append(" (");
for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++) {
if (i > 0) {
stmt.append(",");
}
stmt.append(ownerMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString());
}
for (int i = 0; i < relatedMapping.getNumberOfDatastoreMappings(); i++) {
stmt.append(",");
stmt.append(relatedMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString());
}
stmt.append(") VALUES (");
for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++) {
if (i > 0) {
stmt.append(",");
}
stmt.append(ownerMapping.getDatastoreMapping(i).getInsertionInputParameter());
}
for (int i = 0; i < relatedMapping.getNumberOfDatastoreMappings(); i++) {
stmt.append(",");
stmt.append(relatedMapping.getDatastoreMapping(0).getInsertionInputParameter());
}
stmt.append(") ");
addStmt = stmt.toString();
}
return addStmt;
}
Aggregations