/** * Method to return the SQLText for an UPDATE TABLE statement. Returns the SQLText for <code> * UPDATE T1 SET x1 = val1, x2 = val2 FROM MYTBL T1</code>. Override if the datastore doesn't * support that standard syntax. * * @param tbl The primary table * @param setSQL The SQLText for the SET component * @return SQLText for the update statement */ public SQLText getUpdateTableStatement(SQLTable tbl, SQLText setSQL) { SQLText sql = new SQLText("UPDATE ").append(tbl.getAlias().toString()); // "UPDATE T1" sql.append(" ").append(setSQL); // " SET x1 = val1, x2 = val2" sql.append(" FROM ").append(tbl.toString()); // " FROM MYTBL T1" return sql; }
/** * Method to return an expression for Map.containsValue using INNER JOIN to the element. This is * only for use when there are no "!containsValue" and no "OR" operations. Creates SQL by adding * INNER JOIN to the join table (where it exists), and also to the value table adding an AND * condition on the value (with value of the valueExpr). Returns a BooleanExpression "TRUE" (since * the INNER JOIN will guarantee if the value is contained of not). * * @param mapExpr Map expression * @param valExpr Expression for the value * @return Contains expression */ protected SQLExpression containsAsInnerJoin(MapExpression mapExpr, SQLExpression valExpr) { boolean valIsUnbound = (valExpr instanceof UnboundExpression); String varName = null; String valAlias = null; if (valIsUnbound) { varName = ((UnboundExpression) valExpr).getVariableName(); NucleusLogger.QUERY.debug( "map.containsValue(" + valExpr + ") binding unbound variable " + varName + " using INNER JOIN"); // TODO What if the variable is declared as a subtype, handle this see // CollectionContainsMethod } else if (!stmt.getQueryGenerator().hasExplicitJoins()) { JoinType joinType = stmt.getJoinTypeForTable(valExpr.getSQLTable()); if (joinType == JoinType.CROSS_JOIN) { // Value is currently joined via CROSS JOIN, so remove it (and use INNER JOIN below) valAlias = stmt.removeCrossJoin(valExpr.getSQLTable()); valIsUnbound = true; NucleusLogger.QUERY.debug( "map.containsValue(" + valExpr + ") was previously bound as CROSS JOIN but changing to INNER JOIN"); } // TODO If owner is joined via CROSS JOIN and value is already present then remove CROSS JOIN // and join via INNER JOIN } RDBMSStoreManager storeMgr = stmt.getRDBMSManager(); MetaDataManager mmgr = storeMgr.getMetaDataManager(); AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData(); AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr, mmgr); if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) { // Map formed in join table - add join to join table, then to value table (if present) MapTable mapTbl = (MapTable) storeMgr.getTable(mmd); SQLTable joinSqlTbl = stmt.innerJoin( mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), mapTbl, null, mapTbl.getOwnerMapping(), null, null); if (valCmd != null) { if (valIsUnbound) { DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr); SQLTable valSqlTbl = stmt.innerJoin( joinSqlTbl, mapTbl.getValueMapping(), valTbl, valAlias, valTbl.getIdMapping(), null, null); // Bind the variable in the QueryGenerator valExpr = exprFactory.newExpression(stmt, valSqlTbl, valSqlTbl.getTable().getIdMapping()); stmt.getQueryGenerator() .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping()); } else { // Add restrict to value SQLExpression valIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping()); stmt.whereAnd(valIdExpr.eq(valExpr), true); } } else { if (valIsUnbound) { // Bind the variable in the QueryGenerator valExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping()); stmt.getQueryGenerator() .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping()); } else { // Add restrict to value SQLExpression valIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping()); stmt.whereAnd(valIdExpr.eq(valExpr), true); } } } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) { // Map formed in value table - add join to value table DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr); JavaTypeMapping ownerMapping = null; if (mmd.getMappedBy() != null) { ownerMapping = valTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy())); } else { ownerMapping = valTbl.getExternalMapping(mmd, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK); } SQLTable valSqlTbl = stmt.innerJoin( mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), valTbl, valAlias, ownerMapping, null, null); if (valIsUnbound) { // Bind the variable in the QueryGenerator valExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping()); stmt.getQueryGenerator() .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping()); } else { // Add restrict to value SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping()); stmt.whereAnd(valIdExpr.eq(valExpr), true); } } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) { // Map formed in key table - add join to key table then to value table AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr, mmgr); DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr); AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy()); JavaTypeMapping ownerMapping = null; if (mmd.getMappedBy() != null) { ownerMapping = keyTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy())); } else { ownerMapping = keyTbl.getExternalMapping(mmd, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK); } SQLTable keySqlTbl = stmt.innerJoin( mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), keyTbl, null, ownerMapping, null, null); if (valCmd != null) { DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr); SQLTable valSqlTbl = stmt.innerJoin( keySqlTbl, keyTbl.getMemberMapping(keyValMmd), valTbl, valAlias, valTbl.getIdMapping(), null, null); if (valIsUnbound) { // Bind the variable in the QueryGenerator valExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping()); stmt.getQueryGenerator() .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping()); } else { // Add restrict to value SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping()); stmt.whereAnd(valIdExpr.eq(valExpr), true); } } else { if (valIsUnbound) { // Bind the variable in the QueryGenerator valExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getMemberMapping(keyValMmd)); stmt.getQueryGenerator() .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping()); } else { // Add restrict to value SQLExpression valIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getMemberMapping(keyValMmd)); stmt.whereAnd(valIdExpr.eq(valExpr), true); } } } JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true); return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true)); }
/** * Method to return the basic SQL for a DELETE TABLE statement. Returns the String as <code> * DELETE MYTABLE FROM MYTABLE t1</code>. * * @param tbl The SQLTable to delete * @return The delete table string */ public String getDeleteTableStatement(SQLTable tbl) { return "DELETE " + tbl.getAlias() + " FROM " + tbl.toString(); }