use of org.datanucleus.store.rdbms.mapping.column.ColumnMapping in project datanucleus-rdbms by datanucleus.
the class EmbeddedMapping method addMappingForMember.
/**
* Method to add a mapping for the specified member to this mapping.
* @param embCmd Class that the member belongs to
* @param embMmd Member to be added
* @param embmdMmds Metadata for embedded members in the "embedded" specification (if any)
*/
private void addMappingForMember(AbstractClassMetaData embCmd, AbstractMemberMetaData embMmd, List<AbstractMemberMetaData> embmdMmds) {
if (emd != null && emd.getOwnerMember() != null && emd.getOwnerMember().equals(embMmd.getName())) {
// Do nothing since we don't map owner fields (since the owner is the containing object)
} else {
// Find the (embedded) member metadata for this member
AbstractMemberMetaData embeddedMmd = null;
for (AbstractMemberMetaData embmdMmd : embmdMmds) {
AbstractMemberMetaData embMmdForMmds = embCmd.getMetaDataForMember(embmdMmd.getName());
if (embMmdForMmds != null) {
if (embMmdForMmds.getAbsoluteFieldNumber() == embMmd.getAbsoluteFieldNumber()) {
// Same as the member we are processing, so use it
embeddedMmd = embmdMmd;
break;
}
}
}
// Add mapping
JavaTypeMapping embMmdMapping;
MappingManager mapMgr = table.getStoreManager().getMappingManager();
if (embeddedMmd != null) {
// User has provided a field definition so map with that
embMmdMapping = mapMgr.getMapping(table, embeddedMmd, clr, FieldRole.ROLE_FIELD);
} else {
// User hasn't provided a field definition so map with the classes own definition
embMmdMapping = mapMgr.getMapping(table, embMmd, clr, FieldRole.ROLE_FIELD);
}
if (embMmd.getRelationType(clr) != RelationType.NONE && embMmdMapping instanceof AbstractContainerMapping) {
// TODO Support 1-N (unidirectional) relationships and use owner object as the key in the join table See #core-171
// Removing this block would be the first step, but then we need to update scostore classes to allow for this case, and update
// table of element to link back to the owner of this embedded PC
NucleusLogger.PERSISTENCE.warn("Embedded object at " + getMemberMetaData().getFullFieldName() + " has a member " + embMmd.getFullFieldName() + " that is a container. Not fully supported as part of an embedded object!");
}
// Use field number from embMmd, since the embedded mmd info doesn't have reliable field numbers
embMmdMapping.setAbsFieldNumber(embMmd.getAbsoluteFieldNumber());
this.addJavaTypeMapping(embMmdMapping);
int numCols = embMmdMapping.getNumberOfColumnMappings();
for (int j = 0; j < numCols; j++) {
// Register column with mapping
ColumnMapping colMapping = embMmdMapping.getColumnMapping(j);
this.addColumnMapping(colMapping);
if (this.mmd.isPrimaryKey()) {
// Overall embedded field should be part of PK, so make all columns part of it
Column col = colMapping.getColumn();
if (col != null) {
col.setPrimaryKey();
}
}
}
}
}
use of org.datanucleus.store.rdbms.mapping.column.ColumnMapping in project datanucleus-rdbms by datanucleus.
the class SQLFunctionMapping method getObject.
public Object getObject(ExecutionContext ec, ResultSet resultSet, int[] exprIndex) {
if (exprIndex == null) {
return null;
}
if (columnMappings == null || columnMappings.length == 0) {
// Set the columnMappings and javaType the first time this is used. Get the type from the ResultSetMetaData.
try {
ResultSetMetaData rsmd = resultSet.getMetaData();
int colType = rsmd.getColumnType(exprIndex[0]);
if (colType == Types.DOUBLE || colType == Types.DECIMAL) {
javaType = Double.class;
} else if (colType == Types.FLOAT) {
javaType = Float.class;
} else if (colType == Types.BOOLEAN) {
javaType = Boolean.class;
} else if (colType == Types.INTEGER || colType == Types.NUMERIC) {
javaType = Integer.class;
} else if (colType == Types.SMALLINT || colType == Types.TINYINT) {
javaType = Short.class;
} else if (colType == Types.BIGINT) {
javaType = BigInteger.class;
} else if (colType == Types.LONGVARCHAR || colType == Types.VARCHAR || colType == Types.NVARCHAR || colType == Types.CHAR || colType == Types.NCHAR) {
javaType = String.class;
} else {
javaType = Object.class;
}
// TODO Provide more comprehensive support for all types
} catch (SQLException e) {
e.printStackTrace();
}
Class columnMappingClass = storeMgr.getDatastoreAdapter().getColumnMappingClass(javaType.getName(), null, null, ec.getClassLoaderResolver(), null);
ColumnMapping columnMapping = ColumnMappingFactory.createMapping(columnMappingClass, this, storeMgr, null);
columnMappings = new ColumnMapping[1];
columnMappings[0] = columnMapping;
}
if (javaType == Double.class) {
return getColumnMapping(0).getDouble(resultSet, exprIndex[0]);
} else if (javaType == Float.class) {
return getColumnMapping(0).getFloat(resultSet, exprIndex[0]);
} else if (javaType == Integer.class) {
return getColumnMapping(0).getInt(resultSet, exprIndex[0]);
} else if (javaType == Long.class) {
return getColumnMapping(0).getLong(resultSet, exprIndex[0]);
} else if (javaType == Short.class) {
return getColumnMapping(0).getShort(resultSet, exprIndex[0]);
} else if (javaType == BigInteger.class) {
return getColumnMapping(0).getLong(resultSet, exprIndex[0]);
} else if (javaType == Boolean.class) {
return getColumnMapping(0).getBoolean(resultSet, exprIndex[0]);
} else if (javaType == String.class) {
return getColumnMapping(0).getString(resultSet, exprIndex[0]);
}
return getColumnMapping(0).getObject(resultSet, exprIndex[0]);
}
use of org.datanucleus.store.rdbms.mapping.column.ColumnMapping in project datanucleus-rdbms by datanucleus.
the class ClassTable method runCallBacks.
/**
* Execute the callbacks for the classes that this table maps to.
* @param clr ClassLoader resolver
*/
private void runCallBacks(ClassLoaderResolver clr) {
// Run callbacks for all classes managed by this table
Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
while (cmdIter.hasNext()) {
AbstractClassMetaData managedCmd = cmdIter.next();
if (managingClassCurrent != null && managingClassCurrent.equals(managedCmd.getFullClassName())) {
// We can't run callbacks for this class since it is still being initialised. Mark callbacks to run after it completes
runCallbacksAfterManageClass = true;
break;
}
Collection processedCallbacks = callbacksAppliedForManagedClass.get(managedCmd.getFullClassName());
Collection c = (Collection) storeMgr.getSchemaCallbacks().get(managedCmd.getFullClassName());
if (c != null) {
if (processedCallbacks == null) {
processedCallbacks = new HashSet();
callbacksAppliedForManagedClass.put(managedCmd.getFullClassName(), processedCallbacks);
}
for (Iterator it = c.iterator(); it.hasNext(); ) {
AbstractMemberMetaData callbackMmd = (AbstractMemberMetaData) it.next();
if (processedCallbacks.contains(callbackMmd)) {
continue;
}
processedCallbacks.add(callbackMmd);
if (callbackMmd.getJoinMetaData() == null) {
// 1-N FK relationship
AbstractMemberMetaData ownerFmd = callbackMmd;
if (ownerFmd.getMappedBy() != null) {
// Bidirectional (element has a PC mapping to the owner)
// Check that the "mapped-by" field in the other class actually exists
AbstractMemberMetaData fmd = null;
if (ownerFmd.getMappedBy().indexOf('.') > 0) {
// TODO Can we just use getRelatedMemberMetaData always?
AbstractMemberMetaData[] relMmds = ownerFmd.getRelatedMemberMetaData(clr);
fmd = (relMmds != null && relMmds.length > 0) ? relMmds[0] : null;
} else {
fmd = managedCmd.getMetaDataForMember(ownerFmd.getMappedBy());
}
if (fmd == null) {
throw new NucleusUserException(Localiser.msg("057036", ownerFmd.getMappedBy(), managedCmd.getFullClassName(), ownerFmd.getFullFieldName()));
}
if (ownerFmd.getMap() != null && storeMgr.getBooleanProperty(RDBMSPropertyNames.PROPERTY_RDBMS_UNIQUE_CONSTRAINTS_MAP_INVERSE)) {
initializeFKMapUniqueConstraints(ownerFmd);
}
boolean duplicate = false;
JavaTypeMapping fkDiscrimMapping = null;
JavaTypeMapping orderMapping = null;
if (ownerFmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN)) {
// Collection has a relation discriminator so we need to share the FK. Check for the required discriminator
String colName = ownerFmd.getValueForExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN);
if (colName == null) {
// No column defined so use a fallback name
colName = "RELATION_DISCRIM";
}
Set fkDiscrimEntries = getExternalFkDiscriminatorMappings().entrySet();
Iterator discrimMappingIter = fkDiscrimEntries.iterator();
while (discrimMappingIter.hasNext()) {
Map.Entry entry = (Map.Entry) discrimMappingIter.next();
JavaTypeMapping discrimMapping = (JavaTypeMapping) entry.getValue();
String discrimColName = (discrimMapping.getColumnMapping(0).getColumn().getColumnMetaData()).getName();
if (discrimColName.equalsIgnoreCase(colName)) {
duplicate = true;
fkDiscrimMapping = discrimMapping;
orderMapping = getExternalOrderMappings().get(entry.getKey());
break;
}
}
if (!duplicate) {
// Create the relation discriminator column since we dont have this discriminator
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(colName);
// Allow for elements not in any discriminated collection
colmd.setAllowsNull(Boolean.TRUE);
// Only support String discriminators currently
fkDiscrimMapping = storeMgr.getMappingManager().getMapping(String.class);
fkDiscrimMapping.setTable(this);
ColumnCreator.createIndexColumn(fkDiscrimMapping, storeMgr, clr, this, colmd, false);
}
if (fkDiscrimMapping != null) {
getExternalFkDiscriminatorMappings().put(ownerFmd, fkDiscrimMapping);
}
}
// Add the order mapping as necessary
addOrderMapping(ownerFmd, orderMapping, clr);
} else {
// Unidirectional (element knows nothing about the owner)
String ownerClassName = ownerFmd.getAbstractClassMetaData().getFullClassName();
JavaTypeMapping fkMapping = new PersistableMapping();
fkMapping.setTable(this);
fkMapping.initialize(storeMgr, ownerClassName);
JavaTypeMapping fkDiscrimMapping = null;
JavaTypeMapping orderMapping = null;
boolean duplicate = false;
try {
// Get the owner id mapping of the "1" end
DatastoreClass ownerTbl = storeMgr.getDatastoreClass(ownerClassName, clr);
if (ownerTbl == null) {
// Class doesn't have its own table (subclass-table) so find where it persists
AbstractClassMetaData[] ownerParentCmds = storeMgr.getClassesManagingTableForClass(ownerFmd.getAbstractClassMetaData(), clr);
if (ownerParentCmds.length > 1) {
throw new NucleusUserException("Relation (" + ownerFmd.getFullFieldName() + ") with multiple related tables (using subclass-table). Not supported");
}
ownerClassName = ownerParentCmds[0].getFullClassName();
ownerTbl = storeMgr.getDatastoreClass(ownerClassName, clr);
if (ownerTbl == null) {
throw new NucleusException("Failed to get owner table at other end of relation for field=" + ownerFmd.getFullFieldName());
}
}
JavaTypeMapping ownerIdMapping = ownerTbl.getIdMapping();
ColumnMetaDataContainer colmdContainer = null;
if (ownerFmd.hasCollection() || ownerFmd.hasArray()) {
// 1-N Collection/array
colmdContainer = ownerFmd.getElementMetaData();
} else if (ownerFmd.hasMap() && ownerFmd.getKeyMetaData() != null && ownerFmd.getKeyMetaData().getMappedBy() != null) {
// 1-N Map with key stored in the value
colmdContainer = ownerFmd.getValueMetaData();
} else if (ownerFmd.hasMap() && ownerFmd.getValueMetaData() != null && ownerFmd.getValueMetaData().getMappedBy() != null) {
// 1-N Map with value stored in the key
colmdContainer = ownerFmd.getKeyMetaData();
}
CorrespondentColumnsMapper correspondentColumnsMapping = new CorrespondentColumnsMapper(colmdContainer, this, ownerIdMapping, true);
int countIdFields = ownerIdMapping.getNumberOfColumnMappings();
for (int i = 0; i < countIdFields; i++) {
ColumnMapping refColumnMapping = ownerIdMapping.getColumnMapping(i);
JavaTypeMapping mapping = storeMgr.getMappingManager().getMapping(refColumnMapping.getJavaTypeMapping().getJavaType());
ColumnMetaData colmd = correspondentColumnsMapping.getColumnMetaDataByIdentifier(refColumnMapping.getColumn().getIdentifier());
if (colmd == null) {
throw new NucleusUserException(Localiser.msg("057035", refColumnMapping.getColumn().getIdentifier(), toString())).setFatal();
}
DatastoreIdentifier identifier = null;
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
if (colmd.getName() == null || colmd.getName().length() < 1) {
// No user provided name so generate one
identifier = idFactory.newForeignKeyFieldIdentifier(ownerFmd, null, refColumnMapping.getColumn().getIdentifier(), storeMgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(mapping.getJavaType()), FieldRole.ROLE_OWNER);
} else {
// User-defined name
identifier = idFactory.newColumnIdentifier(colmd.getName());
}
Column refColumn = addColumn(mapping.getJavaType().getName(), identifier, mapping, colmd);
refColumnMapping.getColumn().copyConfigurationTo(refColumn);
if ((colmd.getAllowsNull() == null) || (colmd.getAllowsNull() != null && colmd.isAllowsNull())) {
// User either wants it nullable, or haven't specified anything, so make it nullable
refColumn.setNullable(true);
}
fkMapping.addColumnMapping(getStoreManager().getMappingManager().createColumnMapping(mapping, refColumn, refColumnMapping.getJavaTypeMapping().getJavaType().getName()));
((PersistableMapping) fkMapping).addJavaTypeMapping(mapping);
}
} catch (DuplicateColumnException dce) {
// If the user hasnt specified "relation-discriminator-column" here we dont allow the sharing of columns
if (!ownerFmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN)) {
throw dce;
}
// Find the FK using this column and use it instead of creating a new one since we're sharing
Iterator fkIter = getExternalFkMappings().entrySet().iterator();
fkMapping = null;
while (fkIter.hasNext()) {
Map.Entry entry = (Map.Entry) fkIter.next();
JavaTypeMapping existingFkMapping = (JavaTypeMapping) entry.getValue();
for (int j = 0; j < existingFkMapping.getNumberOfColumnMappings(); j++) {
if (existingFkMapping.getColumnMapping(j).getColumn().getIdentifier().toString().equals(dce.getConflictingColumn().getIdentifier().toString())) {
// The FK is shared (and so if it is a List we also share the index)
fkMapping = existingFkMapping;
fkDiscrimMapping = externalFkDiscriminatorMappings.get(entry.getKey());
orderMapping = getExternalOrderMappings().get(entry.getKey());
break;
}
}
}
if (fkMapping == null) {
// Should never happen since we know there is a col duplicating ours
throw dce;
}
duplicate = true;
}
if (!duplicate && ownerFmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN)) {
// Create the relation discriminator column
String colName = ownerFmd.getValueForExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN);
if (colName == null) {
// No column defined so use a fallback name
colName = "RELATION_DISCRIM";
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(colName);
// Allow for elements not in any discriminated collection
colmd.setAllowsNull(Boolean.TRUE);
// Only support String discriminators currently
fkDiscrimMapping = storeMgr.getMappingManager().getMapping(String.class);
fkDiscrimMapping.setTable(this);
ColumnCreator.createIndexColumn(fkDiscrimMapping, storeMgr, clr, this, colmd, false);
}
// Save the external FK
getExternalFkMappings().put(ownerFmd, fkMapping);
if (fkDiscrimMapping != null) {
getExternalFkDiscriminatorMappings().put(ownerFmd, fkDiscrimMapping);
}
// Add the order mapping as necessary
addOrderMapping(ownerFmd, orderMapping, clr);
}
}
}
}
}
}
use of org.datanucleus.store.rdbms.mapping.column.ColumnMapping in project datanucleus-rdbms by datanucleus.
the class SelectStatement method select.
/**
* Add a select clause for the specified field (via its mapping).
* If an alias is supplied and there are more than 1 column for this mapping then they will have
* names like "{alias}_n" where n is the column number (starting at 0).
* @param table The SQLTable to select from (null implies the primary table)
* @param mapping The mapping for the field
* @param alias optional alias
* @param applyToUnions Whether to apply to unions
* @return The column index(es) in the statement for the specified field (1 is first).
*/
public int[] select(SQLTable table, JavaTypeMapping mapping, String alias, boolean applyToUnions) {
if (mapping == null) {
throw new NucleusException("Mapping to select is null");
} else if (table == null) {
// Default to the primary table if not specified
table = primaryTable;
}
if (mapping.getTable() != table.getTable()) {
throw new NucleusException("Table being selected from (\"" + table.getTable() + "\") is inconsistent with the column selected (\"" + mapping.getTable() + "\")");
}
invalidateStatement();
ColumnMapping[] mappings = mapping.getColumnMappings();
int[] selected = new int[mappings.length];
for (int i = 0; i < selected.length; i++) {
DatastoreIdentifier colAlias = null;
if (alias != null) {
String name = (selected.length > 1) ? (alias + "_" + i) : alias;
colAlias = rdbmsMgr.getIdentifierFactory().newColumnIdentifier(name);
}
SQLColumn col = new SQLColumn(table, mappings[i].getColumn(), colAlias);
selected[i] = selectItem(new SQLText(col.getColumnSelectString()), alias != null ? colAlias.toString() : null, true);
}
if (applyToUnions && unions != null && allowUnions) {
// Apply the select to all unions
Iterator<SelectStatement> unionIter = unions.iterator();
while (unionIter.hasNext()) {
SelectStatement stmt = unionIter.next();
stmt.select(table, mapping, alias);
}
}
return selected;
}
use of org.datanucleus.store.rdbms.mapping.column.ColumnMapping in project datanucleus-rdbms by datanucleus.
the class CharacterLiteral method setStatement.
protected void setStatement() {
st.clearStatement();
ColumnMapping colMapping = mapping.getColumnMapping(0);
if (colMapping.isIntegerBased()) {
st.append("" + (int) this.value.charAt(0));
} else {
st.append('\'').append(this.value).append('\'');
}
}
Aggregations