use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class ElementContainerStore method getSizeStmt.
/**
* Generate statement for getting the size of the container.
* The order part is only present when an order mapping is used.
* The discriminator part is only present when the element has a discriminator.
* <PRE>
* SELECT COUNT(*) FROM TBL THIS
* [INNER JOIN ELEM_TBL ELEM ON TBL.COL = ELEM.ID] - when no null
* [LEFT OUTER JOIN ELEM_TBL ELEM ON TBL.COL = ELEM.ID] - when allows null
* WHERE THIS.OWNERCOL=?
* [AND THIS.ORDERCOL IS NOT NULL]
* [AND (DISCRIMINATOR=? OR DISCRMINATOR=? OR DISCRIMINATOR=? [OR DISCRIMINATOR IS NULL])]
* [AND RELATION_DISCRIM=?]
* </PRE>
* The discriminator part includes all subclasses of the element type.
* If the element is in a different table to the container then an INNER JOIN will be present to
* link the two tables, and table aliases will be present also.
* @return The Statement returning the size of the container.
*/
protected String getSizeStmt() {
if (sizeStmt != null) {
// Statement exists and didn't need any discriminator when setting up the statement so just reuse it
return sizeStmt;
}
synchronized (this) {
boolean usingDiscriminatorInSizeStmt = false;
String containerAlias = "THIS";
StringBuilder stmt = new StringBuilder();
if (elementInfo == null) {
// Serialised/embedded elements in a join table
stmt.append("SELECT COUNT(*) FROM ").append(containerTable.toString()).append(" ").append(containerAlias);
stmt.append(" WHERE ");
BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
if (orderMapping != null) {
// eliminate records that are added but may not be positioned yet.
for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++) {
stmt.append(" AND ");
stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString());
stmt.append(">=0");
}
}
JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
stmt.append(" AND ").append(containerAlias).append(".");
stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
// TODO Cater for columns that store the DELETED flag as ("Y","N") or (1,0)
stmt.append("=FALSE");
}
if (relationDiscriminatorMapping != null) {
BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
}
sizeStmt = stmt.toString();
return sizeStmt;
}
if (usingJoinTable()) {
// Join table collection/array, so do COUNT of join table
String joinedElementAlias = "ELEM";
ComponentInfo elemInfo = elementInfo[0];
stmt.append("SELECT COUNT(*) FROM ").append(containerTable.toString()).append(" ").append(containerAlias);
// Add join to element table if required (only allows for 1 element table currently)
boolean joinedDiscrim = false;
if (elemInfo.getDiscriminatorMapping() != null) {
// Need join to the element table to restrict the discriminator
joinedDiscrim = true;
JavaTypeMapping elemIdMapping = elemInfo.getDatastoreClass().getIdMapping();
stmt.append(allowNulls ? " LEFT OUTER JOIN " : " INNER JOIN ");
stmt.append(elemInfo.getDatastoreClass().toString()).append(" ").append(joinedElementAlias).append(" ON ");
for (int j = 0; j < elementMapping.getNumberOfDatastoreMappings(); j++) {
if (j > 0) {
stmt.append(" AND ");
}
stmt.append(containerAlias).append(".").append(elementMapping.getDatastoreMapping(j).getColumn().getIdentifier());
stmt.append("=");
stmt.append(joinedElementAlias).append(".").append(elemIdMapping.getDatastoreMapping(j).getColumn().getIdentifier());
}
}
// TODO Add join to owner if ownerMapping is for supertable
stmt.append(" WHERE ");
BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
if (orderMapping != null) {
// eliminate records that are added but may not be positioned yet.
for (int j = 0; j < orderMapping.getNumberOfDatastoreMappings(); j++) {
stmt.append(" AND ");
stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
stmt.append(">=0");
}
}
JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
stmt.append(" AND ").append(containerAlias).append(".");
stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
stmt.append("=FALSE");
}
// Add a discriminator filter for collections with an element discriminator
StringBuilder discrStmt = new StringBuilder();
if (elemInfo.getDiscriminatorMapping() != null) {
usingDiscriminatorInSizeStmt = true;
JavaTypeMapping discrimMapping = elemInfo.getDiscriminatorMapping();
Collection<String> classNames = storeMgr.getSubClassesForClass(elemInfo.getClassName(), true, clr);
classNames.add(elemInfo.getClassName());
for (String className : classNames) {
Class cls = clr.classForName(className);
if (!Modifier.isAbstract(cls.getModifiers())) {
for (int j = 0; j < discrimMapping.getNumberOfDatastoreMappings(); j++) {
if (discrStmt.length() > 0) {
discrStmt.append(" OR ");
}
discrStmt.append(joinedDiscrim ? joinedElementAlias : containerAlias);
discrStmt.append(".");
discrStmt.append(discrimMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
discrStmt.append("=");
discrStmt.append(discrimMapping.getDatastoreMapping(j).getUpdateInputParameter());
}
}
}
}
if (discrStmt.length() > 0) {
stmt.append(" AND (");
stmt.append(discrStmt);
if (allowNulls) {
stmt.append(" OR ");
stmt.append(elemInfo.getDiscriminatorMapping().getDatastoreMapping(0).getColumn().getIdentifier().toString());
stmt.append(" IS NULL");
}
stmt.append(")");
}
if (relationDiscriminatorMapping != null) {
BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
}
} else {
// ForeignKey collection/array, so UNION all of the element COUNTs
for (int i = 0; i < elementInfo.length; i++) {
if (i > 0) {
stmt.append(" UNION ");
}
ComponentInfo elemInfo = elementInfo[i];
stmt.append("SELECT COUNT(*),").append("'" + elemInfo.getAbstractClassMetaData().getName() + "'");
stmt.append(" FROM ").append(elemInfo.getDatastoreClass().toString()).append(" ").append(containerAlias);
stmt.append(" WHERE ");
BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
if (orderMapping != null) {
// eliminate records that are added but may not be positioned yet.
for (int j = 0; j < orderMapping.getNumberOfDatastoreMappings(); j++) {
stmt.append(" AND ");
stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
stmt.append(">=0");
}
}
JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
stmt.append(" AND ").append(containerAlias).append(".");
stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
stmt.append("=FALSE");
}
// Add a discriminator filter for collections with an element discriminator
StringBuilder discrStmt = new StringBuilder();
if (elemInfo.getDiscriminatorMapping() != null) {
usingDiscriminatorInSizeStmt = true;
JavaTypeMapping discrimMapping = elemInfo.getDiscriminatorMapping();
Collection<String> classNames = storeMgr.getSubClassesForClass(elemInfo.getClassName(), true, clr);
classNames.add(elemInfo.getClassName());
for (String className : classNames) {
Class cls = clr.classForName(className);
if (!Modifier.isAbstract(cls.getModifiers())) {
for (int j = 0; j < discrimMapping.getNumberOfDatastoreMappings(); j++) {
if (discrStmt.length() > 0) {
discrStmt.append(" OR ");
}
discrStmt.append(containerAlias).append(".").append(discrimMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
discrStmt.append("=");
discrStmt.append(discrimMapping.getDatastoreMapping(j).getUpdateInputParameter());
}
}
}
}
if (discrStmt.length() > 0) {
stmt.append(" AND (");
stmt.append(discrStmt);
if (allowNulls) {
stmt.append(" OR ");
stmt.append(elemInfo.getDiscriminatorMapping().getDatastoreMapping(0).getColumn().getIdentifier().toString());
stmt.append(" IS NULL");
}
stmt.append(")");
}
if (relationDiscriminatorMapping != null) {
BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
}
}
}
if (!usingDiscriminatorInSizeStmt) {
sizeStmt = stmt.toString();
}
return stmt.toString();
}
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class SQLText method applyParametersToStatement.
/**
* Method to set the parameters in the supplied PreparedStatement using their mappings and
* provided values.
* @param ec execution context
* @param ps The PreparedStatement
*/
public void applyParametersToStatement(ExecutionContext ec, PreparedStatement ps) {
if (parameters != null) {
int num = 1;
Iterator<SQLStatementParameter> i = parameters.iterator();
while (i.hasNext()) {
SQLStatementParameter param = i.next();
JavaTypeMapping mapping = param.getMapping();
if (mapping != null) {
Object value = param.getValue();
if (param.getColumnNumber() >= 0) {
Object colValue = null;
if (value != null) {
// Parameter is for a particular column of the overall object/mapping
// so assume that the object is persistable (or id of persistable)
ClassLoaderResolver clr = ec.getClassLoaderResolver();
AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(mapping.getType(), clr);
RDBMSStoreManager storeMgr = mapping.getStoreManager();
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
colValue = mapping.getValueForDatastoreMapping(ec.getNucleusContext(), param.getColumnNumber(), value);
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
colValue = SQLStatementHelper.getValueForPrimaryKeyIndexOfObjectUsingReflection(value, param.getColumnNumber(), cmd, storeMgr, clr);
}
}
mapping.getDatastoreMapping(param.getColumnNumber()).setObject(ps, num, colValue);
num++;
} else {
mapping.setObject(ec, ps, MappingHelper.getMappingIndices(num, mapping), value);
if (mapping.getNumberOfDatastoreMappings() > 0) {
num += mapping.getNumberOfDatastoreMappings();
} else {
num += 1;
}
}
}
}
}
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class SelectStatement method addOrderingColumnsToSelect.
/**
* Convenience method to add any necessary columns to the SELECT that are needed
* by the ordering constraint.
*/
protected void addOrderingColumnsToSelect() {
if (// Don't do this for subqueries, since we will be selecting just the necessary column(s)
orderingExpressions != null && parent == null) {
// Add any ordering columns to the SELECT
DatastoreAdapter dba = getDatastoreAdapter();
if (dba.supportsOption(DatastoreAdapter.ORDERBY_USING_SELECT_COLUMN_INDEX)) {
// Order using the indexes of the ordering columns in the SELECT
orderingColumnIndexes = new int[orderingExpressions.length];
// Add the ordering columns to the selected list, saving the positions
for (int i = 0; i < orderingExpressions.length; ++i) {
orderingColumnIndexes[i] = selectItem(orderingExpressions[i].toSQLText(), null, !aggregated);
if (unions != null && allowUnions) {
Iterator<SelectStatement> iterator = unions.iterator();
while (iterator.hasNext()) {
SelectStatement stmt = iterator.next();
stmt.selectItem(orderingExpressions[i].toSQLText(), null, !aggregated);
}
}
}
} else if (dba.supportsOption(DatastoreAdapter.INCLUDE_ORDERBY_COLS_IN_SELECT)) {
// Order using column aliases "NUCORDER{i}"
for (int i = 0; i < orderingExpressions.length; ++i) {
if (orderingExpressions[i] instanceof ResultAliasExpression) {
// Nothing to do since this is ordering by a result alias
} else if (orderingExpressions[i].getNumberOfSubExpressions() == 1 || aggregated) {
String orderExprAlias = rdbmsMgr.getIdentifierFactory().getIdentifierInAdapterCase("NUCORDER" + i);
if (unions != null && allowUnions) {
Iterator<SelectStatement> iterator = unions.iterator();
while (iterator.hasNext()) {
SelectStatement stmt = iterator.next();
stmt.selectItem(orderingExpressions[i].toSQLText(), aggregated ? null : orderExprAlias, !aggregated);
}
}
selectItem(orderingExpressions[i].toSQLText(), aggregated ? null : orderExprAlias, !aggregated);
} else {
JavaTypeMapping m = orderingExpressions[i].getJavaTypeMapping();
DatastoreMapping[] mappings = m.getDatastoreMappings();
for (int j = 0; j < mappings.length; j++) {
String alias = rdbmsMgr.getIdentifierFactory().getIdentifierInAdapterCase("NUCORDER" + i + "_" + j);
DatastoreIdentifier aliasId = rdbmsMgr.getIdentifierFactory().newColumnIdentifier(alias);
SQLColumn col = new SQLColumn(orderingExpressions[i].getSQLTable(), mappings[j].getColumn(), aliasId);
selectItem(new SQLText(col.getColumnSelectString()), alias, !aggregated);
if (unions != null && allowUnions) {
Iterator<SelectStatement> iterator = unions.iterator();
while (iterator.hasNext()) {
SelectStatement stmt = iterator.next();
stmt.selectItem(new SQLText(col.getColumnSelectString()), alias, !aggregated);
}
}
}
}
}
}
}
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class UnionStatementGenerator method addTypeSelectForClass.
/**
* Convenience method to add a SELECT of a dummy column accessible as "DN_TYPE" storing the class name.
* @param stmt SQLStatement
* @param className Name of the class
*/
private void addTypeSelectForClass(SelectStatement stmt, String className) {
// Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
/*if (hasOption(OPTION_ALLOW_NULLS))
{
NullLiteral nullLtl = new NullLiteral(stmt, null, null, null);
stmt.select(nullLtl, NUC_TYPE_COLUMN);
}
else
{*/
// Add SELECT of dummy column accessible as "DN_TYPE" containing the classname
JavaTypeMapping m = storeMgr.getMappingManager().getMapping(String.class);
String nuctypeName = className;
if (maxClassNameLength > nuctypeName.length()) {
nuctypeName = StringUtils.leftAlignedPaddedString(nuctypeName, maxClassNameLength);
}
StringLiteral lit = new StringLiteral(stmt, m, nuctypeName, null);
stmt.select(lit, DN_TYPE_COLUMN);
/*}*/
}
use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.
the class SQLStatementHelper method getValueForPrimaryKeyIndexOfObjectUsingReflection.
/**
* Convenience method to use reflection to extract the value of a PK field of the provided object.
* @param value The value of the overall object
* @param index Index of the PK field whose value we need to return
* @param cmd Metadata for the class
* @param storeMgr Store manager
* @param clr ClassLoader resolver
* @return Value of this index of the PK field
*/
public static Object getValueForPrimaryKeyIndexOfObjectUsingReflection(Object value, int index, AbstractClassMetaData cmd, RDBMSStoreManager storeMgr, ClassLoaderResolver clr) {
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
throw new NucleusException("This method does not support datastore-identity");
}
int position = 0;
int[] pkPositions = cmd.getPKMemberPositions();
for (int pkPosition : pkPositions) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkPosition);
Object memberValue = null;
if (mmd instanceof FieldMetaData) {
memberValue = ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
} else {
memberValue = ClassUtils.getValueOfMethodByReflection(value, ClassUtils.getJavaBeanGetterName(mmd.getName(), false));
}
if (storeMgr.getApiAdapter().isPersistable(mmd.getType())) {
// Compound PK field, so recurse
// TODO Cater for cases without own table ("subclass-table")
AbstractClassMetaData subCmd = storeMgr.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
DatastoreClass subTable = storeMgr.getDatastoreClass(mmd.getTypeName(), clr);
JavaTypeMapping subMapping = subTable.getIdMapping();
Object subValue = getValueForPrimaryKeyIndexOfObjectUsingReflection(memberValue, index - position, subCmd, storeMgr, clr);
if (index < position + subMapping.getNumberOfDatastoreMappings()) {
return subValue;
}
position = position + subMapping.getNumberOfDatastoreMappings();
} else {
// Normal PK field
if (position == index) {
if (mmd instanceof FieldMetaData) {
return ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
}
return ClassUtils.getValueOfMethodByReflection(value, ClassUtils.getJavaBeanGetterName(mmd.getName(), false));
}
position++;
}
}
return null;
}
Aggregations