use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.
the class SQLStatementHelper method getSQLTableForMappingOfTable.
/**
* Method to return the SQLTable where the specified mapping (in the same table group as the provided
* SQLTable) is defined. If the statement doesn't currently join to the required table then a join will
* be added. If the required table is a superclass table then the join will be INNER. If the required
* table is a secondary table then the join will be defined by the meta-data for the secondary table.
* If this table group is NOT the candidate table group then LEFT OUTER JOIN will be used.
* @param stmt The statement
* @param sqlTbl SQLTable to start from for the supplied mapping (may be in super-table, or secondary-table of this)
* @param mapping The mapping
* @return The SQLTable for this mapping (may have been added to the statement during this method)
*/
public static SQLTable getSQLTableForMappingOfTable(SQLStatement stmt, SQLTable sqlTbl, JavaTypeMapping mapping) {
Table table = sqlTbl.getTable();
if (table instanceof SecondaryDatastoreClass || table instanceof JoinTable) {
// Secondary/join tables have no inheritance so ought to be correct
if (mapping.getTable() != null) {
// Check there is no better table already present in the TableGroup for this mapping
// This can happen when we do a select of a join table and the element table is in the
// same table group, so hence already is present
SQLTable mappingSqlTbl = stmt.getTable(mapping.getTable(), sqlTbl.getGroupName());
if (mappingSqlTbl != null) {
return mappingSqlTbl;
}
}
return sqlTbl;
}
DatastoreClass sourceTbl = (DatastoreClass) sqlTbl.getTable();
DatastoreClass mappingTbl = null;
if (mapping.getTable() != null) {
mappingTbl = (DatastoreClass) mapping.getTable();
} else {
mappingTbl = sourceTbl.getBaseDatastoreClassWithMember(mapping.getMemberMetaData());
}
if (mappingTbl == sourceTbl) {
return sqlTbl;
}
// Try to find this datastore table in the same table group
SQLTable mappingSqlTbl = stmt.getTable(mappingTbl, sqlTbl.getGroupName());
if (mappingSqlTbl == null) {
boolean forceLeftOuter = false;
SQLTableGroup tableGrp = stmt.getTableGroup(sqlTbl.getGroupName());
if (tableGrp.getJoinType() == JoinType.LEFT_OUTER_JOIN) {
// This group isn't the candidate group, and we joined to the candidate group using
// a left outer join originally, so use the same type for this table
forceLeftOuter = true;
}
if (mappingTbl instanceof SecondaryDatastoreClass) {
// Secondary table, so add inner/outer based on metadata
boolean innerJoin = true;
JoinMetaData joinmd = ((SecondaryDatastoreClass) mappingTbl).getJoinMetaData();
if (joinmd != null && joinmd.isOuter() && !forceLeftOuter) {
innerJoin = false;
}
if (innerJoin && !forceLeftOuter) {
// Add join from {sourceTbl}.ID to {secondaryTbl}.ID
mappingSqlTbl = stmt.join(JoinType.INNER_JOIN, sqlTbl, sqlTbl.getTable().getIdMapping(), mappingTbl, null, mappingTbl.getIdMapping(), null, sqlTbl.getGroupName());
} else {
// Add join from {sourceTbl}.ID to {secondaryTbl}.ID
mappingSqlTbl = stmt.join(JoinType.LEFT_OUTER_JOIN, sqlTbl, sqlTbl.getTable().getIdMapping(), mappingTbl, null, mappingTbl.getIdMapping(), null, sqlTbl.getGroupName());
}
} else {
if (forceLeftOuter) {
// Add join from {sourceTbl}.ID to {superclassTbl}.ID
mappingSqlTbl = stmt.join(JoinType.LEFT_OUTER_JOIN, sqlTbl, sqlTbl.getTable().getIdMapping(), mappingTbl, null, mappingTbl.getIdMapping(), null, sqlTbl.getGroupName());
} else {
// Add join from {sourceTbl}.ID to {superclassTbl}.ID
mappingSqlTbl = stmt.join(JoinType.INNER_JOIN, sqlTbl, sqlTbl.getTable().getIdMapping(), mappingTbl, null, mappingTbl.getIdMapping(), null, sqlTbl.getGroupName());
}
}
}
return mappingSqlTbl;
}
use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.
the class RDBMSSchemaHandler method getRDBMSTableInfoForTable.
/**
* Convenience method to get the column info for the catalog+schema+tableName in the datastore.
* @param conn Connection to use
* @param catalogName Catalog
* @param schemaName Schema
* @param tableName Name of the table
* @return The table info containing the columns
*/
protected RDBMSTableInfo getRDBMSTableInfoForTable(Connection conn, String catalogName, String schemaName, String tableName) {
RDBMSSchemaInfo info = (RDBMSSchemaInfo) getSchemaData(conn, TYPE_TABLES, null);
if (info == null) {
// No schema info defined yet
info = new RDBMSSchemaInfo(rdbmsStoreMgr.getCatalogName(), rdbmsStoreMgr.getSchemaName());
schemaDataByName.put(TYPE_TABLES, info);
}
// Check existence
String tableKey = getTableKeyInRDBMSSchemaInfo(catalogName, schemaName, tableName);
RDBMSTableInfo tableInfo = (RDBMSTableInfo) info.getChild(tableKey);
if (tableInfo != null) {
long time = ((Long) tableInfo.getProperty("time")).longValue();
long now = System.currentTimeMillis();
if (now < time + COLUMN_INFO_EXPIRATION_MS) {
// Table info is still valid so just return it
return tableInfo;
}
}
// Refresh all existing tables plus this requested one
boolean insensitiveIdentifiers = identifiersCaseInsensitive();
Collection tableNames = new HashSet();
Collection tables = rdbmsStoreMgr.getManagedTables(catalogName, schemaName);
if (tables.size() > 0) {
Iterator iter = tables.iterator();
while (iter.hasNext()) {
Table tbl = (Table) iter.next();
tableNames.add(insensitiveIdentifiers ? tbl.getIdentifier().getName().toLowerCase() : tbl.getIdentifier().getName());
}
}
tableNames.add(insensitiveIdentifiers ? tableName.toLowerCase() : tableName);
refreshTableData(conn, catalogName, schemaName, tableNames);
tableInfo = (RDBMSTableInfo) info.getChild(tableKey);
if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) {
if (tableInfo == null || tableInfo.getNumberOfChildren() == 0) {
NucleusLogger.DATASTORE_SCHEMA.info(Localiser.msg("050030", tableName));
} else {
NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("050032", tableName, "" + tableInfo.getNumberOfChildren()));
}
}
return tableInfo;
}
use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.
the class MappingManagerImpl method createColumn.
/**
* Method to create a datastore field for a Java type mapping.
* This is used for serialised PC elements/keys/values in a join table.
* TODO Merge this with the method above.
* @param mapping Java type mapping for the field
* @param javaType The type of field being stored in this column
* @param colmd MetaData for the column
* @return The column
*/
public Column createColumn(JavaTypeMapping mapping, String javaType, ColumnMetaData colmd) {
AbstractMemberMetaData mmd = mapping.getMemberMetaData();
Table tbl = mapping.getTable();
if (colmd == null) {
// If column specified add one (use any column name specified on field element)
colmd = new ColumnMetaData();
if (mmd.getColumnMetaData() != null && mmd.getColumnMetaData().length == 1) {
colmd.setName(mmd.getColumnMetaData()[0].getName());
}
mmd.addColumn(colmd);
}
Column col;
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
if (colmd.getName() == null) {
// No name specified, so generate the identifier from the field name
DatastoreIdentifier identifier = idFactory.newIdentifier(IdentifierType.COLUMN, mmd.getName());
int i = 0;
while (tbl.hasColumn(identifier)) {
identifier = idFactory.newIdentifier(IdentifierType.COLUMN, mmd.getName() + "_" + i);
i++;
}
colmd.setName(identifier.getName());
col = tbl.addColumn(javaType, identifier, mapping, colmd);
} else {
// User has specified a name, so try to keep this unmodified
col = tbl.addColumn(javaType, idFactory.newColumnIdentifier(colmd.getName(), storeMgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(mmd.getType()), null, true), mapping, colmd);
}
setColumnNullability(mmd, colmd, col);
if (mmd.getNullValue() == NullValue.DEFAULT) {
// Users default should be applied if a null is to be inserted
col.setDefaultable(colmd.getDefaultValue());
}
return col;
}
use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.
the class MappingManagerImpl method createColumn.
/**
* Method to create a column for a Java type mapping.
* This is NOT used for persistable mappings - see method below.
* @param mapping Java type mapping for the field
* @param javaType The type of field being stored in this column
* @param datastoreFieldIndex Index of the datastore field to use
* @return The datastore field
*/
public Column createColumn(JavaTypeMapping mapping, String javaType, int datastoreFieldIndex) {
AbstractMemberMetaData mmd = mapping.getMemberMetaData();
FieldRole roleForField = mapping.getRoleForMember();
Table tbl = mapping.getTable();
// Take the column MetaData from the component that this mappings role relates to
ColumnMetaData colmd = null;
ColumnMetaDataContainer columnContainer = mmd;
if (roleForField == FieldRole.ROLE_COLLECTION_ELEMENT || roleForField == FieldRole.ROLE_ARRAY_ELEMENT) {
columnContainer = mmd.getElementMetaData();
} else if (roleForField == FieldRole.ROLE_MAP_KEY) {
columnContainer = mmd.getKeyMetaData();
} else if (roleForField == FieldRole.ROLE_MAP_VALUE) {
columnContainer = mmd.getValueMetaData();
}
Column col;
ColumnMetaData[] colmds;
if (columnContainer != null && columnContainer.getColumnMetaData().length > datastoreFieldIndex) {
colmd = columnContainer.getColumnMetaData()[datastoreFieldIndex];
colmds = columnContainer.getColumnMetaData();
} else {
// If column specified add one (use any column name specified on field element)
colmd = new ColumnMetaData();
if (mmd.getColumnMetaData() != null && mmd.getColumnMetaData().length > datastoreFieldIndex) {
colmd.setName(mmd.getColumnMetaData()[datastoreFieldIndex].getName());
}
if (columnContainer != null) {
columnContainer.addColumn(colmd);
colmds = columnContainer.getColumnMetaData();
} else {
colmds = new ColumnMetaData[1];
colmds[0] = colmd;
}
}
// Generate the column identifier
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
DatastoreIdentifier identifier = null;
if (colmd.getName() == null) {
// No name specified, so generate the identifier from the field name
if (roleForField == FieldRole.ROLE_COLLECTION_ELEMENT) {
// Join table collection element
identifier = idFactory.newJoinTableFieldIdentifier(mmd, null, null, true, FieldRole.ROLE_COLLECTION_ELEMENT);
} else if (roleForField == FieldRole.ROLE_ARRAY_ELEMENT) {
// Join table array element
identifier = idFactory.newJoinTableFieldIdentifier(mmd, null, null, true, FieldRole.ROLE_ARRAY_ELEMENT);
} else if (roleForField == FieldRole.ROLE_MAP_KEY) {
// Join table map key
identifier = idFactory.newJoinTableFieldIdentifier(mmd, null, null, true, FieldRole.ROLE_MAP_KEY);
} else if (roleForField == FieldRole.ROLE_MAP_VALUE) {
// Join table map value
identifier = idFactory.newJoinTableFieldIdentifier(mmd, null, null, true, FieldRole.ROLE_MAP_VALUE);
} else {
identifier = idFactory.newIdentifier(IdentifierType.COLUMN, mmd.getName());
int i = 0;
while (tbl.hasColumn(identifier)) {
identifier = idFactory.newIdentifier(IdentifierType.COLUMN, mmd.getName() + "_" + i);
i++;
}
}
colmd.setName(identifier.getName());
} else {
// User has specified a name, so try to keep this unmodified
identifier = idFactory.newColumnIdentifier(colmds[datastoreFieldIndex].getName(), storeMgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(mmd.getType()), null, true);
}
// Create the column
col = tbl.addColumn(javaType, identifier, mapping, colmd);
if (mmd.isPrimaryKey()) {
col.setPrimaryKey();
}
if (!(mmd.getParent() instanceof AbstractClassMetaData)) {
// Embedded so can't be datastore-attributed
} else {
/*if (!mmd.getClassName(true).equals(mmd.getAbstractClassMetaData().getFullClassName()))
{
if (storeMgr.isStrategyDatastoreAttributed(mmd.getAbstractClassMetaData(), mmd.getAbsoluteFieldNumber()) && tbl instanceof DatastoreClass)
{
if ((mmd.isPrimaryKey() && ((DatastoreClass)tbl).isBaseDatastoreClass()) || !mmd.isPrimaryKey())
{
NucleusLogger.GENERAL.info(">> Column addition " + mmd.getFullFieldName() + " IGNORING use of IDENTITY since override of base metadata! See RDBMSMappingManager");
}
}
// Overriding member, so ignore TODO This can be incorrect in many cases
}
else
{*/
if (storeMgr.isValueGenerationStrategyDatastoreAttributed(mmd.getAbstractClassMetaData(), mmd.getAbsoluteFieldNumber()) && tbl instanceof DatastoreClass) {
if ((mmd.isPrimaryKey() && ((DatastoreClass) tbl).isBaseDatastoreClass()) || !mmd.isPrimaryKey()) {
// Increment any PK field if we are in base class, and increment any other field
col.setIdentity(true);
}
}
/*}*/
}
if (mmd.getValueForExtension("select-function") != null) {
col.setWrapperFunction(mmd.getValueForExtension("select-function"), Column.WRAPPER_FUNCTION_SELECT);
}
if (mmd.getValueForExtension("insert-function") != null) {
col.setWrapperFunction(mmd.getValueForExtension("insert-function"), Column.WRAPPER_FUNCTION_INSERT);
}
if (mmd.getValueForExtension("update-function") != null) {
col.setWrapperFunction(mmd.getValueForExtension("update-function"), Column.WRAPPER_FUNCTION_UPDATE);
}
setColumnNullability(mmd, colmd, col);
if (mmd.getNullValue() == NullValue.DEFAULT) {
// Users default should be applied if a null is to be inserted
col.setDefaultable(colmd.getDefaultValue());
}
return col;
}
use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.
the class MapKeyMethod method getAsSubquery.
/**
* Implementation of KEY(mapExpr) using a subquery on the table representing the map.
* @param stmt SQLStatement
* @param mapExpr The map expression
* @return The value expression
*/
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr) {
AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
MapMetaData mapmd = mmd.getMap();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
JavaTypeMapping ownerMapping = null;
JavaTypeMapping keyMapping = null;
Table mapTbl = null;
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
// JoinTable
mapTbl = storeMgr.getTable(mmd);
ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
keyMapping = ((MapTable) mapTbl).getKeyMapping();
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// ForeignKey from value table to key
AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
String keyFieldName = mmd.getKeyMetaData().getMappedBy();
AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(keyFieldName);
keyMapping = mapTbl.getMemberMapping(valKeyMmd);
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// ForeignKey from key table to value
AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
keyMapping = mapTbl.getIdMapping();
} else {
throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
subStmt.setClassLoaderResolver(clr);
SQLExpression keyExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyMapping);
subStmt.select(keyExpr, null);
// Link to primary statement
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
subExpr.setJavaTypeMapping(keyMapping);
return subExpr;
}
Aggregations