001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.sql.framework.codegen.axion;
020:
021: import java.util.ArrayList;
022: import java.util.Collections;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.apache.velocity.VelocityContext;
027: import org.netbeans.modules.sql.framework.common.jdbc.SQLDBConnectionDefinition;
028: import org.netbeans.modules.sql.framework.common.jdbc.SQLUtils;
029: import org.netbeans.modules.sql.framework.common.utils.MonitorUtil;
030: import org.netbeans.modules.sql.framework.codegen.AbstractDB;
031: import org.netbeans.modules.sql.framework.codegen.ColumnIdentifier;
032: import org.netbeans.modules.sql.framework.codegen.ResolvedMapping;
033: import org.netbeans.modules.sql.framework.codegen.StatementContext;
034: import org.netbeans.modules.sql.framework.codegen.TemplateBuilder;
035: import org.netbeans.modules.sql.framework.codegen.base.BaseStatements;
036: import org.netbeans.modules.sql.framework.model.SQLCondition;
037: import org.netbeans.modules.sql.framework.model.SQLConstants;
038: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
039: import org.netbeans.modules.sql.framework.model.SQLDBTable;
040: import org.netbeans.modules.sql.framework.model.SQLPredicate;
041: import org.netbeans.modules.sql.framework.model.SourceTable;
042: import org.netbeans.modules.sql.framework.model.TargetColumn;
043: import org.netbeans.modules.sql.framework.model.TargetTable;
044:
045: import com.sun.sql.framework.exception.BaseException;
046: import com.sun.sql.framework.jdbc.DBConnectionFactory;
047: import com.sun.sql.framework.jdbc.DBConstants;
048: import com.sun.sql.framework.jdbc.SQLPart;
049: import com.sun.sql.framework.utils.ScEncrypt;
050: import com.sun.sql.framework.utils.StringUtil;
051: import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
052:
053: /**
054: * @author Jonathan Giron
055: * @author Ritesh Adval
056: * @version $Revision$
057: */
058: public class AxionStatements extends BaseStatements {
059:
060: protected MonitorUtil mUtil = new MonitorUtil();
061:
062: public AxionStatements(AbstractDB database) {
063: super (database);
064: }
065:
066: public SQLPart getDefragStatement(SQLDBTable table,
067: StatementContext context) throws BaseException {
068: String tableName = this .genFactory.generate(table, context);
069: VelocityContext vContext = new VelocityContext();
070: vContext.put("tableName", tableName); // NOI18N
071: String defragStatement = TemplateBuilder.generateSql(this .db
072: .getTemplateFileName("defrag"), vContext); // NOI18N
073: return createSQLPart(defragStatement, SQLPart.STMT_DEFRAG);
074: }
075:
076: protected void populateContextForInsertSelect(
077: TargetTable targetTable, StatementContext context,
078: VelocityContext vContext) throws BaseException {
079: super .populateContextForInsertSelect(targetTable, context,
080: vContext);
081:
082: StatementContext localContext = new StatementContext();
083: localContext.putAll(context);
084:
085: vContext.put("nestedIndent", "");
086: vContext.put("validationCondition", "");
087: vContext.put("errorColumnIdentifiers", Collections.EMPTY_LIST);
088: vContext.put("errorValueIdentifiers", Collections.EMPTY_LIST);
089: vContext.put("errorLogTable", getDetailsTableName(targetTable));
090: vContext.put("aliasErrorColumns", Boolean.FALSE);
091: vContext.put("aliasErrorValues", Boolean.TRUE);
092: vContext.put("aliasTargetValues", Boolean.TRUE);
093: vContext.put("aliasColumns", Boolean.TRUE);
094:
095: String validationClause = createValidationConditionClause(
096: targetTable, localContext);
097: if (!StringUtil.isNullString(validationClause)) {
098: vContext.put("sourceColumnIdentifiers", localContext
099: .getClientProperty("sourceColumnIdentifiers"));
100: vContext.put("validationCondition", validationClause);
101: vContext.put("conditionQualifier", "FIRST");
102: vContext.put("aliasColumns", Boolean.TRUE);
103:
104: localContext.setSuppressingTablePrefixForTargetColumn(true);
105: localContext.putClientProperty("nestedIndent", " ");
106:
107: vContext.put("targetValueIdentifiers",
108: createTargetValueIdentifierList(targetTable,
109: localContext));
110: vContext.put("errorColumnIdentifiers",
111: createErrorColumnIdentifierList(targetTable,
112: localContext));
113: vContext.put("errorValueIdentifiers",
114: createErrorValueIdentifierList(targetTable,
115: localContext));
116: }
117: }
118:
119: protected void populateContextForUpdate(TargetTable targetTable,
120: StatementContext context, VelocityContext vContext)
121: throws BaseException {
122: // SELECT START
123: StatementContext localContext = new StatementContext();
124: if (context != null) {
125: localContext.putAll(context);
126: }
127:
128: final boolean excludeJoinKeyColumns = false;
129:
130: //Use the Table Qualification flag to suppress column prefix
131: localContext.setSuppressingTablePrefixForTargetColumn(true);
132: List rMappings = createResolvedMappingsForUpdate(targetTable,
133: excludeJoinKeyColumns, localContext);
134: localContext.setSuppressingTablePrefixForTargetColumn(false);
135:
136: String targetTableSql = this .genFactory.generate(targetTable,
137: localContext);
138:
139: localContext.putClientProperty(
140: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
141: Boolean.TRUE);
142: localContext.putClientProperty(
143: StatementContext.USE_TARGET_TABLE_ALIAS_NAME,
144: Boolean.TRUE);
145:
146: vContext.put("targetTable", targetTableSql);
147: // TODO: In new update syntax in axion we need to support DISTINCT
148: // old way DISTINCT was part of SELECT but in new syntax we need to
149: // account for it.
150:
151: vContext.put("fromContent", getFromStatementContentForTarget(
152: targetTable, SQLConstants.INNER_JOIN, localContext));
153: vContext.put("nestedIndent", " ");
154:
155: vContext.put("useUpdateWhere", Boolean.FALSE);
156:
157: String condition = getWhereCondition(targetTable, localContext);
158: String updateWhereClause = getWhereClauseForUpdate(targetTable,
159: context);
160: if (condition != null && !condition.equals("")) {
161: condition += " AND " + updateWhereClause;
162: } else {
163: condition = updateWhereClause;
164: }
165:
166: if (condition != null && !condition.equals("")) {
167: vContext.put("useUpdateWhere", Boolean.TRUE);
168: vContext.put("condition", condition);
169: }
170: // SELECT END
171:
172: vContext.put("mappings", rMappings);
173:
174: // exception when
175: localContext.putClientProperty("nestedIndent", "");
176: localContext.putClientProperty("errorLogTable",
177: getDetailsTableName(targetTable));
178: localContext.putClientProperty("errorColumnIdentifiers",
179: vContext.get("targetColumnIdentifiers"));
180: localContext.putClientProperty("valueIdentifiers", vContext
181: .get("sourceColumnIdentifiers"));
182:
183: vContext.put("exceptionWhen",
184: getValidationExceptionWhenClauseForUpdate(targetTable,
185: localContext));
186: }
187:
188: public List createResolvedMappingsForUpdate(
189: TargetTable targetTable, boolean excludeKeyColumns,
190: StatementContext context) throws BaseException {
191: ArrayList mappings = new ArrayList();
192: String targetJoin = getTargetJoinClause(targetTable,
193: SQLConstants.INNER_JOIN, context);
194:
195: StatementContext localContext = new StatementContext();
196: localContext.putAll(context);
197: localContext.putClientProperty(
198: StatementContext.USE_SOURCE_TABLE_ALIAS_NAME,
199: Boolean.TRUE);
200:
201: Iterator it = targetTable.getMappedColumns().iterator();
202: int aliasCount = 1;
203:
204: while (it.hasNext()) {
205: TargetColumn column = (TargetColumn) it.next();
206: if (column.getValue() != null) {
207: String tSql = this .genFactory.generate(column, context);
208: if (targetJoin.indexOf(tSql) != -1 && excludeKeyColumns) {
209: continue;
210: }
211:
212: String sSql = this .genFactory.generate(column
213: .getValue(), localContext);
214:
215: ColumnIdentifier sId = new ColumnIdentifier(null, sSql);
216: ColumnIdentifier tId = new ColumnIdentifier(null, tSql);
217: ResolvedMapping rm = new ResolvedMapping(sId, tId);
218: mappings.add(rm);
219: aliasCount++;
220: }
221: }
222:
223: return mappings;
224: }
225:
226: private String getWhereClauseForUpdate(TargetTable targetTable,
227: StatementContext context) throws BaseException {
228: SQLCondition joinCondition = targetTable.getJoinCondition();
229: SQLPredicate joinPredicate = null;
230: if (joinCondition != null) {
231: joinPredicate = joinCondition.getRootPredicate();
232: }
233:
234: if (joinPredicate == null) {
235: throw new BaseException("Missing merge condition.");
236: }
237: return this .genFactory.generate(joinPredicate, context);
238: }
239:
240: public SQLPart getMergeStatement(TargetTable targetTable,
241: StatementContext context) throws BaseException {
242: if (context == null) {
243: context = new StatementContext();
244: }
245:
246: VelocityContext vContext = new VelocityContext();
247: StatementContext localContext = new StatementContext();
248: localContext.putAll(context);
249: localContext.putClientProperty(
250: StatementContext.USE_TARGET_TABLE_ALIAS_NAME,
251: Boolean.TRUE);
252: localContext.putClientProperty("nestedIndent", "");
253:
254: populateAnsiMergeStatement(targetTable, localContext, vContext);
255:
256: localContext.putClientProperty("errorLogTable",
257: getDetailsTableName(targetTable));
258: localContext.setUseSourceColumnAliasName(true);
259: vContext.put("nestedIndent", "");
260: vContext.put("validationCondition",
261: createValidationConditionClause(targetTable,
262: localContext));
263: vContext.put("exceptionDML", getErrorLoggingDML(targetTable,
264: localContext));
265: vContext
266: .put("exceptionWhen", TemplateBuilder.generateSql(
267: this .db.getTemplateFileName("exceptionWhen"),
268: vContext));
269:
270: String result = TemplateBuilder.generateSql(this .db
271: .getTemplateFileName("merge"), vContext); // NOI18N
272: return createSQLPart(result, SQLPart.STMT_MERGE); // NOI18N
273: }
274:
275: /**
276: * Creates a DB link creation statement based on the connection information in the
277: * given DBConnectionDefinition.
278: *
279: * @param def DBConnectionDefinition containing connection information to be
280: * incorporated into the new DB link statement
281: * @param linkName unique name of link
282: * @return SQLPart containing create DB link statement
283: * @throws BaseException if error occurs during statement generation
284: */
285: public SQLPart getCreateDBLinkStatement(DBConnectionDefinition def,
286: String linkName) throws BaseException {
287: VelocityContext vContext = new VelocityContext();
288: vContext.put("linkName", this .db.getEscapedName(linkName));
289: vContext.put("jdbcDriver", def.getDriverClass());
290: vContext.put("jdbcUrl", def.getConnectionURL());
291:
292: final String userName = def.getUserName();
293: String encryptedPassword = ScEncrypt.encrypt(userName, def
294: .getPassword());
295: vContext.put("userName", userName);
296: vContext.put("password", encryptedPassword);
297: vContext.put("otherProperties", "");
298:
299: String result = TemplateBuilder.generateSql(this .db
300: .getTemplateFileName("createDbLink"), vContext);
301: return createSQLPart(result, SQLPart.STMT_CREATEDBLINK);
302: }
303:
304: /**
305: * Creates an external DB table with the given local name, based on the given
306: * SQLDBTable and associated with the DB link with the given name.
307: *
308: * @param table SQLDBTable containing metadata for the external DB table to be created
309: * @param axionTableName local name to be used in referencing the external DB table;
310: * if null, the table name embedded in <code>table</code> is used
311: * @param linkName name of DB link to use in resolving connections to
312: * <code>table</code>
313: * @return SQLPart containing generated create statement
314: * @throws BaseException if error occurs during statement generation
315: */
316: public SQLPart getCreateRemoteTableStatement(SQLDBTable table,
317: String axionTableName, String linkName)
318: throws BaseException {
319: StringBuilder sqlBuf = new StringBuilder(100);
320: StatementContext context = new StatementContext();
321: VelocityContext vContext = new VelocityContext();
322:
323: context.setUsingFullyQualifiedTablePrefix(false);
324:
325: final String userDefinedTable = table.getUserDefinedTableName();
326: try {
327: DBConnectionDefinition connDef = table.getParent()
328: .getConnectionDefinition();
329: int dbType = SQLUtils.getSupportedDBType(connDef
330: .getDBType());
331:
332: String catalogName = "";
333: String schemaName = "";
334: if (table.isUsingFullyQualifiedName()) {
335: // Ensure order of precedence for catalog name is followed.
336: catalogName = table.getUserDefinedCatalogName();
337: if (StringUtil.isNullString(catalogName)) {
338: catalogName = table.getCatalog();
339: }
340:
341: // Ensure order of precedence for schema name is followed.
342: schemaName = table.getUserDefinedSchemaName();
343: if (StringUtil.isNullString(schemaName)) {
344: schemaName = table.getSchema();
345: }
346: }
347:
348: String tableName = table.getUserDefinedTableName();
349: if (StringUtil.isNullString(tableName)) {
350: tableName = table.getName();
351: }
352:
353: String tablePrefix = table.getTablePrefix();
354: if (StringUtil.isNullString(tablePrefix)) {
355: tableName = tablePrefix + tableName;
356: }
357:
358: vContext
359: .put("linkName", this .db.getUnescapedName(linkName));
360: vContext.put("remoteName", tableName);
361: vContext.put("ifNotExists", Boolean.FALSE);
362: vContext.put("orderBy", "");
363: vContext.put("where", "");
364: vContext.put("schemaName", schemaName);
365: vContext.put("catalogName", catalogName);
366:
367: if ((table instanceof TargetTable)
368: && (((TargetTable) table).isCreateTargetTable())
369: && (dbType != DBConstants.AXION)) {
370: vContext.put("createIfNotExist", Boolean.TRUE);
371: }
372:
373: if (dbType == DBConstants.AXION) {
374: vContext.put("vendor", "AXION");
375: }
376:
377: boolean columnsAreCaseSensitive = (dbType == DBConstants.SYBASE);
378: vContext.put("columnsAreCaseSensitive", new Boolean(
379: columnsAreCaseSensitive));
380: ((AxionDB) db)
381: .setColumnsAreCaseSensitive(columnsAreCaseSensitive);
382:
383: table.setUserDefinedTableName(axionTableName);
384: String rTableName = this .genFactory
385: .generate(table, context);
386: vContext.put("tableName", rTableName);
387:
388: List cIdentifiers = new ArrayList();
389: List nullableIdentifiers = new ArrayList();
390: StringBuilder columnBuf = new StringBuilder(50);
391:
392: List columns = (ArrayList) table.getColumnList();
393: for (int i = 0; i < columns.size(); i++) {
394: // Should be part of expression/type Generator.
395: SQLDBColumn column = (SQLDBColumn) columns.get(i);
396: String name = db.getEscapedName(column.getName());
397:
398: int jdbcTypeInt = column.getJdbcType();
399: int precision = column.getPrecision();
400: int scale = column.getScale();
401:
402: columnBuf.setLength(0);
403: columnBuf.append(name).append(" ").append(
404: this .db.getTypeGenerator().generate(
405: jdbcTypeInt, precision, scale));
406:
407: cIdentifiers.add(new ColumnIdentifier(null, columnBuf
408: .toString()));
409: nullableIdentifiers.add(Boolean.valueOf(column
410: .isNullable()));
411: }
412:
413: vContext.put("sourceColumnIdentifiers", cIdentifiers);
414: vContext.put("nullables", nullableIdentifiers);
415:
416: // Don't declare primary key columns for external tables.
417: vContext.put("pkIdentifiers", Collections.EMPTY_LIST);
418:
419: sqlBuf.append(TemplateBuilder.generateSql(this .db
420: .getTemplateFileName("createRemote"), vContext));
421: } finally {
422: table.setUserDefinedTableName(userDefinedTable);
423: }
424:
425: return createSQLPart(sqlBuf.toString(),
426: SQLPart.STMT_CREATEEXTERNAL);
427: }
428:
429: /**
430: * @param table
431: * @param logTableName
432: * @return
433: */
434: public SQLPart getCreateFlatfileTableStatement(SQLDBTable table,
435: String orgPropertiesList, boolean ifNotExists)
436: throws BaseException {
437: StringBuilder sqlBuf = new StringBuilder(100);
438: StatementContext context = new StatementContext();
439: VelocityContext vContext = new VelocityContext();
440:
441: context.setUsingFullyQualifiedTablePrefix(false);
442: List cIdentifiers = new ArrayList();
443: List nullableIdentifiers = new ArrayList();
444: StringBuilder columnBuf = new StringBuilder(50);
445:
446: List columns = table.getColumnList();
447: for (int i = 0; i < columns.size(); i++) {
448: // should be part of expression/type Generator.
449: SQLDBColumn column = (SQLDBColumn) columns.get(i);
450: String name = db.getEscapedName(column.getName());
451:
452: int jdbcTypeInt = column.getJdbcType();
453: int precision = column.getPrecision();
454: int scale = column.getScale();
455:
456: columnBuf.setLength(0);
457: columnBuf.append(name).append(" ").append(
458: this .db.getTypeGenerator().generate(jdbcTypeInt,
459: precision, scale));
460:
461: cIdentifiers.add(new ColumnIdentifier(null, columnBuf
462: .toString()));
463: nullableIdentifiers.add(Boolean
464: .valueOf(column.isNullable()));
465: }
466:
467: vContext.put("sourceColumnIdentifiers", cIdentifiers);
468: vContext.put("nullables", nullableIdentifiers);
469: vContext.put("pkIdentifiers", Collections.EMPTY_LIST);
470: vContext.put("ifNotExists", Boolean.valueOf(ifNotExists));
471:
472: if (StringUtil.isNullString(orgPropertiesList)) {
473: orgPropertiesList = "";
474: }
475: vContext.put("orgProperties", orgPropertiesList);
476:
477: sqlBuf.append(TemplateBuilder.generateSql(this .db
478: .getTemplateFileName("createExternal"), vContext));
479:
480: return createSQLPart(sqlBuf.toString(),
481: SQLPart.STMT_CREATEFLATFILE);
482: }
483:
484: /**
485: * @param linkName
486: * @return
487: */
488: public SQLPart getDropDBLinkStatement(String linkName)
489: throws BaseException {
490: VelocityContext vContext = new VelocityContext();
491: vContext.put("linkName", linkName);
492:
493: String sql = TemplateBuilder.generateSql(this .db
494: .getTemplateFileName("dropDbLink"), vContext);
495: return createSQLPart(sql, SQLPart.STMT_DROPDBLINK);
496: }
497:
498: /**
499: * @param table
500: * @return
501: */
502: public SQLPart getDropExternalTableStatement(SQLDBTable table,
503: String axionTableName, boolean ifExists,
504: StatementContext context) throws BaseException {
505: StatementContext localContext = new StatementContext();
506: if (context != null) {
507: localContext.putAll(context);
508: }
509: context.setUsingFullyQualifiedTablePrefix(false);
510: context
511: .putClientProperty("ifExists", Boolean
512: .valueOf(ifExists));
513:
514: final String userDefinedTable = table.getUserDefinedTableName();
515: try {
516: table.setUserDefinedTableName(axionTableName);
517: return getDropStatement(table, context);
518: } finally {
519: table.setUserDefinedTableName(userDefinedTable);
520: }
521: }
522:
523: public String getValidationExceptionWhenClauseForUpdate(
524: TargetTable target, StatementContext context)
525: throws BaseException {
526: VelocityContext vContext = new VelocityContext();
527:
528: String indent = (String) context
529: .getClientProperty("nestedIndent");
530: vContext
531: .put("nestedIndent", (indent != null) ? indent : " ");
532: vContext.put("validationCondition",
533: createValidationConditionClauseForUpdate(target,
534: context));
535:
536: StatementContext localContext = new StatementContext();
537: localContext.putAll(context);
538: localContext.putClientProperty("errorLogTable",
539: getDetailsTableName(target));
540: localContext.putClientProperty("nestedIndent", indent + " ");
541: vContext.put("exceptionDML", getErrorLoggingDML(target,
542: localContext));
543:
544: return TemplateBuilder.generateSql(this .db
545: .getTemplateFileName("exceptionWhen"), vContext);
546: }
547:
548: /**
549: * @param targetTable
550: * @param context
551: * @return
552: * @throws BaseException
553: */
554: protected String createValidationConditionClause(
555: TargetTable targetTable, StatementContext context)
556: throws BaseException {
557: StatementContext localContext = new StatementContext();
558: localContext.putAll(context);
559: localContext.setUseSourceTableAliasName(true);
560: localContext.setUseSourceColumnAliasName(true);
561: String srcColAliasPrefix = (String) context
562: .getClientProperty("mergeConditionSourceColumnAliasPrefix");
563: List sourceColumnIdentifiers = (List) context
564: .getClientProperty("sourceColumnIdentifiers");
565: List mergeCondColumnIdentifiers = (List) context
566: .getClientProperty("mergeConditionColumnIdentifiers");
567: int lastSourceColumnAliasIndex = 0;
568:
569: if ((sourceColumnIdentifiers == null)
570: || (sourceColumnIdentifiers.size() <= 0)) {
571: // Create mapping between source column identifiers and their aliases.
572: sourceColumnIdentifiers = createSourceIdentifierList(
573: targetTable, localContext);
574: context.putClientProperty("sourceColumnIdentifiers",
575: sourceColumnIdentifiers);
576: }
577:
578: if ((mergeCondColumnIdentifiers == null)
579: || (mergeCondColumnIdentifiers.size() <= 0)) {
580: mergeCondColumnIdentifiers = new ArrayList();
581: mergeCondColumnIdentifiers.addAll(sourceColumnIdentifiers);
582: }
583:
584: if (context.getClientProperty("lastSourceAliasIndex") != null) {
585: lastSourceColumnAliasIndex = ((Integer) context
586: .getClientProperty("lastSourceAliasIndex"))
587: .intValue();
588: } else {
589: lastSourceColumnAliasIndex = sourceColumnIdentifiers.size();
590: }
591:
592: List srcColumnsMappedToTarget = getSourceColsDirectlyMapped(targetTable);
593:
594: StringBuilder exceptionBuf = new StringBuilder(100);
595:
596: int i = 0;
597: Iterator srcIter = targetTable.getSourceTableList().iterator();
598: while (srcIter.hasNext()) {
599: SourceTable srcTable = (SourceTable) srcIter.next();
600: SQLCondition condition = srcTable
601: .getDataValidationCondition();
602: if (condition != null) {
603: SQLPredicate predicate = condition.getRootPredicate();
604: if (predicate != null) {
605: String conditionSql = this .db
606: .createGeneratorFactory().generate(
607: predicate, localContext);
608: if (conditionSql != null) {
609: if (i++ != 0) {
610: exceptionBuf.append(" AND ");
611: }
612:
613: //Validation conditions operate on one Source table at a time.
614: List columnsTobeAliased = getConditionColumnsNotInList(
615: condition, srcColumnsMappedToTarget);
616: List missingCondColIdentifiers = null;
617: List missingSrcColIdentifiers = null;
618: if ((srcColAliasPrefix != null)
619: && !"".equals(srcColAliasPrefix)) {
620: missingCondColIdentifiers = createColumnIdentifiersFromSourceColumns(
621: columnsTobeAliased,
622: localContext,
623: lastSourceColumnAliasIndex + 1,
624: srcColAliasPrefix
625: + "."
626: + SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX);
627:
628: } else {
629: missingCondColIdentifiers = createColumnIdentifiersFromSourceColumns(
630: columnsTobeAliased, localContext,
631: lastSourceColumnAliasIndex + 1);
632: }
633: missingSrcColIdentifiers = createColumnIdentifiersFromSourceColumns(
634: columnsTobeAliased, localContext,
635: lastSourceColumnAliasIndex + 1);
636:
637: sourceColumnIdentifiers
638: .addAll(missingSrcColIdentifiers);
639: mergeCondColumnIdentifiers
640: .addAll(missingCondColIdentifiers);
641: conditionSql = replaceColumnNamesWithAliases(
642: mergeCondColumnIdentifiers,
643: conditionSql);
644: exceptionBuf.append(conditionSql);
645: }
646: }
647: }
648: }
649:
650: return exceptionBuf.toString();
651: }
652:
653: /**
654: * @param targetTable
655: * @param context
656: * @return
657: * @throws BaseException
658: */
659: protected String createValidationConditionClauseForUpdate(
660: TargetTable targetTable, StatementContext context)
661: throws BaseException {
662: StatementContext localContext = new StatementContext();
663: localContext.putAll(context);
664: localContext.setUseSourceTableAliasName(true);
665:
666: StringBuilder exceptionBuf = new StringBuilder(100);
667:
668: int i = 0;
669: Iterator srcIter = targetTable.getSourceTableList().iterator();
670: while (srcIter.hasNext()) {
671: SourceTable srcTable = (SourceTable) srcIter.next();
672: SQLCondition condition = srcTable
673: .getDataValidationCondition();
674: if (condition != null) {
675: SQLPredicate predicate = condition.getRootPredicate();
676: if (predicate != null) {
677: String conditionSql = this .db
678: .createGeneratorFactory().generate(
679: predicate, localContext);
680: if (conditionSql != null) {
681: if (i++ != 0) {
682: exceptionBuf.append(" AND ");
683: }
684: exceptionBuf.append(conditionSql);
685: }
686: }
687: }
688: }
689:
690: return exceptionBuf.toString();
691: }
692:
693: /**
694: * @param target
695: * @param context
696: * @return
697: */
698: protected String getErrorLoggingDML(TargetTable target,
699: StatementContext context) throws BaseException {
700: VelocityContext vContext = new VelocityContext();
701: populateContextForErrorLoggingDML(target, context, vContext);
702: return TemplateBuilder.generateSql(this .db
703: .getTemplateFileName("logError"), vContext);
704: }
705:
706: protected void populateContextForErrorLoggingDML(
707: TargetTable target, StatementContext context,
708: VelocityContext vContext) throws BaseException {
709: StatementContext localContext = new StatementContext();
710: localContext.putAll(context);
711:
712: localContext.setSuppressingTablePrefixForTargetColumn(true);
713: localContext.setUseSourceTableAliasName(true);
714: localContext.setUseTargetTableAliasName(true);
715:
716: String indent = (String) localContext
717: .getClientProperty("nestedIndent");
718:
719: vContext.put("errorLogTable", localContext
720: .getClientProperty("errorLogTable"));
721: Object obj = context
722: .getClientProperty("errorColumnIdentifiers");
723: if (obj instanceof List) {
724: vContext.put("errorColumnIdentifiers", obj);
725: } else {
726: vContext.put("errorColumnIdentifiers",
727: createErrorColumnIdentifierList(target,
728: localContext));
729: }
730:
731: obj = context.getClientProperty("errorValueIdentifiers");
732: if (obj instanceof List) {
733: vContext.put("errorValueIdentifiers", obj);
734: } else {
735: vContext
736: .put("errorValueIdentifiers",
737: createErrorValueIdentifierList(target,
738: localContext));
739: }
740:
741: vContext.put("aliasErrorValues", localContext
742: .isUseSourceColumnAliasName() ? Boolean.TRUE
743: : Boolean.FALSE);
744: vContext.put("aliasErrorColumns", localContext
745: .isUseTargetColumnAliasName() ? Boolean.TRUE
746: : Boolean.FALSE);
747:
748: vContext.put("nestedIndent", (indent != null) ? indent : "");
749: }
750:
751: private List createErrorColumnIdentifierList(
752: TargetTable targetTable, StatementContext context)
753: throws BaseException {
754: List cIdentifiers = new ArrayList();
755:
756: Iterator it = targetTable.getMappedColumns().iterator();
757: int aliasCount = 1;
758:
759: while (it.hasNext()) {
760: TargetColumn column = (TargetColumn) it.next();
761: String sql = this .genFactory.generate(column, context);
762: ColumnIdentifier cId = new ColumnIdentifier(
763: TARGET_COLUMN_IDENTIFIER_ALIAS_PREFIX + aliasCount,
764: sql);
765: cIdentifiers.add(cId);
766: aliasCount++;
767: }
768:
769: return cIdentifiers;
770: }
771:
772: protected List createErrorValueIdentifierList(
773: TargetTable targetTable, StatementContext context)
774: throws BaseException {
775: List cIdentifiers = new ArrayList();
776: Iterator it = targetTable.getMappedColumns().iterator();
777: int aliasCount = 1;
778:
779: while (it.hasNext()) {
780: TargetColumn column = (TargetColumn) it.next();
781: if (column.getValue() != null) {
782: String sql = this .genFactory.generate(
783: column.getValue(), context);
784: ColumnIdentifier cId = new ColumnIdentifier(
785: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX
786: + aliasCount, sql);
787: cIdentifiers.add(cId);
788: aliasCount++;
789: }
790: }
791:
792: return cIdentifiers;
793: }
794:
795: protected List createTargetValueIdentifierList(
796: TargetTable targetTable, StatementContext context)
797: throws BaseException {
798: List cIdentifiers = new ArrayList();
799:
800: Iterator it = targetTable.getMappedColumns().iterator();
801: int aliasCount = 1;
802:
803: while (it.hasNext()) {
804: TargetColumn column = (TargetColumn) it.next();
805: if (column.getValue() != null) {
806: String sql = this .genFactory.generate(
807: column.getValue(), context);
808: ColumnIdentifier cId = new ColumnIdentifier(
809: SOURCE_COLUMN_IDENTIFIER_ALIAS_PREFIX
810: + aliasCount, sql);
811: cIdentifiers.add(cId);
812: aliasCount++;
813: }
814: }
815:
816: return cIdentifiers;
817: }
818:
819: protected String getDetailsTableName(TargetTable table) {
820: return MonitorUtil.getDetailsTableName(table);
821: }
822: }
|