0001: /*
0002: * The contents of this file are subject to the terms of the Common Development
0003: * and Distribution License (the License). You may not use this file except in
0004: * compliance with the License.
0005: *
0006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
0007: * or http://www.netbeans.org/cddl.txt.
0008: *
0009: * When distributing Covered Code, include this CDDL Header Notice in each file
0010: * and include the License file at http://www.netbeans.org/cddl.txt.
0011: * If applicable, add the following below the CDDL Header, with the fields
0012: * enclosed by brackets [] replaced by your own identifying information:
0013: * "Portions Copyrighted [year] [name of copyright owner]"
0014: *
0015: * The Original Software is NetBeans. The Initial Developer of the Original
0016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0017: * Microsystems, Inc. All Rights Reserved.
0018: */
0019: package org.netbeans.modules.sql.framework.codegen.base;
0020:
0021: import java.util.ArrayList;
0022: import java.util.Iterator;
0023: import java.util.List;
0024: import java.util.ListIterator;
0025: import java.util.Map;
0026: import org.apache.velocity.VelocityContext;
0027: import org.netbeans.modules.sql.framework.codegen.AbstractDB;
0028: import org.netbeans.modules.sql.framework.codegen.AbstractGeneratorFactory;
0029: import org.netbeans.modules.sql.framework.codegen.ColumnIdentifier;
0030: import org.netbeans.modules.sql.framework.codegen.ResolvedMapping;
0031: import org.netbeans.modules.sql.framework.codegen.StatementContext;
0032: import org.netbeans.modules.sql.framework.codegen.Statements;
0033: import org.netbeans.modules.sql.framework.codegen.SubSelectIdentifier;
0034: import org.netbeans.modules.sql.framework.codegen.TemplateBuilder;
0035: import org.netbeans.modules.sql.framework.model.SQLCondition;
0036: import org.netbeans.modules.sql.framework.model.SQLConstants;
0037: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
0038: import org.netbeans.modules.sql.framework.model.SQLDBTable;
0039: import org.netbeans.modules.sql.framework.model.SQLGroupBy;
0040: import org.netbeans.modules.sql.framework.model.SQLJoinOperator;
0041: import org.netbeans.modules.sql.framework.model.SQLJoinView;
0042: import org.netbeans.modules.sql.framework.model.SQLModelObjectFactory;
0043: import org.netbeans.modules.sql.framework.model.SQLObject;
0044: import org.netbeans.modules.sql.framework.model.SQLPredicate;
0045: import org.netbeans.modules.sql.framework.model.SourceColumn;
0046: import org.netbeans.modules.sql.framework.model.SourceTable;
0047: import org.netbeans.modules.sql.framework.model.TargetColumn;
0048: import org.netbeans.modules.sql.framework.model.TargetTable;
0049: import org.netbeans.modules.sql.framework.model.utils.SQLObjectUtil;
0050: import com.sun.sql.framework.exception.BaseException;
0051: import com.sun.sql.framework.jdbc.SQLPart;
0052: import com.sun.sql.framework.utils.StringUtil;
0053: import org.netbeans.modules.sql.framework.model.PrimaryKey;
0054:
0055: /**
0056: * @author Ritesh Adval
0057: * @author Ahimanikya Satapathy
0058: * @version $Revision$
0059: */
0060: public class BaseStatements implements Statements {
0061:
0062: public static final String LOG_SUMMARY_TABLE_NAME = "SUMMARY";
0063: protected static final String SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX = "s_column";
0064: protected static final String TARGET_COLUMN_IDENTIFIER_ALIAS_PREFIX = "d_column";
0065: protected static final String SRC_EXP_TO_JDBC_TYPE_MAP = "srcExpToJdbcTypeMap";
0066: protected AbstractDB db;
0067: protected AbstractGeneratorFactory genFactory;
0068:
0069: public BaseStatements(AbstractDB database) {
0070: this .db = database;
0071: this .genFactory = database.getGeneratorFactory();
0072: }
0073:
0074: public List<ResolvedMapping> createResolvedMappings(
0075: TargetTable targetTable, boolean excludeKeyColumns,
0076: StatementContext context) throws BaseException {
0077: List<ResolvedMapping> mappings = new ArrayList<ResolvedMapping>();
0078: String targetJoin = getTargetJoinClause(targetTable,
0079: SQLConstants.INNER_JOIN, context);
0080:
0081: Iterator it = targetTable.getMappedColumns().iterator();
0082: int aliasCount = 1;
0083:
0084: while (it.hasNext()) {
0085: TargetColumn column = (TargetColumn) it.next();
0086: if (column.getValue() != null) {
0087: String tSql = this .genFactory.generate(column, context);
0088: if (targetJoin.indexOf(tSql) != -1 && excludeKeyColumns) {
0089: continue;
0090: }
0091:
0092: String sSql = this .genFactory.generate(column
0093: .getValue(), context);
0094: ColumnIdentifier sId = new ColumnIdentifier(
0095: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX
0096: + aliasCount, sSql);
0097: ColumnIdentifier tId = new ColumnIdentifier(
0098: TARGET_COLUMN_IDENTIFIER_ALIAS_PREFIX
0099: + aliasCount, tSql);
0100: ResolvedMapping rm = new ResolvedMapping(sId, tId);
0101: mappings.add(rm);
0102: aliasCount++;
0103: }
0104: }
0105:
0106: return mappings;
0107: }
0108:
0109: /**
0110: * Creates SQL statement to generate log summary table.
0111: *
0112: * @param useMemoryTable true if statement should use syntax for Axion memory table,
0113: * false if a delimited flatfile table is required.
0114: * @return SQLPart containing appropriate create statement for summary table
0115: */
0116: public SQLPart getCreateLogSummaryTableStatement(
0117: boolean useMemoryTable) throws BaseException {
0118: String tableName = LOG_SUMMARY_TABLE_NAME;
0119: StringBuilder sqlBuf = new StringBuilder(100);
0120: VelocityContext vContext = new VelocityContext();
0121: vContext.put("indent", " ");
0122:
0123: vContext.put("tableName", tableName);
0124: vContext.put("fileName", tableName + ".bad");
0125: vContext.put("recordDelimiter", "\\r\\n");
0126: vContext.put("fieldDelimiter", ",");
0127: vContext.put("textQualifier", "\"");
0128: vContext.put("isFirstLineHeader", "true");
0129:
0130: vContext.put("ifNotExists", Boolean.TRUE);
0131: vContext.put("useMemoryTable", Boolean.valueOf(useMemoryTable));
0132:
0133: sqlBuf.append(TemplateBuilder
0134: .generateSql(this .db
0135: .getTemplateFileName("createLogSummaryTable"),
0136: vContext));
0137:
0138: return createSQLPart(sqlBuf.toString(),
0139: SQLPart.STMT_CREATELOGSUMMARYTABLE);
0140: }
0141:
0142: public SQLPart getCreateStatement(SQLDBTable table,
0143: StatementContext context) throws BaseException {
0144: if (context == null) {
0145: context = new StatementContext();
0146: }
0147:
0148: StringBuilder resultBuf = new StringBuilder(50);
0149: VelocityContext vContext = new VelocityContext();
0150:
0151: vContext.put("statementSeparator", Character
0152: .toString(SQLPart.STATEMENT_SEPARATOR));
0153:
0154: String tableName = this .genFactory.generate(table, context);
0155: vContext.put("tableName", tableName);
0156: vContext.put("tempTableName", SQLObjectUtil
0157: .generateTemporaryTableName(table.getName()));
0158:
0159: List<ColumnIdentifier> cIdentifiers = new ArrayList<ColumnIdentifier>();
0160: List<Boolean> nullableIdentifiers = new ArrayList<Boolean>();
0161:
0162: List columns = table.getColumnList();
0163: for (int i = 0; i < columns.size(); i++) {
0164: // Should be part of expression/type generator.
0165: SQLDBColumn column = (SQLDBColumn) columns.get(i);
0166: String name = db.getEscapedName(column.getName());
0167:
0168: int jdbcTypeInt = column.getJdbcType();
0169: int precision = column.getPrecision();
0170: int scale = column.getScale();
0171:
0172: resultBuf.setLength(0);
0173: resultBuf.append(name).append(" ").append(
0174: this .db.getTypeGenerator().generate(jdbcTypeInt,
0175: precision, scale));
0176:
0177: cIdentifiers.add(new ColumnIdentifier(null, resultBuf
0178: .toString()));
0179: nullableIdentifiers.add(Boolean
0180: .valueOf(column.isNullable()));
0181: }
0182:
0183: vContext.put("sourceColumnIdentifiers", cIdentifiers);
0184: vContext.put("nullables", nullableIdentifiers);
0185:
0186: List<String> pkIdentifiers = new ArrayList<String>();
0187: PrimaryKey pk = table.getPrimaryKey();
0188: if (pk != null && pk.getColumnCount() != 0) {
0189: Iterator pkIter = pk.getColumnNames().iterator();
0190: while (pkIter.hasNext()) {
0191: pkIdentifiers.add(db.getEscapedName(pkIter.next()
0192: .toString()));
0193: }
0194: }
0195:
0196: vContext.put("pkIdentifiers", pkIdentifiers);
0197:
0198: String createStatement = TemplateBuilder.generateSql(this .db
0199: .getTemplateFileName("create"), vContext); // NOI18N
0200: return createSQLPart(createStatement, SQLPart.STMT_CREATE); // NOI18N
0201: }
0202:
0203: public SQLPart getDefragStatement(SQLDBTable table,
0204: StatementContext context) throws BaseException {
0205: // Null implementation: do nothing. Allow subclasses to override if necessary.
0206: return null;
0207: }
0208:
0209: public SQLPart getDeleteInvalidRowFromSummaryTableStatement(
0210: TargetTable table) throws BaseException {
0211: String summaryTable = LOG_SUMMARY_TABLE_NAME;
0212: StringBuilder sqlBuf = new StringBuilder(100);
0213: VelocityContext vContext = new VelocityContext();
0214:
0215: vContext.put("tableName", summaryTable);
0216:
0217: sqlBuf
0218: .append(TemplateBuilder
0219: .generateSql(
0220: this .db
0221: .getTemplateFileName("deleteInvalidRowFromSummaryTable"),
0222: vContext));
0223:
0224: return createSQLPart(sqlBuf.toString(),
0225: SQLPart.STMT_DELETEINVALIDROWFROMSUMMARY);
0226: }
0227:
0228: public SQLPart getDeleteStatement(SQLDBTable table,
0229: StatementContext context) throws BaseException {
0230: if (context == null) {
0231: context = new StatementContext();
0232: }
0233:
0234: VelocityContext vContext = new VelocityContext();
0235: StringBuilder resultBuf = new StringBuilder();
0236:
0237: //DELETE STATEMENT
0238: String tableName = this .genFactory.generate(table, context);
0239: vContext.put("table", tableName);
0240:
0241: String deleteStatement = TemplateBuilder.generateSql(this .db
0242: .getTemplateFileName("delete"), vContext); // NOI18N
0243: resultBuf.append(deleteStatement);
0244:
0245: //WHERE condition
0246: Object prop = context.getClientProperty("useWhere");
0247: boolean useWhere = (prop instanceof Boolean) ? ((Boolean) prop)
0248: .booleanValue() : false;
0249: if (table instanceof TargetTable && useWhere) {
0250: String condition = getTargetWhereCondition(
0251: (TargetTable) table, context);
0252: if (condition != null && !condition.trim().equals("")) {
0253: vContext = new VelocityContext();
0254: vContext.put("condition", condition);
0255: vContext.put("nestedIndent", "");
0256: String whereClause = TemplateBuilder.generateSql(
0257: this .db.getTemplateFileName("where"), vContext); // NOI18N
0258: resultBuf.append(whereClause);
0259: }
0260: }
0261:
0262: return createSQLPart(resultBuf.toString(), SQLPart.STMT_DELETE); // NOI18N
0263: }
0264:
0265: public SQLPart getDropStatement(SQLDBTable table,
0266: StatementContext context) throws BaseException {
0267: if (context == null) {
0268: context = new StatementContext();
0269: }
0270:
0271: VelocityContext vContext = new VelocityContext();
0272:
0273: String tableName = this .genFactory.generate(table, context);
0274: vContext.put("tableName", tableName);
0275:
0276: Object prop = context
0277: .getClientProperty(StatementContext.IF_EXISTS);
0278: vContext.put(StatementContext.IF_EXISTS,
0279: (prop instanceof Boolean) ? (Boolean) prop
0280: : Boolean.FALSE);
0281:
0282: String dropStatement = TemplateBuilder.generateSql(this .db
0283: .getTemplateFileName("drop"), vContext); // NOI18N
0284: return createSQLPart(dropStatement, SQLPart.STMT_DROP);
0285: }
0286:
0287: public SQLPart getInitializationStatements(StatementContext context)
0288: throws BaseException {
0289: return null;
0290: }
0291:
0292: public SQLPart getInsertSelectStatement(TargetTable targetTable,
0293: StatementContext context) throws BaseException {
0294: VelocityContext vContext = new VelocityContext();
0295: this .populateContextForInsertSelect(targetTable, context,
0296: vContext);
0297:
0298: String result = TemplateBuilder.generateSql(this .db
0299: .getTemplateFileName("insertSelect"), vContext); // NOI18N
0300: return createSQLPart(result, SQLPart.STMT_INSERTSELECT); // NOI18N
0301: }
0302:
0303: /**
0304: * @param table
0305: * @param logTableName
0306: * @return
0307: */
0308: public SQLPart getInsertStartDateIntoSummaryTableStatement(
0309: TargetTable table, StatementContext context)
0310: throws BaseException {
0311: String summaryTable = LOG_SUMMARY_TABLE_NAME;
0312: StringBuilder sqlBuf = new StringBuilder(100);
0313: VelocityContext vContext = new VelocityContext();
0314:
0315: vContext.put("tableName", summaryTable);
0316: vContext.put("targetTable", getTableNameForStatisticsMetadata(
0317: table, context));
0318:
0319: sqlBuf
0320: .append(TemplateBuilder
0321: .generateSql(
0322: this .db
0323: .getTemplateFileName("insertStartDateIntoSummaryTable"),
0324: vContext));
0325:
0326: return createSQLPart(sqlBuf.toString(),
0327: SQLPart.STMT_INSERTEXECUTIONRECORD);
0328: }
0329:
0330: public SQLPart getMergeStatement(TargetTable targetTable,
0331: StatementContext context) throws BaseException {
0332: if (context == null) {
0333: context = new StatementContext();
0334: }
0335:
0336: StringBuilder mergeStatement = new StringBuilder(100);
0337: mergeStatement.append(this .getUpdateStatement(targetTable,
0338: context).getSQL().toString());
0339: mergeStatement.append(Character
0340: .toString(SQLPart.STATEMENT_SEPARATOR));
0341: mergeStatement.append(this .getInsertSelectStatement(
0342: targetTable, context).getSQL().toString());
0343:
0344: return createSQLPart(mergeStatement.toString(),
0345: SQLPart.STMT_MERGE); // NOI18N;
0346: }
0347:
0348: /**
0349: * Returns Source Table columns directly mapped to target table.
0350: * Also updates JDBC types of all the mapped target columns whether directly or thru expression.
0351: * @param tt
0352: * @param context
0353: * @return
0354: */
0355: protected List getSourceColsDirectlyMapped(TargetTable tt,
0356: StatementContext context) {
0357: if (context == null) {
0358: context = new StatementContext();
0359: }
0360:
0361: List<SourceColumn> srcColsMappedToTgt = new ArrayList<SourceColumn>();
0362: Iterator it = tt.getMappedColumns().iterator();
0363: List<String> jdbcTypeList = new ArrayList<String>();
0364: String val = null;
0365:
0366: while (it.hasNext()) {
0367: TargetColumn column = (TargetColumn) it.next();
0368: SQLObject exp = column.getValue();
0369: val = "" + column.getJdbcType();
0370: jdbcTypeList.add(val);
0371: if (exp instanceof SourceColumn) {
0372: SourceColumn srcColumn = (SourceColumn) exp;
0373: srcColsMappedToTgt.add(srcColumn);
0374: }
0375: }
0376: context.putClientProperty(SQLPart.ATTR_JDBC_TYPE_LIST,
0377: jdbcTypeList);
0378: return srcColsMappedToTgt;
0379: }
0380:
0381: protected List getSourceColsDirectlyMapped(TargetTable tt) {
0382: return getSourceColsDirectlyMapped(tt, (StatementContext) null);
0383: }
0384:
0385: protected void populateAnsiMergeStatement(TargetTable targetTable,
0386: StatementContext context, VelocityContext vContext)
0387: throws BaseException {
0388: List<ColumnIdentifier> sourceColumnIdentifiers = new ArrayList<ColumnIdentifier>();
0389: List<ColumnIdentifier> targetColumnIdentifiers = new ArrayList<ColumnIdentifier>();
0390: List<ColumnIdentifier> subSelectIdentifiers = new ArrayList<ColumnIdentifier>();
0391: List<ResolvedMapping> joinAliases = new ArrayList<ResolvedMapping>();
0392: List srcColDirectlyMapped = getSourceColsDirectlyMapped(targetTable);
0393: int lastAliasIndex = 0;
0394:
0395: final boolean excludeJoinKeyColumns = false;
0396:
0397: if (context == null) {
0398: context = new StatementContext();
0399: }
0400:
0401: SubSelectIdentifier subIdentifier = new SubSelectIdentifier(
0402: "J1");
0403:
0404: //SELECT START
0405: context.putClientProperty(
0406: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
0407: Boolean.TRUE);
0408: //context.putClientProperty(StatementContext.USE_TARGET_TABLE_ALIAS_NAME, Boolean.TRUE);
0409: String targetJoin = getTargetJoinClause(targetTable,
0410: SQLConstants.INNER_JOIN, context);
0411: List rMappings = createResolvedMappings(targetTable,
0412: excludeJoinKeyColumns, context);
0413: if (rMappings != null) {
0414: lastAliasIndex = rMappings.size();
0415: }
0416: ListIterator it = rMappings.listIterator();
0417: while (it.hasNext()) {
0418: ResolvedMapping rm = (ResolvedMapping) it.next();
0419:
0420: ColumnIdentifier oldSrc = rm.getSource();
0421: sourceColumnIdentifiers.add(oldSrc);
0422:
0423: ColumnIdentifier cId = new ColumnIdentifier(subIdentifier
0424: .getAliasName()
0425: + "." + rm.getSource().getAliasName(), oldSrc
0426: .getSql());
0427: subSelectIdentifiers.add(cId);
0428: rm.setSource(cId);
0429:
0430: targetColumnIdentifiers.add(rm.getTarget());
0431:
0432: // If the target column is involved in the join condition, remove its ResolvedMapping
0433: // from the update statement list and remember it so that we can substitute the
0434: // appropraite aliases for its source column in the join condition.
0435: if (targetJoin.indexOf(rm.getTarget().getSql()) != -1) {
0436: it.remove();
0437: joinAliases.add(rm);
0438: }
0439: }
0440:
0441: vContext.put("statementSeparator", Character
0442: .toString(SQLPart.STATEMENT_SEPARATOR));
0443:
0444: // Merge condition
0445: String mergeCondition = "";
0446: SQLCondition cond = targetTable.getJoinCondition();
0447: List<ColumnIdentifier> colIds = null;
0448: if (cond != null) {
0449: SQLPredicate predicate = cond.getRootPredicate();
0450: if (predicate != null) {
0451: mergeCondition = this .genFactory.generate(predicate,
0452: context);
0453: List columnsTobeAliased = getConditionColumnsNotInList(
0454: cond, srcColDirectlyMapped);
0455: List<ColumnIdentifier> missingSourceColIds = this
0456: .createColumnIdentifiersFromSourceColumns(
0457: columnsTobeAliased, context,
0458: lastAliasIndex + 1);
0459: List<ColumnIdentifier> missingMergeColIds = this
0460: .createColumnIdentifiersFromSourceColumns(
0461: columnsTobeAliased,
0462: context,
0463: lastAliasIndex + 1,
0464: subIdentifier.getAliasName()
0465: + "."
0466: + SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX);
0467: lastAliasIndex = lastAliasIndex
0468: + missingSourceColIds.size();
0469: colIds = getColIdsFromRM(joinAliases);
0470: sourceColumnIdentifiers.addAll(missingSourceColIds);
0471: colIds.addAll(missingMergeColIds);
0472: // now replace the column name for source with alias name
0473: mergeCondition = replaceColumnNamesWithAliases(colIds,
0474: mergeCondition);
0475: }
0476: }
0477:
0478: if (!StringUtil.isNullString(mergeCondition)) {
0479: vContext.put("mergeCondition", mergeCondition);
0480: }
0481:
0482: //context.putClientProperty(StatementContext.USE_TARGET_TABLE_ALIAS_NAME, Boolean.TRUE);
0483: String targetTableName = this .genFactory.generate(targetTable,
0484: context);
0485:
0486: vContext.put("targetTable", targetTableName);
0487: vContext
0488: .put("subSelectAliasName", subIdentifier.getAliasName());
0489: vContext
0490: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0491: vContext
0492: .put("targetColumnIdentifiers", targetColumnIdentifiers);
0493: vContext.put("valueIdentifiers", subSelectIdentifiers);
0494:
0495: vContext.put("aliasColumns", Boolean.TRUE);
0496: //vContext.put("distinct", Boolean.FALSE);
0497: vContext.put("distinct", areDistinctRowsRequired(targetTable));
0498: vContext.put("selectAliasName", "");
0499: vContext.put("fromContent", getFromStatementContent(
0500: targetTable, context));
0501: vContext.put("lastSourceAliasIndex",
0502: new Integer(lastAliasIndex));
0503:
0504: vContext.put("useWhere", Boolean.FALSE);
0505:
0506: String condition = getWhereCondition(targetTable, context);
0507:
0508: if (condition != null && !condition.equals("")) {
0509: vContext.put("useWhere", Boolean.TRUE);
0510: vContext.put("condition", condition);
0511: }
0512: //SELECT END
0513: // errorValueIdentifiers is require only for validation
0514: context.putClientProperty("errorValueIdentifiers",
0515: subSelectIdentifiers);
0516: context.putClientProperty("sourceColumnIdentifiers",
0517: sourceColumnIdentifiers);
0518: context.putClientProperty(
0519: "mergeConditionSourceColumnAliasPrefix", subIdentifier
0520: .getAliasName());
0521: if ((colIds != null) && (colIds.size() > 0)) {
0522: context.putClientProperty(
0523: "mergeConditionColumnIdentifiers", colIds);
0524: }
0525:
0526: vContext.put("mappings", rMappings);
0527: }
0528:
0529: public SQLPart getOnePassSelectStatement(TargetTable targetTable,
0530: StatementContext context) throws BaseException {
0531: if (context == null) {
0532: context = new StatementContext();
0533: }
0534:
0535: VelocityContext vContext = new VelocityContext();
0536:
0537: context.putClientProperty(
0538: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
0539: Boolean.TRUE);
0540:
0541: List sourceColumnIdentifiers = this .createSourceIdentifierList(
0542: targetTable, context);
0543: vContext
0544: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0545:
0546: vContext.put("aliasColumns", Boolean.FALSE);
0547: vContext.put("distinct", areDistinctRowsRequired(targetTable));
0548:
0549: vContext.put("selectAliasName", "");
0550: vContext.put("fromContent", getFromStatementContent(
0551: targetTable, context));
0552: vContext.put("nestedIndent", "");
0553:
0554: String condition = getWhereCondition(targetTable, context);
0555: if (condition != null && !condition.equals("")) {
0556: vContext.put("useWhere", Boolean.TRUE);
0557: vContext.put("condition", condition);
0558: }
0559:
0560: SourceTable[] srcTables = targetTable.getSourceTableList()
0561: .toArray(new SourceTable[0]);
0562: for (SourceTable srcTable : srcTables) {
0563: populateContextForGroupByAndHaving(srcTable, context,
0564: vContext);
0565: }
0566:
0567: populateContextForGroupByAndHaving(targetTable, context,
0568: vContext);
0569: populateContextForGroupByAndHaving(targetTable.getJoinView(),
0570: context, vContext);
0571:
0572: String result = TemplateBuilder.generateSql(this .db
0573: .getTemplateFileName("select"), vContext); // NOI18N
0574: return createSQLPart(result, SQLPart.STMT_SELECT);
0575: }
0576:
0577: protected void populateContextForGroupByAndHaving(SQLObject object,
0578: StatementContext context, VelocityContext vContext)
0579: throws BaseException {
0580: SQLGroupBy groupBy = null;
0581: if (object instanceof SourceTable) {
0582: groupBy = ((SourceTable) object).getSQLGroupBy();
0583: } else if (object instanceof TargetTable) {
0584: groupBy = ((TargetTable) object).getSQLGroupBy();
0585: } else if (object instanceof SQLJoinView) {
0586: groupBy = ((SQLJoinView) object).getSQLGroupBy();
0587: }
0588: if (groupBy != null && groupBy.getColumns().size() > 0) {
0589: vContext.put("useGroupBy", Boolean.TRUE);
0590: List groupByList = createGroupByIdentifierList(object,
0591: context);
0592: vContext.put("groupByIdentifiers", groupByList);
0593:
0594: String havingCondition = getHavingCondition(groupBy,
0595: context);
0596: if (havingCondition != null && !havingCondition.equals("")) {
0597: vContext.put("havingCondition", havingCondition);
0598: }
0599: }
0600: }
0601:
0602: public SQLPart getPreparedInsertStatement(SQLDBTable table,
0603: StatementContext context) throws BaseException {
0604: VelocityContext vContext = new VelocityContext();
0605: this .populateContextForPrepStmtInsert(table, context, vContext);
0606:
0607: String result = TemplateBuilder.generateSql(this .db
0608: .getTemplateFileName("insertValues"), vContext); // NOI18N
0609: SQLPart sqlPart = createSQLPart(result, SQLPart.STMT_INSERT);
0610: sqlPart.setAttribute(SQLPart.ATTR_JDBC_TYPE_LIST, context
0611: .getClientProperty(SQLPart.ATTR_JDBC_TYPE_LIST));
0612:
0613: return sqlPart;
0614: }
0615:
0616: public SQLPart getRowCountStatement(SQLDBTable table,
0617: StatementContext context) throws BaseException {
0618: if (context == null) {
0619: context = new StatementContext();
0620: }
0621: VelocityContext vContext = new VelocityContext();
0622: boolean isSource = table.getObjectType() == SQLConstants.SOURCE_TABLE;
0623: boolean fullExtraction = isSource
0624: && "full".equalsIgnoreCase(((SourceTable) table)
0625: .getExtractionType());
0626:
0627: vContext.put("tableName", this .genFactory.generate(table,
0628: context));
0629: vContext.put("useWhere", Boolean.FALSE);
0630:
0631: if (isSource && !fullExtraction) {
0632: SQLCondition cond = ((SourceTable) table)
0633: .getExtractionCondition();
0634: SQLObject predicate = (cond != null) ? cond
0635: .getRootPredicate() : null;
0636:
0637: if (predicate != null) {
0638: vContext.put("useWhere", Boolean.TRUE);
0639: vContext.put("whereCondition", this .genFactory
0640: .generate(predicate, context));
0641: }
0642: }
0643: String result = TemplateBuilder.generateSql(this .db
0644: .getTemplateFileName("rowCount"), vContext); // NOI18N
0645: return createSQLPart(result, SQLPart.STMT_ROWCOUNT);
0646: }
0647:
0648: public SQLPart getSelectExecutionIdFromSummaryTableStatement(
0649: TargetTable table, StatementContext context)
0650: throws BaseException {
0651: String summaryTable = LOG_SUMMARY_TABLE_NAME;
0652: StringBuilder sqlBuf = new StringBuilder(100);
0653:
0654: VelocityContext vContext = new VelocityContext();
0655: vContext.put("summaryTable", summaryTable);
0656: vContext.put("targetTable", getTableNameForStatisticsMetadata(
0657: table, context));
0658:
0659: sqlBuf
0660: .append(TemplateBuilder
0661: .generateSql(
0662: this .db
0663: .getTemplateFileName("selectExecutionIdFromSummaryTable"),
0664: vContext));
0665:
0666: return createSQLPart(sqlBuf.toString(),
0667: SQLPart.STMT_SELECTEXECUTIONIDFROMSUMMARY);
0668: }
0669:
0670: public SQLPart getSelectStatement(SourceTable sourceTable,
0671: StatementContext context) throws BaseException {
0672: if (context == null) {
0673: context = new StatementContext();
0674: }
0675: VelocityContext vContext = new VelocityContext();
0676:
0677: List sourceColumnIdentifiers = this .createSourceIdentifierList(
0678: sourceTable, context);
0679: vContext
0680: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0681:
0682: vContext.put("aliasColumns", Boolean.valueOf(context
0683: .isUseSourceColumnAliasName()));
0684: vContext.put("distinct", Boolean.valueOf(sourceTable
0685: .isSelectDistinct()));
0686:
0687: vContext.put("selectAliasName", "");
0688: String tableName = this .genFactory.generate(sourceTable,
0689: context);
0690: vContext.put("fromContent", tableName);
0691:
0692: // Add extraction conditions only if user did not set extraction flag to full.
0693: vContext.put("condition", "");
0694: vContext.put("useWhere", Boolean.FALSE);
0695: vContext.put("nestedIndent", "");
0696: if (!"full".equalsIgnoreCase(sourceTable.getExtractionType())) {
0697: //NOI18N
0698: List<SourceTable> sourceList = new ArrayList<SourceTable>(1);
0699: sourceList.add(sourceTable);
0700: String condition = getSourceWhereCondition(sourceList,
0701: context);
0702: if (condition != null && !condition.equals("")) {
0703: vContext.put("useWhere", Boolean.TRUE);
0704: vContext.put("condition", condition);
0705: vContext.put("notInSql", "");
0706: vContext.put("integritySql", "");
0707: }
0708: }
0709:
0710: Object prop = context.getClientProperty("limit");
0711: String limit = (prop == null) ? "" : prop.toString();
0712: vContext.put("limit", limit);
0713:
0714: populateContextForGroupByAndHaving(sourceTable, context,
0715: vContext);
0716:
0717: String result = TemplateBuilder.generateSql(this .db
0718: .getTemplateFileName("select"), vContext); // NOI18N
0719: return createSQLPart(result, SQLPart.STMT_SELECT);
0720: }
0721:
0722: public SQLPart getSelectStatement(SQLJoinView joinView,
0723: StatementContext context) throws BaseException {
0724: if (context == null) {
0725: context = new StatementContext();
0726: }
0727: VelocityContext vContext = new VelocityContext();
0728:
0729: List<ColumnIdentifier> sourceColumnIdentifiers = new ArrayList<ColumnIdentifier>();
0730: Iterator it = joinView.getSourceTables().iterator();
0731: while (it.hasNext()) {
0732: SourceTable table = (SourceTable) it.next();
0733: sourceColumnIdentifiers.addAll(this
0734: .createSourceIdentifierList(table, context));
0735: }
0736:
0737: vContext
0738: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0739:
0740: vContext.put("aliasColumns", Boolean.valueOf(context
0741: .isUseSourceColumnAliasName()));
0742:
0743: vContext.put("selectAliasName", "");
0744: String fromContent = this .genFactory.generate(joinView
0745: .getRootJoin(), context);
0746: vContext.put("fromContent", fromContent);
0747:
0748: // Add extraction conditions only if user did not set extraction flag to full.
0749: vContext.put("condition", "");
0750: vContext.put("useWhere", Boolean.FALSE);
0751: vContext.put("nestedIndent", "");
0752: String condition = getSourceWhereCondition(joinView
0753: .getSourceTables(), context);
0754: if (condition != null && !condition.equals("")) {
0755: vContext.put("useWhere", Boolean.TRUE);
0756: vContext.put("condition", condition);
0757: vContext.put("notInSql", "");
0758: vContext.put("integritySql", "");
0759: }
0760:
0761: Object prop = context.getClientProperty("limit");
0762: String limit = (prop == null) ? "" : prop.toString();
0763: vContext.put("limit", limit);
0764:
0765: SourceTable[] srcTables = joinView.getSourceTables().toArray(
0766: new SourceTable[0]);
0767: for (SourceTable srcTable : srcTables) {
0768: populateContextForGroupByAndHaving(srcTable, context,
0769: vContext);
0770: }
0771: populateContextForGroupByAndHaving(joinView, context, vContext);
0772:
0773: String result = TemplateBuilder.generateSql(this .db
0774: .getTemplateFileName("select"), vContext); // NOI18N
0775: return createSQLPart(result, SQLPart.STMT_SELECT);
0776: }
0777:
0778: public SQLPart getSelectStatement(SQLJoinOperator joinOp,
0779: StatementContext context) throws BaseException {
0780: if (context == null) {
0781: context = new StatementContext();
0782: }
0783: VelocityContext vContext = new VelocityContext();
0784:
0785: List<ColumnIdentifier> sourceColumnIdentifiers = new ArrayList<ColumnIdentifier>();
0786: for (SourceTable table : joinOp.getAllSourceTables()) {
0787: sourceColumnIdentifiers.addAll(this
0788: .createSourceIdentifierList(table, context));
0789: }
0790:
0791: vContext
0792: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0793:
0794: vContext.put("aliasColumns", Boolean.valueOf(context
0795: .isUseSourceColumnAliasName()));
0796:
0797: vContext.put("selectAliasName", "");
0798: String fromContent = this .genFactory.generate(joinOp, context);
0799: vContext.put("fromContent", fromContent);
0800:
0801: // Add extraction conditions only if user did not set extraction flag to full.
0802: vContext.put("condition", "");
0803: vContext.put("useWhere", Boolean.FALSE);
0804: vContext.put("nestedIndent", "");
0805: String condition = getSourceWhereCondition(joinOp
0806: .getAllSourceTables(), context);
0807: if (condition != null && !condition.equals("")) {
0808: vContext.put("useWhere", Boolean.TRUE);
0809: vContext.put("condition", condition);
0810: vContext.put("notInSql", "");
0811: vContext.put("integritySql", "");
0812: }
0813:
0814: Object prop = context.getClientProperty("limit");
0815: String limit = (prop == null) ? "" : prop.toString();
0816: vContext.put("limit", limit);
0817:
0818: SourceTable[] srcTables = joinOp.getAllSourceTables().toArray(
0819: new SourceTable[0]);
0820: for (SourceTable srcTable : srcTables) {
0821: populateContextForGroupByAndHaving(srcTable, context,
0822: vContext);
0823: }
0824:
0825: String result = TemplateBuilder.generateSql(this .db
0826: .getTemplateFileName("select"), vContext); // NOI18N
0827: return createSQLPart(result, SQLPart.STMT_SELECT);
0828: }
0829:
0830: public SQLPart getSelectStatement(TargetTable targetTable,
0831: StatementContext context) throws BaseException {
0832: if (context == null) {
0833: context = new StatementContext();
0834: }
0835:
0836: VelocityContext vContext = new VelocityContext();
0837:
0838: List<ColumnIdentifier> sourceColumnIdentifiers = new ArrayList<ColumnIdentifier>();
0839: Iterator it = targetTable.getColumnList().iterator();
0840: while (it.hasNext()) {
0841: TargetColumn column = (TargetColumn) it.next();
0842: String sql = this .genFactory.generate(column, context);
0843: ColumnIdentifier cId = new ColumnIdentifier(column
0844: .getDisplayName(), sql);
0845: sourceColumnIdentifiers.add(cId);
0846: }
0847: vContext
0848: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
0849:
0850: vContext.put("aliasColumns", Boolean.FALSE);
0851: vContext.put("distinct", Boolean.FALSE);
0852:
0853: vContext.put("selectAliasName", "");
0854: vContext.put("fromContent", this .genFactory.generate(
0855: targetTable, context));
0856: vContext.put("useWhere", Boolean.FALSE);
0857: vContext.put("nestedIndent", "");
0858:
0859: Object prop = context.getClientProperty("limit");
0860: String limit = (prop == null) ? "" : prop.toString();
0861: vContext.put("limit", limit);
0862:
0863: String result = TemplateBuilder.generateSql(this .db
0864: .getTemplateFileName("select"), vContext); // NOI18N
0865: return createSQLPart(result, SQLPart.STMT_SELECT); // NOI18N
0866: }
0867:
0868: public SQLPart getStaticInsertStatement(TargetTable targetTable,
0869: StatementContext context) throws BaseException {
0870: StatementContext localContext = new StatementContext();
0871: if (context != null) {
0872: localContext.putAll(context);
0873: }
0874: localContext.setSuppressingTablePrefixForTargetColumn(true);
0875:
0876: VelocityContext vContext = new VelocityContext();
0877: this .populateContextForStaticInsert(targetTable, localContext,
0878: vContext);
0879:
0880: String result = TemplateBuilder.generateSql(this .db
0881: .getTemplateFileName("insertValues"), vContext); // NOI18N
0882: return createSQLPart(result, SQLPart.STMT_STATICINSERT); // NOI18N
0883: }
0884:
0885: public String getSummaryTableName() {
0886: return LOG_SUMMARY_TABLE_NAME;
0887: }
0888:
0889: public SQLPart getTableExistsStatement(SQLDBTable table,
0890: StatementContext context) throws BaseException {
0891: if (context == null) {
0892: context = new StatementContext();
0893: }
0894:
0895: VelocityContext vContext = new VelocityContext();
0896:
0897: // WT 63392: Need to replace characters normally used to escape table
0898: // names with single-quotes in context of using the table name as a String.
0899: vContext.put("tableName", getUnqualifiedTableName(table,
0900: context));
0901:
0902: // If schemaName is supplied in the context, use that value rather than the name
0903: // associated
0904: // with the target table - table may be a SourceTable but the appropriate schema
0905: // to use may
0906: // not be the value obtained from table.getSchema().
0907: String schemaName = (String) context
0908: .getClientProperty("targetSchema");
0909: if (StringUtil.isNullString(schemaName)) {
0910: String uSchema = table.getUserDefinedSchemaName();
0911: if (StringUtil.isNullString(uSchema)) {
0912: if (!StringUtil.isNullString(table.getSchema())) {
0913: schemaName = table.getSchema().toUpperCase();
0914: }
0915: } else {
0916: schemaName = uSchema.toUpperCase();
0917: }
0918: }
0919: vContext.put("schemaName", schemaName);
0920:
0921: String result = TemplateBuilder.generateSql(this .db
0922: .getTemplateFileName("tableExists"), vContext); // NOI18N
0923: return createSQLPart(result, SQLPart.STMT_CHECKTABLEEXISTS); // NOI18N;;
0924: }
0925:
0926: public SQLPart getTruncateStatement(SQLDBTable targetTable,
0927: StatementContext context) throws BaseException {
0928: VelocityContext vContext = new VelocityContext();
0929:
0930: vContext.put("statementSeparator", Character
0931: .toString(SQLPart.STATEMENT_SEPARATOR));
0932: vContext.put("tableName", this .genFactory.generate(targetTable,
0933: context));
0934:
0935: String result = TemplateBuilder.generateSql(this .db
0936: .getTemplateFileName("truncate"), vContext); // NOI18N
0937: return createSQLPart(result, SQLPart.STMT_TRUNCATE); // NOI18N;;
0938: }
0939:
0940: public SQLPart getUpdateEndDateInSummaryTableStatement(
0941: TargetTable table, StatementContext context)
0942: throws BaseException {
0943: String summaryTable = LOG_SUMMARY_TABLE_NAME;
0944: StringBuilder sqlBuf = new StringBuilder(100);
0945:
0946: VelocityContext vContext = new VelocityContext();
0947: vContext.put("tableName", summaryTable);
0948: vContext.put("targetTable", getTableNameForStatisticsMetadata(
0949: table, context));
0950:
0951: sqlBuf.append(TemplateBuilder.generateSql(this .db
0952: .getTemplateFileName("updateEndDateInSummaryTable"),
0953: vContext));
0954:
0955: return createSQLPart(sqlBuf.toString(),
0956: SQLPart.STMT_UPDATEEXECUTIONRECORD);
0957: }
0958:
0959: public SQLPart getUpdateStatement(TargetTable targetTable,
0960: StatementContext context) throws BaseException {
0961: VelocityContext vContext = new VelocityContext();
0962: String templateName = "";
0963:
0964: if (targetTable.getSourceTableList().size() != 0) {
0965: populateContextForUpdate(targetTable, context, vContext);
0966: templateName = this .db.getTemplateFileName("update"); // NOI18N
0967: } else {
0968: populateContextForStaticUpdate(targetTable, context,
0969: vContext);
0970: templateName = this .db.getTemplateFileName("updateStatic"); // NOI18N
0971: }
0972: String result = TemplateBuilder.generateSql(templateName,
0973: vContext);
0974:
0975: return createSQLPart(result, SQLPart.STMT_UPDATE); // NOI18N
0976: }
0977:
0978: // TODO Voilates Statements interface pattern, need to redesign the interfaces.
0979: public Map getCorrelatedUpdateStatement(TargetTable targetTable,
0980: StatementContext context) throws BaseException {
0981: throw new UnsupportedOperationException(
0982: "Not supported for this DB yet.");
0983: }
0984:
0985: /**
0986: * Implements no-op version of method signature - concrete subclasses should override to
0987: * perform any formatting of the SQL statement in <code>rawSQLPart</code> that is required
0988: * for a particular JDBC driver to accept and execute it.
0989: *
0990: * @param rawSQLPart SQLPart containing SQL statement to be normalized
0991: * @return SQLPart containing normalized SQL statement
0992: */
0993: public SQLPart normalizeSQLForExecution(SQLPart rawSQLPart) {
0994: return rawSQLPart;
0995: }
0996:
0997: /**
0998: * Indicates whether one or more of the source tables, if any, associated with the given
0999: * TargetTable require the use of the DISTINCT keyword when selecting rows from them.
1000: *
1001: * @param targetTable TargetTable whose associated SourceTables are to be interrogated
1002: * @return Boolean.TRUE if at least one table requires the DISTINCT keyword; Boolean.FALSE
1003: * otherwise
1004: */
1005: protected final Boolean areDistinctRowsRequired(
1006: TargetTable targetTable) throws BaseException {
1007: Boolean useDistinct = Boolean.FALSE;
1008: Iterator srcIter = targetTable.getSourceTableList().iterator();
1009: while (srcIter.hasNext()) {
1010: SourceTable sourceTable = (SourceTable) srcIter.next();
1011: if (sourceTable.isSelectDistinct()) {
1012: useDistinct = Boolean.TRUE;
1013: break;
1014: }
1015: }
1016: return useDistinct;
1017: }
1018:
1019: private List<ColumnIdentifier> getIntegrityCheckCols(List tgtCols,
1020: StatementContext context) throws BaseException {
1021: List<ColumnIdentifier> colIds = new ArrayList<ColumnIdentifier>();
1022: Iterator itr = tgtCols.iterator();
1023: TargetColumn tgtCol = null;
1024: ColumnIdentifier colId = null;
1025: String sql = null;
1026:
1027: while (itr.hasNext()) {
1028: tgtCol = (TargetColumn) itr.next();
1029: sql = this .genFactory.generate(tgtCol, context);
1030: colId = new ColumnIdentifier(null, sql);
1031: colIds.add(colId);
1032: }
1033:
1034: return colIds;
1035: }
1036:
1037: protected String appendSQLForIntegrityCheck(
1038: TargetTable targetTable, StatementContext context)
1039: throws BaseException {
1040: //SQL code to check key integrity
1041: SQLCondition cond = targetTable.getJoinCondition();
1042: List colIds = null;
1043:
1044: if (cond != null) {
1045: SQLPredicate predicate = cond.getRootPredicate();
1046: if (predicate != null) {
1047: List tgtCols = predicate.getTargetColumnsUsed();
1048: colIds = getIntegrityCheckCols(tgtCols, context);
1049: }
1050: }
1051:
1052: VelocityContext vContext = new VelocityContext();
1053: String result = "";
1054:
1055: if ((colIds != null) && (colIds.size() > 0)) {
1056: vContext.put("targetColumnIdentifiers", colIds);
1057: result = TemplateBuilder.generateSql(this .db
1058: .getTemplateFileName("selectIntegrityCheck"),
1059: vContext); // NOI18N
1060: }
1061:
1062: return result;
1063: }
1064:
1065: /**
1066: * Gets List of ColumnIdentifiers representing all columns in a source table.
1067: *
1068: * @param sourceTable
1069: * @param context
1070: * @return
1071: * @throws BaseException
1072: */
1073: protected List<ColumnIdentifier> createGroupByIdentifierList(
1074: SQLObject object, StatementContext context)
1075: throws BaseException {
1076: List<ColumnIdentifier> cIdentifiers = new ArrayList<ColumnIdentifier>();
1077:
1078: SQLGroupBy rGroupBy = null;
1079: if (object instanceof SourceTable) {
1080: rGroupBy = ((SourceTable) object).getSQLGroupBy();
1081: } else if (object instanceof TargetTable) {
1082: rGroupBy = ((TargetTable) object).getSQLGroupBy();
1083: } else if (object instanceof SQLJoinView) {
1084: rGroupBy = ((SQLJoinView) object).getSQLGroupBy();
1085: }
1086: if (rGroupBy != null && rGroupBy.getColumns().size() > 0) {
1087: Iterator it = rGroupBy.getColumns().iterator();
1088: while (it.hasNext()) {
1089: SQLObject expr = (SQLObject) it.next();
1090: if (expr instanceof SourceColumn) {
1091: String sql = this .genFactory
1092: .generate(expr, context);
1093: ColumnIdentifier cId = new ColumnIdentifier(null,
1094: sql);
1095: cIdentifiers.add(cId);
1096: } else if (expr instanceof TargetColumn) {
1097: TargetColumn col = (TargetColumn) expr;
1098: String sql = this .genFactory.generate(col
1099: .getValue(), context);
1100: ColumnIdentifier cId = new ColumnIdentifier(null,
1101: sql);
1102: cIdentifiers.add(cId);
1103: }
1104: }
1105: }
1106:
1107: return cIdentifiers;
1108: }
1109:
1110: /**
1111: * Gets List of ColumnIdentifiers representing all columns in a source table.
1112: *
1113: * @param sourceTable
1114: * @param context
1115: * @return
1116: * @throws BaseException
1117: */
1118: protected List<ColumnIdentifier> createSourceIdentifierList(
1119: SourceTable sourceTable, StatementContext context)
1120: throws BaseException {
1121: ArrayList<ColumnIdentifier> cIdentifiers = new ArrayList<ColumnIdentifier>();
1122:
1123: Iterator it = sourceTable.getColumnList().iterator();
1124: int aliasCount = 1;
1125:
1126: while (it.hasNext()) {
1127: SourceColumn column = (SourceColumn) it.next();
1128: if (column.isVisible() || !column.isNullable()) {
1129: String sql = this .genFactory.generate(column, context);
1130: ColumnIdentifier cId = new ColumnIdentifier(
1131: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX
1132: + aliasCount, sql);
1133: cIdentifiers.add(cId);
1134: aliasCount++;
1135: }
1136: }
1137:
1138: return cIdentifiers;
1139: }
1140:
1141: protected List<ColumnIdentifier> createSourceIdentifierList(
1142: TargetTable targetTable, StatementContext context)
1143: throws BaseException {
1144: List<ColumnIdentifier> cIdentifiers = new ArrayList<ColumnIdentifier>();
1145: int aliasCount = 1;
1146:
1147: for (TargetColumn column : targetTable.getMappedColumns()) {
1148: SQLObject mapExpression = column.getValue();
1149: if (mapExpression != null) {
1150:
1151: String sql = this .genFactory.generate(
1152: column.getValue(), context);
1153: ColumnIdentifier cId = new ColumnIdentifier(
1154: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX
1155: + aliasCount, sql);
1156: cIdentifiers.add(cId);
1157: aliasCount++;
1158:
1159: if (mapExpression instanceof SourceColumn) {
1160: cId.setExpression(false);
1161: } else {
1162: cId.setExpression(true);
1163: }
1164: }
1165: }
1166: return cIdentifiers;
1167: }
1168:
1169: /**
1170: * Creates SQLPart Object
1171: *
1172: * @param sqlString the generated SQL statement string
1173: * @param key key used in the statement map
1174: * @return SQLPart
1175: */
1176: protected SQLPart createSQLPart(String sqlString, String key) {
1177: SQLPart sqlPart = new SQLPart(sqlString, key, "");
1178: return sqlPart;
1179: }
1180:
1181: protected List<ColumnIdentifier> createTargetIdentifierList(
1182: TargetTable targetTable, StatementContext context)
1183: throws BaseException {
1184: List<ColumnIdentifier> cIdentifiers = new ArrayList<ColumnIdentifier>();
1185: int aliasCount = 1;
1186:
1187: for (TargetColumn column : targetTable.getMappedColumns()) {
1188: String sql = this .genFactory.generate(column, context);
1189: ColumnIdentifier cId = new ColumnIdentifier(
1190: TARGET_COLUMN_IDENTIFIER_ALIAS_PREFIX + aliasCount,
1191: sql);
1192: cIdentifiers.add(cId);
1193: aliasCount++;
1194: }
1195: return cIdentifiers;
1196: }
1197:
1198: protected String getFromStatementContent(TargetTable targetTable,
1199: StatementContext context) throws BaseException {
1200: SQLJoinView joinView = targetTable.getJoinView();
1201:
1202: if (joinView != null) {
1203: SQLJoinOperator join = joinView.getRootJoin();
1204: if (join != null) {
1205: return this .genFactory.generate(join, context);
1206: }
1207: throw new BaseException(
1208: "Cannot create FROM statement: join is null");
1209: }
1210:
1211: List sTables = targetTable.getSourceTableList();
1212: if (sTables.size() != 1) {
1213: throw new BaseException(
1214: "Cannot create FROM statement: expected 1 source table, found "
1215: + sTables.size());
1216: }
1217:
1218: return this .genFactory.generate((SQLObject) sTables.get(0),
1219: context);
1220: }
1221:
1222: protected String getFromStatementContentForTarget(
1223: TargetTable targetTable, int joinType,
1224: StatementContext context) throws BaseException {
1225: return getTargetJoinClause(targetTable, joinType, context);
1226: }
1227:
1228: /**
1229: * @param sTables
1230: * @param context
1231: * @return
1232: * @throws BaseException
1233: */
1234: protected String getSourceWhereCondition(List sTables,
1235: StatementContext context) throws BaseException {
1236: StringBuilder sourceCondition = new StringBuilder(50);
1237: Iterator it = sTables.iterator();
1238: int cnt = 0;
1239:
1240: while (it.hasNext()) {
1241: SourceTable sTable = (SourceTable) it.next();
1242: SQLCondition condition = sTable.getExtractionCondition();
1243: SQLPredicate predicate = condition.getRootPredicate();
1244:
1245: if (predicate != null
1246: && !"full".equalsIgnoreCase(sTable
1247: .getExtractionType())) {
1248: if (cnt != 0) {
1249: sourceCondition.append(" AND ");
1250: }
1251: sourceCondition.append(this .genFactory.generate(
1252: predicate, context));
1253: cnt++;
1254: }
1255: }
1256:
1257: return sourceCondition.toString();
1258: }
1259:
1260: protected String getWhereCondition(TargetTable targetTable,
1261: StatementContext context) throws BaseException {
1262: List sTables = targetTable.getSourceTableList();
1263: String conditionText = getSourceWhereCondition(sTables, context);
1264:
1265: SQLCondition filterCondition = targetTable.getFilterCondition();
1266: SQLPredicate filterPredicate = null;
1267: if (filterCondition != null) {
1268: filterPredicate = filterCondition.getRootPredicate();
1269: }
1270:
1271: if (filterPredicate != null) {
1272: String filterConditionText = this .genFactory.generate(
1273: filterPredicate, context);
1274: if (filterConditionText != null
1275: && !filterConditionText.equals("")) {
1276: if (conditionText != null && !conditionText.equals("")) {
1277: conditionText += " AND " + filterConditionText;
1278: } else {
1279: conditionText = filterConditionText;
1280: }
1281: }
1282: }
1283: return conditionText;
1284: }
1285:
1286: protected String getHavingCondition(SQLGroupBy groupBy,
1287: StatementContext context) throws BaseException {
1288: String havingCondition = null;
1289: SQLCondition condition = groupBy.getHavingCondition();
1290: SQLPredicate predicate = condition.getRootPredicate();
1291: if (predicate != null) {
1292: havingCondition = this .genFactory.generate(predicate,
1293: context);
1294: }
1295: return havingCondition;
1296: }
1297:
1298: protected String getTargetJoinClause(TargetTable targetTable,
1299: int joinType, StatementContext context)
1300: throws BaseException {
1301: String joinResult = "";
1302: SQLCondition condition = targetTable.getJoinCondition();
1303: SQLPredicate predicate = null;
1304: SQLJoinOperator join = null;
1305: if (condition != null) {
1306: predicate = condition.getRootPredicate();
1307: }
1308:
1309: if (predicate == null) {
1310: throw new BaseException("Missing merge condition.");
1311: }
1312:
1313: if (targetTable.getJoinView() != null) {
1314: join = targetTable.getJoinView().getRootJoin();
1315: }
1316:
1317: try {
1318: SQLJoinOperator operator = SQLModelObjectFactory
1319: .getInstance().createSQLJoinOperator();
1320: // This new join opearator parent object needs to be set.
1321: operator.setParentObject(SQLObjectUtil
1322: .getAncestralSQLDefinition(targetTable));
1323: operator.setJoinType(joinType);
1324: SQLCondition clonedCond = (SQLCondition) condition
1325: .cloneSQLObject();
1326:
1327: if (joinType == SQLConstants.RIGHT_OUTER_JOIN) {
1328: clonedCond.replaceTargetColumnIsNullPredicate();
1329: }
1330:
1331: operator.setJoinCondition(clonedCond);
1332:
1333: if (join != null) {
1334: // add target table condition to the join object
1335: SQLJoinOperator joinClone = (SQLJoinOperator) join
1336: .cloneSQLObject();
1337: operator.addInput(SQLJoinOperator.LEFT, targetTable);
1338: operator.addInput(SQLJoinOperator.RIGHT, joinClone);
1339:
1340: joinResult += this .genFactory.generate(operator,
1341: context);
1342: operator.removeInputByArgName(SQLJoinOperator.RIGHT,
1343: joinClone);
1344: } else {
1345: List sTables = targetTable.getSourceTableList();
1346: if (sTables.size() != 1) {
1347: throw new BaseException(
1348: "Cannot create target join statement: Expected 1 source table, found "
1349: + sTables.size());
1350: }
1351:
1352: operator.addInput(SQLJoinOperator.LEFT, targetTable);
1353: operator.addInput(SQLJoinOperator.RIGHT,
1354: (SQLObject) sTables.get(0));
1355: joinResult += this .genFactory.generate(operator,
1356: context);
1357: }
1358: } catch (CloneNotSupportedException ex) {
1359: throw new BaseException(ex);
1360: }
1361:
1362: return joinResult;
1363: }
1364:
1365: protected String getTargetWhereCondition(TargetTable targetTable,
1366: StatementContext context) throws BaseException {
1367: SQLCondition joinCondition = targetTable.getJoinCondition();
1368: String joinConditionText = "";
1369: if (joinCondition != null) {
1370: SQLPredicate joinPredicate = joinCondition
1371: .getRootPredicate();
1372:
1373: if (joinPredicate != null) {
1374: joinConditionText = this .genFactory.generate(
1375: joinPredicate, context);
1376: // throw new BaseException("Missing merge condition.");
1377: }
1378: }
1379:
1380: SQLCondition filterCondition = targetTable.getFilterCondition();
1381: if (filterCondition != null) {
1382: SQLPredicate filterPredicate = filterCondition
1383: .getRootPredicate();
1384:
1385: if (filterPredicate != null) {
1386: String filterConditionText = this .genFactory.generate(
1387: filterPredicate, context);
1388: if (filterConditionText != null
1389: && !filterConditionText.equals("")) {
1390: joinConditionText += " AND " + filterConditionText;
1391: }
1392: }
1393: }
1394: return joinConditionText;
1395: }
1396:
1397: /**
1398: * Gets table name associated with the given SQLDBTable, without qualifying
1399: * delimiters.
1400: *
1401: * @param dbTable SQLDBTable whose name is to be returned
1402: * @param context StatementContext
1403: * @return
1404: */
1405: protected String getUnqualifiedTableName(SQLDBTable dbTable,
1406: StatementContext context) {
1407: String tableName = "";
1408:
1409: if (dbTable.getObjectType() == SQLConstants.SOURCE_TABLE
1410: && context.isUsingTempTableName((SourceTable) dbTable)) {
1411: tableName = ((SourceTable) dbTable).getTemporaryTableName();
1412: } else {
1413: String userDefined = dbTable.getUserDefinedTableName();
1414: if (StringUtil.isNullString(userDefined)) {
1415: if (context.isUsingUniqueTableName()
1416: || context.isUsingUniqueTableName(dbTable)) {
1417: tableName = dbTable.getTablePrefix()
1418: + dbTable.getUniqueTableName();
1419: } else {
1420: tableName = dbTable.getTablePrefix()
1421: + dbTable.getName();
1422: }
1423: } else {
1424: tableName = dbTable.getTablePrefix() + userDefined;
1425: }
1426: }
1427:
1428: return tableName;
1429: }
1430:
1431: protected void populateContextForInsertSelect(
1432: TargetTable targetTable, StatementContext context,
1433: VelocityContext vContext) throws BaseException {
1434: StatementContext localContext = new StatementContext();
1435: if (context != null) {
1436: localContext.putAll(context);
1437: }
1438:
1439: // SET CONTEXT TO USE TARGET TABLE ALIAS NAME IN FROM CLAUSE
1440: // AND ALSO ALIAS THIS ALIAS WILL BE PREPENDED IN COLUMN NAME
1441: localContext.putClientProperty(
1442: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
1443: Boolean.TRUE);
1444:
1445: vContext.put("statementSeparator", Character
1446: .toString(SQLPart.STATEMENT_SEPARATOR));
1447: String targetTableName = this .genFactory.generate(targetTable,
1448: localContext);
1449: vContext.put("targetTable", targetTableName);
1450:
1451: //Use the Table Qualification flag to suppress column prefix
1452: localContext.setSuppressingTablePrefixForTargetColumn(true);
1453:
1454: List targetColumnIdentifiers = this .createTargetIdentifierList(
1455: targetTable, localContext);
1456: vContext
1457: .put("targetColumnIdentifiers", targetColumnIdentifiers);
1458:
1459: //START SELECT
1460: List sourceColumnIdentifiers = this .createSourceIdentifierList(
1461: targetTable, localContext);
1462: vContext
1463: .put("sourceColumnIdentifiers", sourceColumnIdentifiers);
1464: context.putClientProperty("sourceColumnIdentifiers",
1465: sourceColumnIdentifiers);
1466: vContext.put("aliasColumns", Boolean.FALSE);
1467: vContext.put("distinct", areDistinctRowsRequired(targetTable));
1468:
1469: vContext.put("selectAliasName", "");
1470: vContext.put("nestedIndent", "");
1471: //END SELECT
1472: //START WHERE
1473: vContext.put("condition", "");
1474: vContext.put("notInSql", "");
1475: vContext.put("integritySql", "");
1476:
1477: // NOTE: to build the where clauses/join conditions, allow target columns to use
1478: // table aliases
1479: localContext.putClientProperty(
1480: StatementContext.USE_TARGET_TABLE_ALIAS_NAME,
1481: Boolean.TRUE);
1482: localContext.setSuppressingTablePrefixForTargetColumn(false);
1483:
1484: // TODO: If filter has been applied already, don't apply again.
1485: String condition = getWhereCondition(targetTable, localContext);
1486: if (condition != null && !condition.equals("")) {
1487: vContext.put("useWhere", Boolean.TRUE);
1488: vContext.put("condition", condition);
1489: }
1490:
1491: String integritySql = appendSQLForIntegrityCheck(targetTable,
1492: localContext);
1493: if (integritySql != null && !integritySql.trim().equals("")) {
1494: vContext.put("useWhere", Boolean.TRUE);
1495: vContext.put("integritySql", integritySql);
1496: vContext
1497: .put("fromContent",
1498: getFromStatementContentForTarget(
1499: targetTable,
1500: SQLConstants.RIGHT_OUTER_JOIN,
1501: localContext));
1502: } else {
1503: vContext.put("fromContent", getFromStatementContent(
1504: targetTable, localContext));
1505: }
1506: //END WHERE
1507: populateContextForGroupByAndHaving(targetTable, localContext,
1508: vContext);
1509: }
1510:
1511: @SuppressWarnings(value="unchecked")
1512: protected void populateContextForUpdate(TargetTable targetTable,
1513: StatementContext context, VelocityContext vContext)
1514: throws BaseException {
1515: // Inherit settings from incoming context to allow for localized customization
1516: StatementContext localContext = new StatementContext();
1517: if (context != null) {
1518: localContext.putAll(context);
1519: }
1520:
1521: localContext.putClientProperty(
1522: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
1523: Boolean.TRUE);
1524: //localContext.putClientProperty(StatementContext.USE_TARGET_TABLE_ALIAS_NAME, Boolean.TRUE);
1525: vContext.put("statementSeparator", Character
1526: .toString(SQLPart.STATEMENT_SEPARATOR));
1527:
1528: // SELECT START
1529: final boolean excludeJoinKeyColumns = false;
1530: List rMappings = createResolvedMappings(targetTable,
1531: excludeJoinKeyColumns, localContext);
1532: List<ColumnIdentifier> selectIdentifiers = new ArrayList<ColumnIdentifier>();
1533:
1534: Iterator it = rMappings.iterator();
1535: while (it.hasNext()) {
1536: ResolvedMapping rm = (ResolvedMapping) it.next();
1537: selectIdentifiers.add(rm.getSource());
1538: selectIdentifiers.add(rm.getTarget());
1539: }
1540:
1541: List whereConditionList = (List) localContext
1542: .getClientProperty("whereList");
1543:
1544: if (whereConditionList != null) {
1545: // Will reset the conditions. Avoid duplication and prefer conditions from
1546: // DB specific JOIN generator.
1547: whereConditionList.clear();
1548: }
1549:
1550: vContext.put("sourceColumnIdentifiers", selectIdentifiers);
1551: vContext.put("aliasColumns", Boolean.TRUE);
1552: vContext.put("distinct", areDistinctRowsRequired(targetTable));
1553: vContext.put("selectAliasName", "");
1554: vContext.put("fromContent", getFromStatementContentForTarget(
1555: targetTable, SQLConstants.INNER_JOIN, localContext));
1556: vContext.put("nestedIndent", " ");
1557:
1558: vContext.put("useUpdateWhere", Boolean.FALSE);
1559:
1560: String condition = getWhereCondition(targetTable, localContext);
1561: if ((condition != null && !condition.equals(""))
1562: || (whereConditionList != null && !whereConditionList
1563: .isEmpty())) {
1564:
1565: if (whereConditionList == null
1566: || whereConditionList.isEmpty()) {
1567: whereConditionList = new ArrayList();
1568: }
1569:
1570: if ((condition != null) && (!condition.equals(""))) {
1571: whereConditionList.add(condition);
1572: }
1573:
1574: vContext.put("useUpdateWhere", Boolean.TRUE);
1575: vContext.put("conditions", whereConditionList);
1576: }
1577: //SELECT END
1578: //SET START
1579: vContext.put("mappings", rMappings);
1580: //SET END
1581: }
1582:
1583: /**
1584: * Creates appropriate table name from the given TargetTable and StatementContext
1585: * state to use in updating statistics metadata tables.
1586: *
1587: * @param table TargetTable whose reference name is to be created
1588: * @param context StatementContext to use in determing appropriate reference name
1589: * @return appropriate table name to use as a reference in statistics metadata tables.
1590: */
1591: protected String getTableNameForStatisticsMetadata(
1592: TargetTable table, StatementContext context) {
1593: String targetTableName = context.isUsingUniqueTableName() ? table
1594: .getUniqueTableName()
1595: : table.getName();
1596: return targetTableName.toUpperCase();
1597: }
1598:
1599: private void populateContextForPrepStmtInsert(SQLDBTable table,
1600: StatementContext context, VelocityContext vContext)
1601: throws BaseException {
1602: StatementContext localContext = new StatementContext();
1603: if (context != null) {
1604: localContext.putAll(context);
1605: }
1606:
1607: // Use the Table Qualification flag to suppress column prefix
1608: switch (table.getObjectType()) {
1609: case SQLConstants.SOURCE_TABLE:
1610: localContext.setSuppressingTablePrefixForSourceColumn(true);
1611: break;
1612: case SQLConstants.TARGET_TABLE:
1613: localContext.setSuppressingTablePrefixForTargetColumn(true);
1614: break;
1615: }
1616:
1617: String targetTableName = this .genFactory.generate(table,
1618: localContext);
1619: vContext.put("targetTable", targetTableName);
1620:
1621: List<ColumnIdentifier> targetColumnIdentifiers = new ArrayList<ColumnIdentifier>();
1622: List<ColumnIdentifier> prepStmtPlaceholders = new ArrayList<ColumnIdentifier>();
1623: List<String> types = new ArrayList<String>();
1624:
1625: List columns = (table instanceof TargetTable) ? ((TargetTable) table)
1626: .getMappedColumns()
1627: : table.getColumnList();
1628:
1629: Iterator it = columns.iterator();
1630: while (it.hasNext()) {
1631: SQLDBColumn column = (SQLDBColumn) it.next();
1632: if (column.isVisible()) {
1633: String sql = this .genFactory.generate(column,
1634: localContext);
1635: ColumnIdentifier cId = new ColumnIdentifier(null, sql);
1636: targetColumnIdentifiers.add(cId);
1637: prepStmtPlaceholders
1638: .add(new ColumnIdentifier(null, "?"));
1639: types.add(String.valueOf(column.getJdbcType()));
1640: }
1641: }
1642:
1643: // Put List of JDBC types for each column in given statement context.
1644: context.putClientProperty(SQLPart.ATTR_JDBC_TYPE_LIST, types);
1645:
1646: vContext
1647: .put("targetColumnIdentifiers", targetColumnIdentifiers);
1648:
1649: // VALUES - prepared statement placeholders, i.e., '?'.
1650: vContext.put("valueIdentifiers", prepStmtPlaceholders);
1651: }
1652:
1653: private void populateContextForStaticInsert(
1654: TargetTable targetTable, StatementContext context,
1655: VelocityContext vContext) throws BaseException {
1656: if (context == null) {
1657: context = new StatementContext();
1658: }
1659:
1660: String targetTableName = this .genFactory.generate(targetTable,
1661: context);
1662: vContext.put("targetTable", targetTableName);
1663:
1664: List targetColumnIdentifiers = this .createTargetIdentifierList(
1665: targetTable, context);
1666: vContext
1667: .put("targetColumnIdentifiers", targetColumnIdentifiers);
1668:
1669: // VALUES
1670: List valueIdentifiers = this .createSourceIdentifierList(
1671: targetTable, context);
1672: vContext.put("valueIdentifiers", valueIdentifiers);
1673: }
1674:
1675: /**
1676: * Populates given VelocityContext with sufficient information to generate a static
1677: * update statement for the given TargetTable, using hints from the given
1678: * StatementContext.
1679: *
1680: * @param targetTable
1681: * @param context
1682: * @param context2
1683: */
1684: protected void populateContextForStaticUpdate(
1685: TargetTable targetTable, StatementContext context,
1686: VelocityContext vContext) throws BaseException {
1687: StatementContext localContext = new StatementContext();
1688: if (context != null) {
1689: localContext.putAll(context);
1690: }
1691: localContext.setSuppressingTablePrefixForTargetColumn(true);
1692:
1693: String targetTableName = this .genFactory.generate(targetTable,
1694: localContext);
1695: vContext.put("targetTable", targetTableName);
1696:
1697: List setMappings = this .createStaticUpdateSetList(targetTable,
1698: localContext);
1699: vContext.put("setMappings", setMappings);
1700:
1701: String condition = getTargetWhereCondition(targetTable,
1702: localContext);
1703: if (condition != null && !condition.trim().equals("")) {
1704: vContext.put("condition", condition);
1705: vContext.put("nestedIndent", "");
1706: vContext.put("whereClause", TemplateBuilder.generateSql(
1707: this .db.getTemplateFileName("where"), vContext)); // NOI18N
1708: vContext.put("useWhere", Boolean.TRUE);
1709: }
1710: }
1711:
1712: /**
1713: * Creates List of UpdateSetMapping instances, each of which represents a mapping of a
1714: * target column to an expression (SQL function, or pseudo-column.)
1715: *
1716: * @param targetTable
1717: * @param context
1718: * @return
1719: */
1720: private List<UpdateSetMapping> createStaticUpdateSetList(
1721: TargetTable targetTable, StatementContext context)
1722: throws BaseException {
1723: List mappedList = targetTable.getMappedColumns();
1724: if (mappedList.size() == 0) {
1725: throw new BaseException(
1726: "Must have at least one column mapped to a literal, source column, or operator.");
1727: }
1728:
1729: List<UpdateSetMapping> mappings = new ArrayList<UpdateSetMapping>(
1730: mappedList.size());
1731: int aliasCount = 1;
1732:
1733: Iterator it = mappedList.iterator();
1734: while (it.hasNext()) {
1735: TargetColumn column = (TargetColumn) it.next();
1736: String sql = this .genFactory.generate(column, context);
1737: ColumnIdentifier cId = new ColumnIdentifier(
1738: TARGET_COLUMN_IDENTIFIER_ALIAS_PREFIX + aliasCount,
1739: sql);
1740: String expression = this .genFactory.generate(column
1741: .getValue(), context);
1742:
1743: mappings.add(new UpdateSetMapping(cId, expression));
1744: aliasCount++;
1745: }
1746:
1747: return mappings;
1748: }
1749:
1750: /**
1751: * Apart from returning Source columns in the condition but not in the list., will also set context
1752: * with JDBC type for these missing columns.
1753: * @param condition
1754: * @param origList
1755: * @param context
1756: * @return
1757: */
1758: @SuppressWarnings(value="unchecked")
1759: protected List getConditionColumnsNotInList(SQLCondition condition,
1760: List origList, StatementContext context) {
1761: int jdbcType = -1;
1762: Object obj = null;
1763:
1764: if (context == null) {
1765: context = new StatementContext();
1766: }
1767: List jdbcTypeList = (List) context
1768: .getClientProperty(SQLPart.ATTR_JDBC_TYPE_LIST);
1769: List columnsInCondition = condition.getParticipatingColumns();
1770: List columnsNotInList = new ArrayList();
1771:
1772: if (jdbcTypeList == null) {
1773: jdbcTypeList = new ArrayList();
1774: }
1775:
1776: if (columnsInCondition != null) {
1777: Iterator itr = columnsInCondition.iterator();
1778: while (itr.hasNext()) {
1779: obj = itr.next();
1780: if (obj instanceof SourceColumn) {
1781: if (!origList.contains(obj)) {
1782: columnsNotInList.add(obj);
1783: jdbcType = ((SourceColumn) obj).getJdbcType();
1784: jdbcTypeList.add("" + jdbcType);
1785: }
1786: }
1787: }
1788: }
1789:
1790: context.putClientProperty(SQLPart.ATTR_JDBC_TYPE_LIST,
1791: jdbcTypeList);
1792: return columnsNotInList;
1793: }
1794:
1795: protected List getConditionColumnsNotInList(SQLCondition condition,
1796: List origList) {
1797: return getConditionColumnsNotInList(condition, origList,
1798: (StatementContext) null);
1799: }
1800:
1801: protected List<ColumnIdentifier> createColumnIdentifiersFromSourceColumns(
1802: List columnTobeAliased, StatementContext context,
1803: int startIndex) throws BaseException {
1804: return createColumnIdentifiersFromSourceColumns(
1805: columnTobeAliased, context, startIndex,
1806: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX);
1807: }
1808:
1809: protected List<ColumnIdentifier> createColumnIdentifiersFromSourceColumns(
1810: List columnTobeAliased, StatementContext context,
1811: int startIndex, String aliasPrefix) throws BaseException {
1812: List<ColumnIdentifier> colIdentifier = new ArrayList<ColumnIdentifier>();
1813: if ((columnTobeAliased != null)
1814: && (columnTobeAliased.size() > 0)) {
1815:
1816: Iterator itr = columnTobeAliased.iterator();
1817: while (itr.hasNext()) {
1818: SourceColumn sc = (SourceColumn) itr.next();
1819: String sql = this .genFactory.generate(sc, context);
1820: ColumnIdentifier cId = new ColumnIdentifier(aliasPrefix
1821: + startIndex, sql);
1822: colIdentifier.add(cId);
1823: startIndex++;
1824: }
1825: }
1826: return colIdentifier;
1827: }
1828:
1829: protected List<ColumnIdentifier> getColIdsFromRM(
1830: List<ResolvedMapping> rmList) throws BaseException {
1831: Iterator it1 = rmList.iterator();
1832: List<ColumnIdentifier> colIds = new ArrayList<ColumnIdentifier>();
1833: while (it1.hasNext()) {
1834: ColumnIdentifier cId = ((ResolvedMapping) it1.next())
1835: .getSource();
1836: colIds.add(cId);
1837: }
1838: return colIds;
1839: }
1840:
1841: protected String replaceColumnNamesWithAliases(List colIdentifier,
1842: String sql) throws BaseException {
1843: if ((colIdentifier != null) && (colIdentifier.size() > 0)) {
1844: List<String> columnSqlList = new ArrayList<String>();
1845: List<String> aliasList = new ArrayList<String>();
1846:
1847: Iterator iter = colIdentifier.iterator();
1848: while (iter.hasNext()) {
1849: ColumnIdentifier cId = (ColumnIdentifier) iter.next();
1850: if (!cId.isExpression()) {
1851: columnSqlList.add(cId.getSql());
1852: aliasList.add(cId.getAliasName());
1853: }
1854: }
1855:
1856: String[] columnSqls = new String[0];
1857: columnSqls = columnSqlList.toArray(columnSqls);
1858: String[] aliases = new String[0];
1859: aliases = aliasList.toArray(aliases);
1860: sql = StringUtil.replaceInString(sql, columnSqls, aliases);
1861: }
1862:
1863: return sql;
1864: }
1865:
1866: /**
1867: * Helper class to associate a ColumnIdentifier with a String expression, for use in
1868: * generating column-value mappings for the set clause of an update statement.
1869: *
1870: * @author Jonathan Giron
1871: * @version $Revision$
1872: */
1873: public static class UpdateSetMapping {
1874:
1875: private ColumnIdentifier cId;
1876: private String exp;
1877:
1878: public UpdateSetMapping(ColumnIdentifier columnId,
1879: String expression) {
1880: cId = columnId;
1881: exp = expression;
1882: }
1883:
1884: public String getAlias() {
1885: return cId.getAliasName();
1886: }
1887:
1888: public String getColumnName() {
1889: return cId.getSql();
1890: }
1891:
1892: public String getExpression() {
1893: return exp;
1894: }
1895: }
1896: }
|