use of org.datanucleus.metadata.ColumnMetaData in project tests by datanucleus.
the class AnnotationPlusXMLTest method testColumn.
/**
* Check explicit column information in "package.jdo" and/or "package.orm".
*/
public void testColumn() {
// Person
ClassMetaData cmd = (ClassMetaData) metaDataMgr.getMetaDataForClass(Person.class.getName(), clr);
String prefix = cmd.getFullClassName() + " : ";
// "lastName"
AbstractMemberMetaData fmd = cmd.getMetaDataForMember("lastName");
ColumnMetaData[] colmds = fmd.getColumnMetaData();
assertEquals(prefix + "column identifier incorrect", "LASTNAME", colmds[0].getName());
assertEquals(prefix + "column length incorrect", new Integer(64), colmds[0].getLength());
assertEquals(prefix + "column JDBC type incorrect", JdbcType.VARCHAR, colmds[0].getJdbcType());
// "firstName"
fmd = cmd.getMetaDataForMember("firstName");
colmds = fmd.getColumnMetaData();
assertEquals(prefix + "column identifier incorrect", "FIRSTNAME", colmds[0].getName());
assertEquals(prefix + "column length incorrect", new Integer(32), colmds[0].getLength());
assertEquals(prefix + "column JDBC type incorrect", JdbcType.VARCHAR, colmds[0].getJdbcType());
// "emailAddress"
fmd = cmd.getMetaDataForMember("emailAddress");
colmds = fmd.getColumnMetaData();
assertEquals(prefix + "column identifier incorrect", "EMAILADDRESS", colmds[0].getName());
assertEquals(prefix + "column length incorrect", new Integer(128), colmds[0].getLength());
assertEquals(prefix + "column JDBC type incorrect", JdbcType.VARCHAR, colmds[0].getJdbcType());
// "dateOfBirth"
fmd = cmd.getMetaDataForMember("dateOfBirth");
colmds = fmd.getColumnMetaData();
assertEquals("column identifier incorrect", "DATEOFBIRTH", colmds[0].getName());
assertEquals("column JDBC type incorrect", JdbcType.TIMESTAMP, colmds[0].getJdbcType());
// package.orm (additional)
Map<String, String> extmds = fmd.getExtensions();
assertNotNull(prefix + "extension info is null!", extmds);
assertEquals(prefix + "incorrect number of extensions", 1, extmds.size());
assertTrue("extension not present", extmds.containsKey("insert-function"));
assertEquals("extension value is incorrect", "CURRENT_TIMESTAMP", extmds.get("insert-function"));
}
use of org.datanucleus.metadata.ColumnMetaData in project datanucleus-rdbms by datanucleus.
the class ClassTable method manageUnmappedColumns.
/**
* Adds on management of the columns in the defined MetaData that are "unmapped" (have no field associated).
* @param theCmd ClassMetaData for the class to be managed
* @param clr The ClassLoaderResolver
*/
private void manageUnmappedColumns(AbstractClassMetaData theCmd, ClassLoaderResolver clr) {
List cols = theCmd.getUnmappedColumns();
if (cols != null && cols.size() > 0) {
Iterator colsIter = cols.iterator();
while (colsIter.hasNext()) {
ColumnMetaData colmd = (ColumnMetaData) colsIter.next();
// Create a column with the specified name and jdbc-type
if (colmd.getJdbcType() == JdbcType.VARCHAR && colmd.getLength() == null) {
colmd.setLength(storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_RDBMS_STRING_DEFAULT_LENGTH));
}
IdentifierFactory idFactory = getStoreManager().getIdentifierFactory();
DatastoreIdentifier colIdentifier = idFactory.newIdentifier(IdentifierType.COLUMN, colmd.getName());
Column col = addColumn(null, colIdentifier, null, colmd);
SQLTypeInfo sqlTypeInfo = storeMgr.getSQLTypeInfoForJDBCType(dba.getJDBCTypeForName(colmd.getJdbcTypeName()));
col.setTypeInfo(sqlTypeInfo);
if (unmappedColumns == null) {
unmappedColumns = new HashSet();
}
if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) {
NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("057011", col.toString(), colmd.getJdbcType()));
}
unmappedColumns.add(col);
}
}
}
use of org.datanucleus.metadata.ColumnMetaData in project datanucleus-rdbms by datanucleus.
the class ClassTable method initializePK.
/**
* Method to initialise the table primary key field(s).
* @param clr The ClassLoaderResolver
*/
protected void initializePK(ClassLoaderResolver clr) {
assertIsPKUninitialized();
AbstractMemberMetaData[] membersToAdd = new AbstractMemberMetaData[cmd.getNoOfPrimaryKeyMembers()];
// Initialise Primary Key mappings for application id with PK fields in this class
int pkFieldNum = 0;
int fieldCount = cmd.getNoOfManagedMembers();
boolean hasPrimaryKeyInThisClass = false;
if (cmd.getNoOfPrimaryKeyMembers() > 0) {
pkMappings = new JavaTypeMapping[cmd.getNoOfPrimaryKeyMembers()];
if (cmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.COMPLETE_TABLE) {
// COMPLETE-TABLE so use root class metadata and add PK members
// TODO Does this allow for overridden PK field info ?
AbstractClassMetaData baseCmd = cmd.getBaseAbstractClassMetaData();
fieldCount = baseCmd.getNoOfManagedMembers();
for (int relFieldNum = 0; relFieldNum < fieldCount; ++relFieldNum) {
AbstractMemberMetaData mmd = baseCmd.getMetaDataForManagedMemberAtRelativePosition(relFieldNum);
if (mmd.isPrimaryKey()) {
AbstractMemberMetaData overriddenMmd = cmd.getOverriddenMember(mmd.getName());
if (overriddenMmd != null) {
// PK field is overridden so use the overriding definition
mmd = overriddenMmd;
}
if (mmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = mmd;
hasPrimaryKeyInThisClass = true;
} else if (mmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", mmd.getName())).setFatal();
}
// Check if auto-increment and that it is supported by this RDBMS
if ((mmd.getValueStrategy() == ValueGenerationStrategy.IDENTITY) && !dba.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS)) {
throw new NucleusException(Localiser.msg("057020", cmd.getFullClassName(), mmd.getName())).setFatal();
}
}
}
} else {
for (int relFieldNum = 0; relFieldNum < fieldCount; ++relFieldNum) {
AbstractMemberMetaData fmd = cmd.getMetaDataForManagedMemberAtRelativePosition(relFieldNum);
if (fmd.isPrimaryKey()) {
if (fmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = fmd;
hasPrimaryKeyInThisClass = true;
} else if (fmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", fmd.getName())).setFatal();
}
// Check if auto-increment and that it is supported by this RDBMS
if ((fmd.getValueStrategy() == ValueGenerationStrategy.IDENTITY) && !dba.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS)) {
throw new NucleusException(Localiser.msg("057020", cmd.getFullClassName(), fmd.getName())).setFatal();
}
}
}
}
}
// No Primary Key defined, so search for superclass or handle datastore id
if (!hasPrimaryKeyInThisClass) {
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// application-identity
// TODO rewrite this to just use metadata to get the PKs of the superclass(es). Any reason why not?
DatastoreClass superTable = storeMgr.getDatastoreClass(cmd.getPersistableSuperclass(), clr);
if (isPKInitialized()) {
// The above call could have triggered a population of the PK here
return;
}
if (superTable == null && cmd.getPersistableSuperclass() != null) {
// The superclass doesn't have its own table, so keep going up til we find the next table
AbstractClassMetaData supercmd = cmd.getSuperAbstractClassMetaData();
while (true) {
if (supercmd.getPersistableSuperclass() == null) {
break;
}
superTable = storeMgr.getDatastoreClass(supercmd.getPersistableSuperclass(), clr);
if (isPKInitialized()) {
// The above call could have triggered a population of the PK here
return;
}
if (superTable != null) {
break;
}
supercmd = supercmd.getSuperAbstractClassMetaData();
if (supercmd == null) {
break;
}
}
}
if (superTable != null) {
// Superclass has a table so copy its PK mappings
ColumnMetaDataContainer colContainer = null;
if (cmd.getInheritanceMetaData() != null) {
// Try via <inheritance><join>...</join></inheritance>
colContainer = cmd.getInheritanceMetaData().getJoinMetaData();
}
if (colContainer == null) {
// Try via <primary-key>...</primary-key>
colContainer = cmd.getPrimaryKeyMetaData();
}
addApplicationIdUsingClassTableId(colContainer, superTable, clr, cmd);
} else {
// No supertable to copy, so find superclass with PK fields and create new mappings and columns
AbstractClassMetaData pkCmd = getClassWithPrimaryKeyForClass(cmd.getSuperAbstractClassMetaData(), clr);
if (pkCmd != null) {
// TODO Just use cmd.getPKMemberPositions to avoid iteration to find PKs
pkMappings = new JavaTypeMapping[pkCmd.getNoOfPrimaryKeyMembers()];
pkFieldNum = 0;
fieldCount = pkCmd.getNoOfInheritedManagedMembers() + pkCmd.getNoOfManagedMembers();
for (int absFieldNum = 0; absFieldNum < fieldCount; ++absFieldNum) {
AbstractMemberMetaData fmd = pkCmd.getMetaDataForManagedMemberAtAbsolutePosition(absFieldNum);
if (fmd.isPrimaryKey()) {
AbstractMemberMetaData overriddenFmd = cmd.getOverriddenMember(fmd.getName());
if (overriddenFmd != null) {
// PK field is overridden so use the overriding definition
fmd = overriddenFmd;
} else {
AbstractClassMetaData thisCmd = cmd;
while (thisCmd.getSuperAbstractClassMetaData() != null && thisCmd.getSuperAbstractClassMetaData() != pkCmd) {
thisCmd = thisCmd.getSuperAbstractClassMetaData();
overriddenFmd = thisCmd.getOverriddenMember(fmd.getName());
if (overriddenFmd != null) {
// PK field is overridden so use the overriding definition
fmd = overriddenFmd;
break;
}
}
}
if (fmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = fmd;
} else if (fmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", fmd.getName())).setFatal();
}
}
}
}
}
} else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// datastore-identity
ColumnMetaData colmd = null;
if (cmd.getIdentityMetaData() != null && cmd.getIdentityMetaData().getColumnMetaData() != null) {
// Try via <datastore-identity>...</datastore-identity>
colmd = cmd.getIdentityMetaData().getColumnMetaData();
}
if (colmd == null) {
// Try via <primary-key>...</primary-key>
if (cmd.getPrimaryKeyMetaData() != null && cmd.getPrimaryKeyMetaData().getColumnMetaData() != null && cmd.getPrimaryKeyMetaData().getColumnMetaData().length > 0) {
colmd = cmd.getPrimaryKeyMetaData().getColumnMetaData()[0];
}
}
addDatastoreId(colmd, null, cmd);
} else if (cmd.getIdentityType() == IdentityType.NONDURABLE) {
// Do nothing since no identity!
}
}
// add field mappings in the end, so we compute all columns after the post initialize
for (int i = 0; i < membersToAdd.length; i++) {
if (membersToAdd[i] != null) {
try {
DatastoreClass datastoreClass = getStoreManager().getDatastoreClass(membersToAdd[i].getType().getName(), clr);
if (datastoreClass.getIdMapping() == null) {
throw new NucleusException("Unsupported relationship with field " + membersToAdd[i].getFullFieldName()).setFatal();
}
} catch (NoTableManagedException ex) {
// do nothing
}
JavaTypeMapping fieldMapping = storeMgr.getMappingManager().getMapping(this, membersToAdd[i], clr, FieldRole.ROLE_FIELD);
addMemberMapping(fieldMapping);
pkMappings[i] = fieldMapping;
}
}
initializeIDMapping();
state = TABLE_STATE_PK_INITIALIZED;
}
use of org.datanucleus.metadata.ColumnMetaData in project datanucleus-rdbms by datanucleus.
the class ClassTable method addOrderColumn.
/**
* Adds an ordering column to the element table (this) in FK list relationships.
* Used to store the position of the element in the List.
* If the <order> provides a mapped-by, this will return the existing column mapping.
* @param mmd The MetaData of the field/property with the list for the column to map to
* @return The Mapping for the order column
*/
private JavaTypeMapping addOrderColumn(AbstractMemberMetaData mmd, ClassLoaderResolver clr) {
Class indexType = Integer.class;
JavaTypeMapping orderIndexMapping = new OrderIndexMapping();
orderIndexMapping.initialize(storeMgr, indexType.getName());
orderIndexMapping.setMemberMetaData(mmd);
orderIndexMapping.setTable(this);
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
DatastoreIdentifier indexColumnName = null;
ColumnMetaData colmd = null;
// Allow for any user definition in OrderMetaData
OrderMetaData omd = mmd.getOrderMetaData();
if (omd != null) {
colmd = (omd.getColumnMetaData() != null && omd.getColumnMetaData().length > 0 ? omd.getColumnMetaData()[0] : null);
if (omd.getMappedBy() != null) {
// User has defined ordering using the column(s) of an existing field.
// Not adding anything so just set table back to "initialised"
state = TABLE_STATE_INITIALIZED;
JavaTypeMapping orderMapping = getMemberMapping(omd.getMappedBy());
if (!(orderMapping instanceof IntegerMapping) && !(orderMapping instanceof LongMapping)) {
throw new NucleusUserException(Localiser.msg("057022", mmd.getFullFieldName(), omd.getMappedBy()));
}
return orderMapping;
}
String colName = null;
if (omd.getColumnMetaData() != null && omd.getColumnMetaData().length > 0 && omd.getColumnMetaData()[0].getName() != null) {
// User-defined name so create an identifier using it
colName = omd.getColumnMetaData()[0].getName();
indexColumnName = idFactory.newColumnIdentifier(colName);
}
}
if (indexColumnName == null) {
// No name defined so generate one
indexColumnName = idFactory.newForeignKeyFieldIdentifier(mmd, null, null, storeMgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(indexType), FieldRole.ROLE_INDEX);
}
Column column = addColumn(indexType.getName(), indexColumnName, orderIndexMapping, colmd);
if (colmd == null || (colmd.getAllowsNull() == null) || (colmd.getAllowsNull() != null && colmd.isAllowsNull())) {
// User either wants it nullable, or havent specified anything, so make it nullable
column.setNullable(true);
}
storeMgr.getMappingManager().createDatastoreMapping(orderIndexMapping, column, indexType.getName());
return orderIndexMapping;
}
use of org.datanucleus.metadata.ColumnMetaData in project datanucleus-rdbms by datanucleus.
the class ClassTable method getForeignKeyForForeignKeyMetaData.
/**
* Convenience method to create a FK for the specified ForeignKeyMetaData.
* Used for foreign-keys specified at <class> level.
* @param fkmd ForeignKey MetaData
* @return The ForeignKey
*/
private ForeignKey getForeignKeyForForeignKeyMetaData(ForeignKeyMetaData fkmd) {
if (fkmd == null) {
return null;
}
// Create the ForeignKey base details
ForeignKey fk = new ForeignKey(dba, fkmd.isDeferred());
fk.setForMetaData(fkmd);
if (fkmd.getFkDefinitionApplies()) {
// User-defined FK definition should be used
return fk;
}
// Find the target of the foreign-key
AbstractClassMetaData acmd = cmd;
if (fkmd.getTable() == null) {
// Can't create a FK if we don't know where it goes to
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058105", acmd.getFullClassName()));
return null;
}
DatastoreIdentifier tableId = storeMgr.getIdentifierFactory().newTableIdentifier(fkmd.getTable());
ClassTable refTable = (ClassTable) storeMgr.getDatastoreClass(tableId);
if (refTable == null) {
// TODO Go to the datastore and query for this table to get the columns of the PK
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058106", acmd.getFullClassName(), fkmd.getTable()));
return null;
}
PrimaryKey pk = refTable.getPrimaryKey();
List targetCols = pk.getColumns();
// Generate the columns for the source of the foreign-key
List<Column> sourceCols = new ArrayList<>();
ColumnMetaData[] colmds = fkmd.getColumnMetaData();
String[] memberNames = fkmd.getMemberNames();
if (colmds != null && colmds.length > 0) {
// FK specified via <column>
for (int i = 0; i < colmds.length; i++) {
// Find the column and add to the source columns for the FK
DatastoreIdentifier colId = storeMgr.getIdentifierFactory().newColumnIdentifier(colmds[i].getName());
Column sourceCol = columnsByIdentifier.get(colId);
if (sourceCol == null) {
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058107", acmd.getFullClassName(), fkmd.getTable(), colmds[i].getName(), toString()));
return null;
}
sourceCols.add(sourceCol);
}
} else if (memberNames != null && memberNames.length > 0) {
// FK specified via <field>
for (int i = 0; i < memberNames.length; i++) {
// Find the metadata for the actual field with the same name as this "foreign-key" field
// and add all columns to the source columns for the FK
AbstractMemberMetaData realMmd = getMetaDataForMember(memberNames[i]);
if (realMmd == null) {
throw new NucleusUserException("Table " + this + " has foreign-key specified on member " + memberNames[i] + " but that member does not exist in the class that this table represents");
}
JavaTypeMapping fieldMapping = memberMappingsMap.get(realMmd);
int countCols = fieldMapping.getNumberOfDatastoreMappings();
for (int j = 0; j < countCols; j++) {
// Add each column of this field to the FK definition
sourceCols.add(fieldMapping.getDatastoreMapping(j).getColumn());
}
}
}
if (sourceCols.size() != targetCols.size()) {
// Different number of cols in this table and target table
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058108", acmd.getFullClassName(), fkmd.getTable(), "" + sourceCols.size(), "" + targetCols.size()));
}
// Add all column mappings to the ForeignKey
if (sourceCols.size() > 0) {
for (int i = 0; i < sourceCols.size(); i++) {
Column source = sourceCols.get(i);
String targetColName = (colmds != null && colmds[i] != null) ? colmds[i].getTarget() : null;
// Default to matching via the natural order
Column target = (Column) targetCols.get(i);
if (targetColName != null) {
// User has specified the target column for this col so try it in our target list
for (int j = 0; j < targetCols.size(); j++) {
Column targetCol = (Column) targetCols.get(j);
if (targetCol.getIdentifier().getName().equalsIgnoreCase(targetColName)) {
// Found the required column
target = targetCol;
break;
}
}
}
fk.addColumn(source, target);
}
}
return fk;
}
Aggregations