Search in sources :

Example 16 with Table

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;
}
Also used : PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) Table(org.datanucleus.store.rdbms.table.Table) JoinTable(org.datanucleus.store.rdbms.table.JoinTable) JoinMetaData(org.datanucleus.metadata.JoinMetaData) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) JoinTable(org.datanucleus.store.rdbms.table.JoinTable)

Example 17 with Table

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;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) Iterator(java.util.Iterator) Collection(java.util.Collection) HashSet(java.util.HashSet)

Example 18 with Table

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;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) Column(org.datanucleus.store.rdbms.table.Column) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory)

Example 19 with Table

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;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) ColumnMetaDataContainer(org.datanucleus.metadata.ColumnMetaDataContainer) Column(org.datanucleus.store.rdbms.table.Column) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) FieldRole(org.datanucleus.metadata.FieldRole) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 20 with Table

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;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) MapMetaData(org.datanucleus.metadata.MapMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SubqueryExpression(org.datanucleus.store.rdbms.sql.expression.SubqueryExpression) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

Table (org.datanucleus.store.rdbms.table.Table)23 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)17 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)14 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)13 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)10 NucleusException (org.datanucleus.exceptions.NucleusException)9 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)9 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)9 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)9 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)8 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)8 MapTable (org.datanucleus.store.rdbms.table.MapTable)8 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)7 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)7 CollectionTable (org.datanucleus.store.rdbms.table.CollectionTable)6 ClassTable (org.datanucleus.store.rdbms.table.ClassTable)5 ArrayTable (org.datanucleus.store.rdbms.table.ArrayTable)4 PersistableJoinTable (org.datanucleus.store.rdbms.table.PersistableJoinTable)4 Collection (java.util.Collection)3 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)3