/** * Constructor, taking the meta data for the field, and the table it is mapped to. * * @param mmd MetaData for the field. * @param table Table definition */ public RDBMSStoreData(AbstractMemberMetaData mmd, Table table) { super(mmd.getFullFieldName(), mmd, SCO_TYPE, null); if (table == null) { throw new NullPointerException("table should not be null"); } this.table = table; this.tableName = table.toString(); this.tableOwner = true; this.tableIdentifier = table.getIdentifier(); String interfaceName = (table.getStoreManager().getMetaDataManager().isPersistentInterface(mmd.getType().getName()) ? mmd.getType().getName() : null); if (interfaceName != null) { this.interfaceName = interfaceName; } }
/** * Constructor for FCO data. * * @param cmd MetaData for the class. * @param table Table where the class is stored. * @param tableOwner Whether the class is the owner of the table. */ public RDBMSStoreData(ClassMetaData cmd, Table table, boolean tableOwner) { super(cmd.getFullClassName(), cmd, FCO_TYPE, null); this.tableOwner = tableOwner; if (table != null) { this.table = table; this.tableName = table.toString(); this.tableIdentifier = table.getIdentifier(); } String interfaces = null; ImplementsMetaData[] implMds = cmd.getImplementsMetaData(); if (implMds != null) { for (int i = 0; i < cmd.getImplementsMetaData().length; i++) { if (interfaces == null) { interfaces = ""; } else { interfaces += ","; } interfaces += cmd.getImplementsMetaData()[i].getName(); } this.interfaceName = interfaces; } }
/** * Generate statement for clearing the (join table) container. * * <PRE> * DELETE FROM CONTAINERTABLE WHERE OWNERCOL = ? [AND RELATION_DISCRIM=?] * </PRE> * * TODO Add a discriminator restriction on this statement so we only clear ones with a valid * discriminator value * * @return Statement for clearing the container. */ protected String getClearStmt() { if (clearStmt == null) { synchronized (this) { StringBuilder stmt = new StringBuilder("DELETE FROM ").append(containerTable.toString()).append(" WHERE "); BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, null, true); if (getRelationDiscriminatorMapping() != null) { BackingStoreHelper.appendWhereClauseForMapping( stmt, relationDiscriminatorMapping, null, false); } clearStmt = stmt.toString(); } } return clearStmt; }
/** * 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) { // If an ordering is present, restrict to items where the index is not null to // 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"); } } 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"; ElementInfo 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) { // If an ordering is present, restrict to items where the index is not null to // 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"); } } // 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( ((AbstractDatastoreMapping) 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 "); } ElementInfo 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) { // If an ordering is present, restrict to items where the index is not null to // 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"); } } // 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( ((AbstractDatastoreMapping) 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(); } }
/** * Generates the statement for adding items to a (join table) container. The EMBEDDEDFIELDX * columns are only added for embedded PC elements. * * <PRE> * INSERT INTO COLLTABLE (OWNERCOL,[ELEMENTCOL],[EMBEDDEDFIELD1, EMBEDDEDFIELD2,...],[ORDERCOL]) VALUES (?,?,?) * </PRE> * * @return The Statement for adding an item */ protected String getAddStmtForJoinTable() { if (addStmt == null) { synchronized (this) { StringBuilder stmt = new StringBuilder("INSERT INTO "); stmt.append(containerTable.toString()); stmt.append(" ("); for (int i = 0; i < getOwnerMapping().getNumberOfDatastoreMappings(); i++) { if (i > 0) { stmt.append(","); } stmt.append( getOwnerMapping().getDatastoreMapping(i).getColumn().getIdentifier().toString()); } for (int i = 0; i < elementMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append(elementMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString()); } if (orderMapping != null) { for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append(orderMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString()); } } if (relationDiscriminatorMapping != null) { for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append( relationDiscriminatorMapping .getDatastoreMapping(i) .getColumn() .getIdentifier() .toString()); } } stmt.append(") VALUES ("); for (int i = 0; i < getOwnerMapping().getNumberOfDatastoreMappings(); i++) { if (i > 0) { stmt.append(","); } stmt.append( ((AbstractDatastoreMapping) getOwnerMapping().getDatastoreMapping(i)) .getInsertionInputParameter()); } for (int i = 0; i < elementMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append( ((AbstractDatastoreMapping) elementMapping.getDatastoreMapping(0)) .getInsertionInputParameter()); } if (orderMapping != null) { for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append( ((AbstractDatastoreMapping) orderMapping.getDatastoreMapping(0)) .getInsertionInputParameter()); } } if (relationDiscriminatorMapping != null) { for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++) { stmt.append(",") .append( ((AbstractDatastoreMapping) relationDiscriminatorMapping.getDatastoreMapping(0)) .getInsertionInputParameter()); } } stmt.append(") "); addStmt = stmt.toString(); } } return addStmt; }
/** * Method to return the INSERT statement to use when inserting into a table that has no columns * specified. This is the case when we have a single column in the table and that column is * autoincrement/identity (and so is assigned automatically in the datastore). * * @param table The table * @return The statement for the INSERT */ public String getInsertStatementForNoColumns(Table table) { return "INSERT INTO " + table.toString() + " DEFAULT VALUES"; }
public String getDropTableStatement(Table table) { return "DROP TABLE " + table.toString(); }