0001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
0002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
0003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
0005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
0006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
0008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
0011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
0012: // POSSIBILITY OF SUCH DAMAGE.
0013: //
0014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
0015: package com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational.oracle;
0016:
0017: import java.io.PrintWriter;
0018: import java.util.Collection;
0019: import java.util.Iterator;
0020:
0021: import org.apache.log4j.Logger;
0022:
0023: import com.metaboss.enterprise.bo.BOException;
0024: import com.metaboss.enterprise.bs.BSException;
0025: import com.metaboss.enterprise.datatypes.DataTypeTranslationMetadata;
0026: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
0027: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.AssociationRole;
0028: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
0029: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
0030: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainRelationalStorageDefinition;
0031: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTable;
0032: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableAttributeColumn;
0033: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableReferenceColumn;
0034: import com.metaboss.sdlctools.services.codegeneration.CodeGenerationStylesheetAccessor;
0035: import com.metaboss.sdlctools.services.codegeneration.CommonUtil;
0036: import com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational.DataBaseMetaData;
0037: import com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational.ImplementationGeneratorBase;
0038: import com.metaboss.sdlctools.services.codegenerationstylesheet.STAttributeStylesheet;
0039: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDatatypeStylesheet;
0040: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDatatypeTranslationStylesheet;
0041: import com.metaboss.sdlctools.services.codegenerationstylesheet.STEntityStylesheet;
0042:
0043: /** Generator of the persistence layer implementation based on oracle DBMS */
0044: public class ImplementationGenerator extends
0045: ImplementationGeneratorBase {
0046: private static Logger sLogger = Logger
0047: .getLogger(ImplementationGenerator.class);
0048:
0049: public ImplementationGenerator(DataBaseMetaData pDataBaseMetaData)
0050: throws BSException {
0051: super (pDataBaseMetaData);
0052: }
0053:
0054: // This hepler writes out the helper method to to insert records where there are lobs ans clobs
0055: // Oracle has somewhat specific implementation of this (may be it can use generic too - need to check)
0056: protected void writeInsertEntityHelperOperation(
0057: PrintWriter pWriter, Entity pEntity,
0058: DomainRelationalStorageDefinition pDomainStorage)
0059: throws BOException, BSException {
0060: STEntityStylesheet lEntityStylesheet = CodeGenerationStylesheetAccessor
0061: .getEntityStylesheet(pEntity);
0062: Collection lAttributes = pEntity.getAttributes();
0063: Collection lReferences = pEntity.getReferences();
0064:
0065: DataType lInstanceIdDatatype = pEntity.getInstanceIdDataType();
0066: STDatatypeStylesheet lInstanceIdDatatypeStylesheet = CodeGenerationStylesheetAccessor
0067: .getDatatypeStylesheet(lInstanceIdDatatype);
0068: STDatatypeTranslationStylesheet lInstanceIdDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
0069: .getDatatypeTranslationStylesheet(lInstanceIdDatatype);
0070: DataTypeTranslationMetadata.SqlType lInstanceIdDatatypeSqlType = DataTypeTranslationMetadata.SqlType
0071: .createFromName(lInstanceIdDatatypeTranslationStylesheet
0072: .getSqlTypeName());
0073:
0074: boolean lIsModifiable = pEntity.isModifiable();
0075: DataType lVersionIdDatatype = (lIsModifiable) ? pEntity
0076: .getVersionIdDataType() : null;
0077: STDatatypeStylesheet lVersionIdDatatypeStylesheet = (lIsModifiable) ? CodeGenerationStylesheetAccessor
0078: .getDatatypeStylesheet(lVersionIdDatatype)
0079: : null;
0080: STDatatypeTranslationStylesheet lVersionIdDatatypeTranslationStylesheet = (lIsModifiable) ? CodeGenerationStylesheetAccessor
0081: .getDatatypeTranslationStylesheet(lVersionIdDatatype)
0082: : null;
0083: DataTypeTranslationMetadata.SqlType lVersionIdDatatypeSqlType = (lIsModifiable) ? DataTypeTranslationMetadata.SqlType
0084: .createFromName(lVersionIdDatatypeTranslationStylesheet
0085: .getSqlTypeName())
0086: : null;
0087:
0088: boolean lHasState = pEntity.getStateMachine() != null;
0089: DataType lStateDatatype = (lHasState) ? pEntity
0090: .getStateDataType() : null;
0091: STDatatypeStylesheet lStateDatatypeStylesheet = (lHasState) ? CodeGenerationStylesheetAccessor
0092: .getDatatypeStylesheet(lStateDatatype)
0093: : null;
0094: STDatatypeTranslationStylesheet lStateDatatypeTranslationStylesheet = (lHasState) ? CodeGenerationStylesheetAccessor
0095: .getDatatypeTranslationStylesheet(lStateDatatype)
0096: : null;
0097: DataTypeTranslationMetadata.SqlType lStateDatatypeSqlType = (lHasState) ? DataTypeTranslationMetadata.SqlType
0098: .createFromName(lStateDatatypeTranslationStylesheet
0099: .getSqlTypeName())
0100: : null;
0101:
0102: RelationalEntityTable lEntityTable = pDomainStorage
0103: .getEntityTable(pEntity);
0104: String lEntityTableName = lEntityTable.getNameOverride();
0105: if (lEntityTableName == null || lEntityTableName.length() == 0)
0106: lEntityTableName = lEntityTable.getNameSuggestion();
0107: String lInstanceIdColumnName = lEntityTable
0108: .getInstanceIdColumnNameOverride();
0109: if (lInstanceIdColumnName == null
0110: || lInstanceIdColumnName.length() == 0)
0111: lInstanceIdColumnName = lEntityTable
0112: .getInstanceIdColumnNameSuggestion();
0113:
0114: String lVersionIdColumnName = null;
0115: if (lIsModifiable) {
0116: lVersionIdColumnName = lEntityTable
0117: .getVersionIdColumnNameOverride();
0118: if (lVersionIdColumnName == null
0119: || lVersionIdColumnName.length() == 0)
0120: lVersionIdColumnName = lEntityTable
0121: .getVersionIdColumnNameSuggestion();
0122: }
0123:
0124: String lStateColumnName = null;
0125: if (lHasState) {
0126: lStateColumnName = lEntityTable
0127: .getStateColumnNameOverride();
0128: if (lStateColumnName == null
0129: || lStateColumnName.length() == 0)
0130: lStateColumnName = lEntityTable
0131: .getStateColumnNameSuggestion();
0132: }
0133: // Find out if this entity has LOBs (can only be in attributes)
0134: boolean lHasBlobs = false;
0135: boolean lHasClobs = false;
0136: for (Iterator lAttributesIterator = lAttributes.iterator(); ((lHasBlobs == false) || (lHasBlobs == false))
0137: && (lAttributesIterator.hasNext());) {
0138: Attribute lAttribute = (Attribute) lAttributesIterator
0139: .next();
0140: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
0141: .getDatatypeTranslationStylesheet(lAttribute
0142: .getDataType());
0143: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
0144: .createFromName(lAttributeDatatypeTranslationStylesheet
0145: .getSqlTypeName());
0146: if (lAttributeDatatypeSqlType
0147: .equals(DataTypeTranslationMetadata.SQL_BLOB))
0148: lHasBlobs = true;
0149: else if (lAttributeDatatypeSqlType
0150: .equals(DataTypeTranslationMetadata.SQL_CLOB))
0151: lHasClobs = true;
0152: }
0153:
0154: pWriter.println();
0155: pWriter.println(" // Inserts one or more new "
0156: + pEntity.getName() + " records into the database");
0157: pWriter.println(" private void insert" + pEntity.getName()
0158: + "Records( java.sql.Connection pConnection, "
0159: + lEntityStylesheet.getStorageRecordFullName()
0160: + "[] pNewRecords) throws PSException");
0161: pWriter.println(" {");
0162: pWriter.println(" try");
0163: pWriter.println(" {");
0164:
0165: pWriter
0166: .println(" java.sql.PreparedStatement lCurrentStatement = null;");
0167: pWriter
0168: .println(" String lCurrentTextOfInsertStatement = null;");
0169: if (lHasBlobs || lHasClobs) {
0170: pWriter
0171: .println(" ArrayList lLobOperations = null; // Actual instance will be created if required");
0172: }
0173: pWriter.println(" try");
0174: pWriter.println(" {");
0175: pWriter
0176: .println(" StringBuffer lProposedTextOfInsert = new StringBuffer();");
0177: pWriter
0178: .println(" StringBuffer lProposedTextOfValues = new StringBuffer();");
0179: pWriter
0180: .println(" for (int i = 0; i < pNewRecords.length; i++)");
0181: pWriter.println(" {");
0182: pWriter
0183: .println(" lProposedTextOfInsert.setLength(0);");
0184: pWriter
0185: .println(" lProposedTextOfInsert.append(\"INSERT INTO "
0186: + lEntityTableName + " (\");");
0187: pWriter
0188: .println(" lProposedTextOfValues.setLength(0);");
0189: pWriter
0190: .println(" lProposedTextOfValues.append(\") VALUES (\");");
0191: pWriter.println(" "
0192: + lEntityStylesheet.getStorageRecordFullName()
0193: + " lNewRecord = pNewRecords[i];");
0194: // InstanceId is mandatory
0195: pWriter
0196: .println(" if (lNewRecord.InstanceId == null)");
0197: pWriter
0198: .println(" throw new PSAttributeConstraintViolationException(\""
0199: + lEntityStylesheet.getStorageRecordFullName()
0200: + ".InstanceId is not expected to be undefined for insert() operation.\");");
0201: pWriter
0202: .println(" if (lNewRecord.InstanceId.isEmpty())");
0203: pWriter
0204: .println(" throw new PSAttributeConstraintViolationException(\""
0205: + lEntityStylesheet.getStorageRecordFullName()
0206: + ".InstanceId is not expected to be empty for insert() operation.\");");
0207: pWriter
0208: .println(" if (lNewRecord.InstanceId.isConcealed())");
0209: pWriter
0210: .println(" throw new PSAttributeConstraintViolationException(\""
0211: + lEntityStylesheet.getStorageRecordFullName()
0212: + ".InstanceId is not expected to be concealed for insert() operation.\");");
0213: pWriter
0214: .println(" lProposedTextOfInsert.append(\""
0215: + lInstanceIdColumnName + "\");");
0216: pWriter
0217: .println(" lProposedTextOfValues.append(\"?\");");
0218: if (lIsModifiable) {
0219: pWriter
0220: .println(" // VersionId is mandatory and must be the initial version");
0221: pWriter
0222: .println(" if (lNewRecord.VersionId == null)");
0223: pWriter
0224: .println(" throw new PSAttributeConstraintViolationException(\""
0225: + lEntityStylesheet
0226: .getStorageRecordFullName()
0227: + ".VersionId is not expected to be undefined for insert() operation.\");");
0228: pWriter
0229: .println(" if (lNewRecord.VersionId.isEmpty())");
0230: pWriter
0231: .println(" throw new PSAttributeConstraintViolationException(\""
0232: + lEntityStylesheet
0233: .getStorageRecordFullName()
0234: + ".VersionId is not expected to be empty for insert() operation.\");");
0235: pWriter
0236: .println(" if (lNewRecord.VersionId.isConcealed())");
0237: pWriter
0238: .println(" throw new PSAttributeConstraintViolationException(\""
0239: + lEntityStylesheet
0240: .getStorageRecordFullName()
0241: + ".VersionId is not expected to be concealed for insert() operation.\");");
0242: pWriter
0243: .println(" if (!lNewRecord.VersionId.isInitial())");
0244: pWriter
0245: .println(" throw new PSAttributeConstraintViolationException(\""
0246: + lEntityStylesheet
0247: .getStorageRecordFullName()
0248: + ".VersionId expected to be '\" + "
0249: + lVersionIdDatatypeStylesheet
0250: .getClassFullName()
0251: + ".createInitial() + \"' for insert() operation. Version id '\" + lNewRecord.VersionId + \"' is not valid for insert() operation.\");");
0252: pWriter
0253: .println(" lProposedTextOfInsert.append(\","
0254: + lVersionIdColumnName + "\");");
0255: pWriter
0256: .println(" lProposedTextOfValues.append(\",?\");");
0257: }
0258: if (lHasState) {
0259: pWriter
0260: .println(" // State is mandatory and must be the initial state");
0261: pWriter.println(" if (lNewRecord."
0262: + lEntityStylesheet
0263: .getStateStorageStructureAttributeName()
0264: + " == null)");
0265: pWriter
0266: .println(" throw new PSAttributeConstraintViolationException(\""
0267: + lEntityStylesheet
0268: .getStorageRecordFullName()
0269: + "."
0270: + lEntityStylesheet
0271: .getStateStorageStructureAttributeName()
0272: + " is not expected to be undefined for insert() operation.\");");
0273: pWriter.println(" if (lNewRecord."
0274: + lEntityStylesheet
0275: .getStateStorageStructureAttributeName()
0276: + ".isEmpty())");
0277: pWriter
0278: .println(" throw new PSAttributeConstraintViolationException(\""
0279: + lEntityStylesheet
0280: .getStorageRecordFullName()
0281: + "."
0282: + lEntityStylesheet
0283: .getStateStorageStructureAttributeName()
0284: + " is not expected to be empty for insert() operation.\");");
0285: pWriter.println(" if (lNewRecord."
0286: + lEntityStylesheet
0287: .getStateStorageStructureAttributeName()
0288: + ".isConcealed())");
0289: pWriter
0290: .println(" throw new PSAttributeConstraintViolationException(\""
0291: + lEntityStylesheet
0292: .getStorageRecordFullName()
0293: + "."
0294: + lEntityStylesheet
0295: .getStateStorageStructureAttributeName()
0296: + " is not expected to be concealed for insert() operation.\");");
0297: pWriter.println(" if (!lNewRecord."
0298: + lEntityStylesheet
0299: .getStateStorageStructureAttributeName()
0300: + ".isInitial())");
0301: pWriter.println(" {");
0302: pWriter.println(" "
0303: + lStateDatatypeStylesheet.getClassFullName()
0304: + " lInitialState = "
0305: + lStateDatatypeStylesheet.getClassFullName()
0306: + ".createInitial();");
0307: pWriter
0308: .println(" if (!lInitialState.canTransition(lNewRecord."
0309: + lEntityStylesheet
0310: .getStateStorageStructureAttributeName()
0311: + "))");
0312: pWriter
0313: .println(" throw new PSAttributeConstraintViolationException(\"For insert() operation the "
0314: + lEntityStylesheet
0315: .getStorageRecordFullName()
0316: + "."
0317: + lEntityStylesheet
0318: .getStateStorageStructureAttributeName()
0319: + " field is expected to be set to initial state or any of the states immediately navigable from the initial state. Value '\" + lNewRecord."
0320: + lEntityStylesheet
0321: .getStateStorageStructureAttributeName()
0322: + " + \"' is not valid for insert() operation.\");");
0323: pWriter.println(" }");
0324: pWriter
0325: .println(" lProposedTextOfInsert.append(\","
0326: + lStateColumnName + "\");");
0327: pWriter
0328: .println(" lProposedTextOfValues.append(\",?\");");
0329: }
0330: // Deal with attributes
0331: if (lHasBlobs || lHasClobs) {
0332: // Special deferred lob processing
0333: pWriter
0334: .println(" LobOperationDetail lThisRecordLobOperation = null; // Will be created if required");
0335: }
0336: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
0337: .hasNext();) {
0338: Attribute lAttribute = (Attribute) lAttributesIterator
0339: .next();
0340: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
0341: .getAttributeColumn(lAttribute);
0342: String lAttributeColumnName = lRelationalEntityTableAttribute
0343: .getColumnNameOverride();
0344: if (lAttributeColumnName == null
0345: || lAttributeColumnName.length() == 0)
0346: lAttributeColumnName = lRelationalEntityTableAttribute
0347: .getColumnNameSuggestion();
0348:
0349: // Do not look at SQL_BLOB and SQL_CLOB here
0350: STAttributeStylesheet lAttributeStylesheet = CodeGenerationStylesheetAccessor
0351: .getAttributeStylesheet(lAttribute);
0352: STDatatypeStylesheet lAttributeDatatypeStylesheet = CodeGenerationStylesheetAccessor
0353: .getDatatypeStylesheet(lAttribute.getDataType());
0354: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
0355: .getDatatypeTranslationStylesheet(lAttribute
0356: .getDataType());
0357: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
0358: .createFromName(lAttributeDatatypeTranslationStylesheet
0359: .getSqlTypeName());
0360: if (lAttribute.isOptional()) {
0361: // Do not even bother inserting optional attribute - null will just appear automatically
0362: pWriter.println(" // "
0363: + lAttribute.getName() + " is optional");
0364: pWriter.println(" if (lNewRecord."
0365: + lAttributeStylesheet.getNormalisedName()
0366: + " != null && lNewRecord."
0367: + lAttributeStylesheet.getNormalisedName()
0368: + ".isEmpty() == false)");
0369: pWriter.println(" {");
0370: pWriter
0371: .println(" if (lNewRecord."
0372: + lAttributeStylesheet
0373: .getNormalisedName()
0374: + ".isConcealed())");
0375: pWriter
0376: .println(" throw new PSAttributeConstraintViolationException(\""
0377: + lEntityStylesheet
0378: .getStorageRecordFullName()
0379: + "."
0380: + lAttributeStylesheet
0381: .getNormalisedName()
0382: + " is not expected to be concealed for insert() operation.\");");
0383: pWriter
0384: .println(" lProposedTextOfInsert.append(\","
0385: + lAttributeColumnName + "\");");
0386: if (lAttributeDatatypeSqlType
0387: .equals(DataTypeTranslationMetadata.SQL_BLOB)) {
0388: pWriter
0389: .println(" lProposedTextOfValues.append(\",empty_blob()\");");
0390: pWriter
0391: .println(" if (lThisRecordLobOperation == null)");
0392: pWriter
0393: .println(" lThisRecordLobOperation = new LobOperationDetail();");
0394: pWriter
0395: .println(" lThisRecordLobOperation.ColumnNames.add(\""
0396: + lAttributeColumnName + "\");");
0397: pWriter
0398: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
0399: + getUniqueDatatypeName(lAttribute
0400: .getDataType())
0401: + "(lNewRecord."
0402: + lAttributeStylesheet
0403: .getNormalisedName()
0404: + "));");
0405: } else if (lAttributeDatatypeSqlType
0406: .equals(DataTypeTranslationMetadata.SQL_CLOB)) {
0407: pWriter
0408: .println(" lProposedTextOfValues.append(\",empty_clob()\");");
0409: pWriter
0410: .println(" if (lThisRecordLobOperation == null)");
0411: pWriter
0412: .println(" lThisRecordLobOperation = new LobOperationDetail();");
0413: pWriter
0414: .println(" lThisRecordLobOperation.ColumnNames.add(\""
0415: + lAttributeColumnName + "\");");
0416: pWriter
0417: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
0418: + getUniqueDatatypeName(lAttribute
0419: .getDataType())
0420: + "(lNewRecord."
0421: + lAttributeStylesheet
0422: .getNormalisedName()
0423: + "));");
0424: } else
0425: pWriter
0426: .println(" lProposedTextOfValues.append(\",?\");");
0427: pWriter.println(" }");
0428: } else {
0429: pWriter.println(" // "
0430: + lAttribute.getName() + " is mandatory");
0431: pWriter.println(" if (lNewRecord."
0432: + lAttributeStylesheet.getNormalisedName()
0433: + " == null)");
0434: pWriter
0435: .println(" throw new PSAttributeConstraintViolationException(\""
0436: + lEntityStylesheet
0437: .getStorageRecordFullName()
0438: + "."
0439: + lAttributeStylesheet
0440: .getNormalisedName()
0441: + " is not expected to be undefined for insert() operation.\");");
0442: pWriter.println(" if (lNewRecord."
0443: + lAttributeStylesheet.getNormalisedName()
0444: + ".isEmpty())");
0445: pWriter
0446: .println(" throw new PSAttributeConstraintViolationException(\""
0447: + lEntityStylesheet
0448: .getStorageRecordFullName()
0449: + "."
0450: + lAttributeStylesheet
0451: .getNormalisedName()
0452: + " is not expected to be empty for insert() operation.\");");
0453: pWriter.println(" if (lNewRecord."
0454: + lAttributeStylesheet.getNormalisedName()
0455: + ".isConcealed())");
0456: pWriter
0457: .println(" throw new PSAttributeConstraintViolationException(\""
0458: + lEntityStylesheet
0459: .getStorageRecordFullName()
0460: + "."
0461: + lAttributeStylesheet
0462: .getNormalisedName()
0463: + " is not expected to be concealed for insert() operation.\");");
0464: pWriter
0465: .println(" lProposedTextOfInsert.append(\","
0466: + lAttributeColumnName + "\");");
0467: if (lAttributeDatatypeSqlType
0468: .equals(DataTypeTranslationMetadata.SQL_BLOB)) {
0469: pWriter
0470: .println(" lProposedTextOfValues.append(\",empty_blob()\");");
0471: pWriter
0472: .println(" if (lThisRecordLobOperation == null)");
0473: pWriter
0474: .println(" lThisRecordLobOperation = new LobOperationDetail();");
0475: pWriter
0476: .println(" lThisRecordLobOperation.ColumnNames.add(\""
0477: + lAttributeColumnName + "\");");
0478: pWriter
0479: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
0480: + getUniqueDatatypeName(lAttribute
0481: .getDataType())
0482: + "(lNewRecord."
0483: + lAttributeStylesheet
0484: .getNormalisedName()
0485: + "));");
0486: } else if (lAttributeDatatypeSqlType
0487: .equals(DataTypeTranslationMetadata.SQL_CLOB)) {
0488: pWriter
0489: .println(" lProposedTextOfValues.append(\",empty_clob()\");");
0490: pWriter
0491: .println(" if (lThisRecordLobOperation == null)");
0492: pWriter
0493: .println(" lThisRecordLobOperation = new LobOperationDetail();");
0494: pWriter
0495: .println(" lThisRecordLobOperation.ColumnNames.add(\""
0496: + lAttributeColumnName + "\");");
0497: pWriter
0498: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
0499: + getUniqueDatatypeName(lAttribute
0500: .getDataType())
0501: + "(lNewRecord."
0502: + lAttributeStylesheet
0503: .getNormalisedName()
0504: + "));");
0505: } else
0506: pWriter
0507: .println(" lProposedTextOfValues.append(\",?\");");
0508: }
0509: }
0510: if (lHasBlobs || lHasClobs) {
0511: pWriter
0512: .println(" if (lThisRecordLobOperation != null)");
0513: pWriter.println(" {");
0514: pWriter
0515: .println(" lThisRecordLobOperation.InstanceId = lNewRecord.InstanceId;");
0516: pWriter
0517: .println(" if (lLobOperations == null)");
0518: pWriter
0519: .println(" lLobOperations = new ArrayList();");
0520: pWriter
0521: .println(" lLobOperations.add(lThisRecordLobOperation);");
0522: pWriter.println(" }");
0523: }
0524: // Deal with associations
0525: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
0526: .hasNext();) {
0527: AssociationRole lReference = (AssociationRole) lReferencesIterator
0528: .next();
0529: // Association constraint is only necessary if this entity has a reference
0530: if (CommonUtil.doesEntityStoreReference(lReference)) {
0531: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
0532: .getReferenceColumn(lReference);
0533: String lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0534: .getColumnNameOverride();
0535: if (lAssociationRoleInstanceIdColumnName == null
0536: || lAssociationRoleInstanceIdColumnName
0537: .length() == 0)
0538: lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0539: .getColumnNameSuggestion();
0540: if (lReference.isOptional()) {
0541: // Do not even bother inserting optional reference - null will just appear automatically
0542: pWriter
0543: .println(" if (lNewRecord."
0544: + lReference.getName()
0545: + "InstanceId != null && lNewRecord."
0546: + lReference.getName()
0547: + "InstanceId.isEmpty() == false)");
0548: pWriter.println(" {");
0549: pWriter
0550: .println(" if (lNewRecord."
0551: + lReference.getName()
0552: + "InstanceId.isConcealed())");
0553: pWriter
0554: .println(" throw new PSAssociationConstraintViolationException(\""
0555: + lEntityStylesheet
0556: .getStorageRecordFullName()
0557: + "."
0558: + lReference.getName()
0559: + "InstanceId is not expected to be concealed for insert() operation.\");");
0560: pWriter
0561: .println(" lProposedTextOfInsert.append(\","
0562: + lAssociationRoleInstanceIdColumnName
0563: + "\");");
0564: pWriter
0565: .println(" lProposedTextOfValues.append(\",?\");");
0566: pWriter.println(" }");
0567: } else {
0568: pWriter
0569: .println(" if (lNewRecord."
0570: + lReference.getName()
0571: + "InstanceId == null)");
0572: pWriter
0573: .println(" throw new PSAssociationConstraintViolationException(\""
0574: + lEntityStylesheet
0575: .getStorageRecordFullName()
0576: + "."
0577: + lReference.getName()
0578: + "InstanceId is not expected to be undefined for insert() operation.\");");
0579: pWriter
0580: .println(" if (lNewRecord."
0581: + lReference.getName()
0582: + "InstanceId.isEmpty())");
0583: pWriter
0584: .println(" throw new PSAssociationConstraintViolationException(\""
0585: + lEntityStylesheet
0586: .getStorageRecordFullName()
0587: + "."
0588: + lReference.getName()
0589: + "InstanceId is not expected to be empty for insert() operation.\");");
0590: pWriter
0591: .println(" if (lNewRecord."
0592: + lReference.getName()
0593: + "InstanceId.isConcealed())");
0594: pWriter
0595: .println(" throw new PSAssociationConstraintViolationException(\""
0596: + lEntityStylesheet
0597: .getStorageRecordFullName()
0598: + "."
0599: + lReference.getName()
0600: + "InstanceId is not expected to be concealed for insert() operation.\");");
0601: pWriter
0602: .println(" lProposedTextOfInsert.append(\","
0603: + lAssociationRoleInstanceIdColumnName
0604: + "\");");
0605: pWriter
0606: .println(" lProposedTextOfValues.append(\",?\");");
0607: }
0608: }
0609: }
0610: // We have built the statement for this insertion. Compare with saved one and make a decision to continue current batch or not
0611: pWriter
0612: .println(" String lProposedTextOfInsertStatement = lProposedTextOfInsert.toString() + lProposedTextOfValues.toString() + \")\";");
0613: pWriter
0614: .println(" if (lCurrentStatement != null)");
0615: pWriter.println(" {");
0616: pWriter
0617: .println(" if (!lCurrentTextOfInsertStatement.equals(lProposedTextOfInsertStatement))");
0618: pWriter.println(" {");
0619: // Execute batched up previous sttement
0620: pWriter
0621: .println(" lCurrentStatement.executeBatch();");
0622: pWriter
0623: .println(" lCurrentStatement.close();");
0624: pWriter
0625: .println(" lCurrentStatement = null;");
0626: pWriter.println(" }");
0627: pWriter.println(" }");
0628: pWriter
0629: .println(" if (lCurrentStatement == null)");
0630: pWriter.println(" {");
0631: pWriter
0632: .println(" lCurrentTextOfInsertStatement = lProposedTextOfInsertStatement;");
0633: pWriter
0634: .println(" sLogger.debug(\"About to execute SQL statement: \" + lCurrentTextOfInsertStatement + \";\");");
0635: pWriter
0636: .println(" lCurrentStatement = pConnection.prepareStatement(lCurrentTextOfInsertStatement);");
0637: pWriter.println(" }");
0638: // Now populate the statement
0639: pWriter.println(" int lParameterIndex = 1;");
0640: pWriter
0641: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lNewRecord.InstanceId);");
0642: pWriter.println(" lCurrentStatement."
0643: + getDataBaseMetaData().suggestStatementSetMethod(
0644: lInstanceIdDatatype)
0645: + "( lParameterIndex++, TypesConvertor.getSqlValueFrom"
0646: + getUniqueDatatypeName(lInstanceIdDatatype)
0647: + "(lNewRecord.InstanceId));");
0648: if (lIsModifiable) {
0649: pWriter
0650: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lNewRecord.VersionId);");
0651: pWriter
0652: .println(" lCurrentStatement."
0653: + getDataBaseMetaData()
0654: .suggestStatementSetMethod(
0655: lVersionIdDatatype)
0656: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0657: + getUniqueDatatypeName(lVersionIdDatatype)
0658: + "(lNewRecord.VersionId));");
0659: }
0660: if (lHasState) {
0661: pWriter
0662: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lNewRecord."
0663: + lEntityStylesheet
0664: .getStateStorageStructureAttributeName()
0665: + ");");
0666: pWriter
0667: .println(" lCurrentStatement."
0668: + getDataBaseMetaData()
0669: .suggestStatementSetMethod(
0670: lStateDatatype)
0671: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0672: + getUniqueDatatypeName(lStateDatatype)
0673: + "(lNewRecord."
0674: + lEntityStylesheet
0675: .getStateStorageStructureAttributeName()
0676: + "));");
0677: }
0678: // Deal with attributes
0679: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
0680: .hasNext();) {
0681: Attribute lAttribute = (Attribute) lAttributesIterator
0682: .next();
0683: STAttributeStylesheet lAttributeStylesheet = CodeGenerationStylesheetAccessor
0684: .getAttributeStylesheet(lAttribute);
0685: DataType lAttributeDatatype = lAttribute.getDataType();
0686: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
0687: .getDatatypeTranslationStylesheet(lAttribute
0688: .getDataType());
0689: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
0690: .createFromName(lAttributeDatatypeTranslationStylesheet
0691: .getSqlTypeName());
0692: if (lAttributeDatatypeSqlType
0693: .equals(DataTypeTranslationMetadata.SQL_BLOB) == false
0694: && lAttributeDatatypeSqlType
0695: .equals(DataTypeTranslationMetadata.SQL_CLOB) == false) {
0696: if (lAttribute.isOptional()) {
0697: pWriter
0698: .println(" if (lNewRecord."
0699: + lAttributeStylesheet
0700: .getNormalisedName()
0701: + " != null && lNewRecord."
0702: + lAttributeStylesheet
0703: .getNormalisedName()
0704: + ".isEmpty() == false)");
0705: pWriter.println(" {");
0706: // Limit output at 30 characters we only do it for attributes as other parameters are quite short an also might be important for debugging
0707: pWriter
0708: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + com.metaboss.util.StringUtils.suggestTruncatedOutput(lNewRecord."
0709: + lAttributeStylesheet
0710: .getNormalisedName()
0711: + ".toString(),30));");
0712: pWriter
0713: .println(" lCurrentStatement."
0714: + getDataBaseMetaData()
0715: .suggestStatementSetMethod(
0716: lAttributeDatatype)
0717: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0718: + getUniqueDatatypeName(lAttributeDatatype)
0719: + "(lNewRecord."
0720: + lAttributeStylesheet
0721: .getNormalisedName()
0722: + "));");
0723: pWriter.println(" }");
0724: } else {
0725: // Limit output at 30 characters we only do it for attributes as other parameters are quite short an also might be important for debugging
0726: pWriter
0727: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + com.metaboss.util.StringUtils.suggestTruncatedOutput(lNewRecord."
0728: + lAttributeStylesheet
0729: .getNormalisedName()
0730: + ".toString(),30));");
0731: pWriter
0732: .println(" lCurrentStatement."
0733: + getDataBaseMetaData()
0734: .suggestStatementSetMethod(
0735: lAttributeDatatype)
0736: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0737: + getUniqueDatatypeName(lAttributeDatatype)
0738: + "(lNewRecord."
0739: + lAttributeStylesheet
0740: .getNormalisedName()
0741: + "));");
0742: }
0743: }
0744: }
0745: // Deal with associations
0746: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
0747: .hasNext();) {
0748: AssociationRole lRole = (AssociationRole) lReferencesIterator
0749: .next();
0750: // Association constraint is only necessary if this entity has a reference
0751: if (CommonUtil.doesEntityStoreReference(lRole)) {
0752: DataType lRoleEntityInstanceIdDatatype = lRole
0753: .getEntity().getInstanceIdDataType();
0754: if (lRole.isOptional()) {
0755: pWriter
0756: .println(" if (lNewRecord."
0757: + lRole.getName()
0758: + "InstanceId != null && lNewRecord."
0759: + lRole.getName()
0760: + "InstanceId.isEmpty() == false)");
0761: pWriter.println(" {");
0762: pWriter
0763: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lNewRecord."
0764: + lRole.getName() + "InstanceId);");
0765: pWriter
0766: .println(" lCurrentStatement."
0767: + getDataBaseMetaData()
0768: .suggestStatementSetMethod(
0769: lRoleEntityInstanceIdDatatype)
0770: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0771: + getUniqueDatatypeName(lRoleEntityInstanceIdDatatype)
0772: + "(lNewRecord."
0773: + lRole.getName()
0774: + "InstanceId));");
0775: pWriter.println(" }");
0776: } else {
0777: pWriter
0778: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lNewRecord."
0779: + lRole.getName() + "InstanceId);");
0780: pWriter
0781: .println(" lCurrentStatement."
0782: + getDataBaseMetaData()
0783: .suggestStatementSetMethod(
0784: lRoleEntityInstanceIdDatatype)
0785: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
0786: + getUniqueDatatypeName(lRoleEntityInstanceIdDatatype)
0787: + "(lNewRecord."
0788: + lRole.getName()
0789: + "InstanceId));");
0790: }
0791: }
0792: }
0793: pWriter
0794: .println(" lCurrentStatement.addBatch();");
0795: pWriter.println(" }");
0796: pWriter
0797: .println(" lCurrentStatement.executeBatch();");
0798: pWriter.println(" lCurrentStatement.close();");
0799: pWriter.println(" lCurrentStatement = null;");
0800: if (lHasBlobs || lHasClobs) {
0801: // Look after Lobs
0802: pWriter
0803: .println(" if (lLobOperations != null)");
0804: pWriter
0805: .println(" save"
0806: + pEntity.getName()
0807: + "Lobs(pConnection, (LobOperationDetail[])lLobOperations.toArray(new LobOperationDetail[lLobOperations.size()]));");
0808: }
0809: pWriter.println(" }");
0810: pWriter.println(" finally");
0811: pWriter.println(" {");
0812: pWriter
0813: .println(" if (lCurrentStatement != null)");
0814: pWriter
0815: .println(" lCurrentStatement.close();");
0816: pWriter.println(" }");
0817: pWriter.println(" }");
0818: pWriter
0819: .println(" catch(DataTypeInvalidOperationForEmptyInstanceException e)");
0820: pWriter.println(" {");
0821: pWriter
0822: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code must check for empty instance\",e);");
0823: pWriter.println(" }");
0824: pWriter
0825: .println(" catch(DataTypeInvalidOperationForConcealedInstanceException e)");
0826: pWriter.println(" {");
0827: pWriter
0828: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code must check for concealed instance\",e);");
0829: pWriter.println(" }");
0830: writeSQLExceptionHandlerForInsertEntity(pWriter, pEntity,
0831: lEntityTable);
0832: pWriter.println(" }");
0833: }
0834:
0835: // This helper writes out the SQLException catch block for the insert entity operation
0836: // The body of the catch block must result in throwing some kind of PSException
0837: protected void writeSQLExceptionHandlerForInsertEntity(
0838: PrintWriter pWriter, Entity pEntity,
0839: RelationalEntityTable pEntityTable) throws BSException {
0840: STEntityStylesheet lEntityStylesheet = CodeGenerationStylesheetAccessor
0841: .getEntityStylesheet(pEntity);
0842:
0843: String lEntityTableName = pEntityTable.getNameOverride();
0844: if (lEntityTableName == null || lEntityTableName.length() == 0)
0845: lEntityTableName = pEntityTable.getNameSuggestion();
0846:
0847: pWriter.println(" catch(java.sql.SQLException e)");
0848: pWriter.println(" {");
0849: pWriter
0850: .println(" String lMessage = e.getMessage();");
0851: pWriter.println(" if (lMessage != null)");
0852: pWriter.println(" {");
0853: pWriter.println(" lMessage = lMessage.trim();");
0854: pWriter
0855: .println(" if (lMessage.startsWith(\"ORA-02291 integrity constraint\") && lMessage.endsWith(\"- parent key not found\"))");
0856: pWriter
0857: .println(" throw new PSAssociationConstraintViolationException(\"Error on insert("
0858: + lEntityStylesheet.getStorageRecordFullName()
0859: + ")\", e);");
0860: pWriter
0861: .println(" if (lMessage.startsWith(\"ORA-00001: unique constraint\"))");
0862: pWriter
0863: .println(" throw new PSAttributeConstraintViolationException(\"Error on insert("
0864: + lEntityStylesheet.getStorageRecordFullName()
0865: + ")\", e);");
0866: pWriter.println(" }");
0867: pWriter
0868: .println(" throw new PSDataSourceOperationInvocationException(\"Error on insert("
0869: + lEntityStylesheet.getStorageRecordFullName()
0870: + ")\", e);");
0871: pWriter.println(" }");
0872: }
0873:
0874: // This helper writes out the SQLException catch block for the update entity operation
0875: // The body of the catch block must result in throwing some kind of PSException
0876: protected void writeSQLExceptionHandlerForUpdateEntity(
0877: PrintWriter pWriter, Entity pEntity,
0878: RelationalEntityTable pEntityTable) throws BSException {
0879: STEntityStylesheet lEntityStylesheet = CodeGenerationStylesheetAccessor
0880: .getEntityStylesheet(pEntity);
0881:
0882: String lEntityTableName = pEntityTable.getNameOverride();
0883: if (lEntityTableName == null || lEntityTableName.length() == 0)
0884: lEntityTableName = pEntityTable.getNameSuggestion();
0885:
0886: pWriter.println(" catch(java.sql.SQLException e)");
0887: pWriter.println(" {");
0888: pWriter
0889: .println(" String lMessage = e.getMessage();");
0890: pWriter.println(" if (lMessage != null)");
0891: pWriter.println(" {");
0892: pWriter.println(" lMessage = lMessage.trim();");
0893: pWriter
0894: .println(" if (lMessage.startsWith(\"ORA-02291 integrity constraint\") && lMessage.endsWith(\"- parent key not found\"))");
0895: pWriter
0896: .println(" throw new PSAssociationConstraintViolationException(\"Error on update("
0897: + lEntityStylesheet.getStorageRecordFullName()
0898: + ")\", e);");
0899: pWriter
0900: .println(" if (lMessage.startsWith(\"ORA-00001: unique constraint\"))");
0901: pWriter
0902: .println(" throw new PSAttributeConstraintViolationException(\"Error on update("
0903: + lEntityStylesheet.getStorageRecordFullName()
0904: + ")\", e);");
0905: pWriter.println(" }");
0906: pWriter
0907: .println(" throw new PSDataSourceOperationInvocationException(\"Error on update("
0908: + lEntityStylesheet.getStorageRecordFullName()
0909: + ")\", e);");
0910: pWriter.println(" }");
0911: }
0912:
0913: // This hepler writes out the optional helper method to update the entity record
0914: // It has a special approach to dealing with lobs - only aplicable to Oracle
0915: // Oracle has somewhat specific implementation of this (may be it can use generic too - need to check)
0916: protected void writeOptionalUpdateEntityHelperOperation(
0917: PrintWriter pWriter, Entity pEntity,
0918: DomainRelationalStorageDefinition pDomainStorage)
0919: throws BOException, BSException {
0920: if (pEntity.isModifiable()) {
0921: // This should be in storage definition latter on
0922: boolean lUpdateInBatches = false;
0923:
0924: STEntityStylesheet lEntityStylesheet = CodeGenerationStylesheetAccessor
0925: .getEntityStylesheet(pEntity);
0926:
0927: Collection lAttributes = pEntity.getAttributes();
0928: Collection lReferences = pEntity.getReferences();
0929:
0930: DataType lInstanceIdDatatype = pEntity
0931: .getInstanceIdDataType();
0932: STDatatypeStylesheet lInstanceIdDatatypeStylesheet = CodeGenerationStylesheetAccessor
0933: .getDatatypeStylesheet(lInstanceIdDatatype);
0934:
0935: DataType lVersionIdDatatype = pEntity
0936: .getVersionIdDataType();
0937: STDatatypeStylesheet lVersionIdDatatypeStylesheet = CodeGenerationStylesheetAccessor
0938: .getDatatypeStylesheet(lVersionIdDatatype);
0939:
0940: boolean lHasState = pEntity.getStateMachine() != null;
0941: DataType lStateDatatype = (lHasState) ? pEntity
0942: .getStateDataType() : null;
0943: STDatatypeStylesheet lStateDatatypeStylesheet = (lHasState) ? CodeGenerationStylesheetAccessor
0944: .getDatatypeStylesheet(lStateDatatype)
0945: : null;
0946:
0947: RelationalEntityTable lEntityTable = pDomainStorage
0948: .getEntityTable(pEntity);
0949: String lEntityTableName = lEntityTable.getNameOverride();
0950: if (lEntityTableName == null
0951: || lEntityTableName.length() == 0)
0952: lEntityTableName = lEntityTable.getNameSuggestion();
0953:
0954: String lInstanceIdColumnName = lEntityTable
0955: .getInstanceIdColumnNameOverride();
0956: if (lInstanceIdColumnName == null
0957: || lInstanceIdColumnName.length() == 0)
0958: lInstanceIdColumnName = lEntityTable
0959: .getInstanceIdColumnNameSuggestion();
0960:
0961: String lVersionIdColumnName = lVersionIdColumnName = lEntityTable
0962: .getVersionIdColumnNameOverride();
0963: if (lVersionIdColumnName == null
0964: || lVersionIdColumnName.length() == 0)
0965: lVersionIdColumnName = lEntityTable
0966: .getVersionIdColumnNameSuggestion();
0967:
0968: String lStateColumnName = null;
0969: if (lHasState) {
0970: lStateColumnName = lEntityTable
0971: .getStateColumnNameOverride();
0972: if (lStateColumnName == null
0973: || lStateColumnName.length() == 0)
0974: lStateColumnName = lEntityTable
0975: .getStateColumnNameSuggestion();
0976: }
0977:
0978: // Find out if this entity has LOBs (can only be in attributes)
0979: boolean lHasBlobs = false;
0980: boolean lHasClobs = false;
0981: for (Iterator lAttributesIterator = lAttributes.iterator(); ((lHasBlobs == false) || (lHasBlobs == false))
0982: && (lAttributesIterator.hasNext());) {
0983: Attribute lAttribute = (Attribute) lAttributesIterator
0984: .next();
0985: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
0986: .getDatatypeTranslationStylesheet(lAttribute
0987: .getDataType());
0988: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
0989: .createFromName(lAttributeDatatypeTranslationStylesheet
0990: .getSqlTypeName());
0991: if (lAttributeDatatypeSqlType
0992: .equals(DataTypeTranslationMetadata.SQL_BLOB))
0993: lHasBlobs = true;
0994: else if (lAttributeDatatypeSqlType
0995: .equals(DataTypeTranslationMetadata.SQL_CLOB))
0996: lHasClobs = true;
0997: }
0998:
0999: pWriter.println();
1000: pWriter.println(" // Inserts one or more new "
1001: + pEntity.getName() + " records into the database");
1002: pWriter.println(" private void update"
1003: + pEntity.getName()
1004: + "Records( java.sql.Connection pConnection, "
1005: + lEntityStylesheet.getStorageRecordFullName()
1006: + "[] pModifiedRecords) throws PSException");
1007: pWriter.println(" {");
1008: pWriter.println(" try");
1009: pWriter.println(" {");
1010: if (lUpdateInBatches) {
1011: pWriter
1012: .println(" java.sql.CallableStatement lCurrentStatement = null;");
1013: } else {
1014: pWriter
1015: .println(" java.sql.PreparedStatement lCurrentStatement = null;");
1016: }
1017: pWriter
1018: .println(" String lCurrentTextOfUpdateStatement = null;");
1019: if (lHasBlobs || lHasClobs) {
1020: pWriter
1021: .println(" ArrayList lLobOperations = null; // Actual instance will be created if required");
1022: }
1023: pWriter.println(" try");
1024: pWriter.println(" {");
1025: if (lUpdateInBatches) {
1026: pWriter
1027: .println(" int lCurrentBatchBaseIndex = 0;");
1028: }
1029: pWriter
1030: .println(" StringBuffer lProposedTextOfUpdate = new StringBuffer();");
1031: pWriter
1032: .println(" for (int i = 0; i < pModifiedRecords.length; i++)");
1033: pWriter.println(" {");
1034: pWriter.println(" "
1035: + lEntityStylesheet.getStorageRecordFullName()
1036: + " lModifiedRecord = pModifiedRecords[i];");
1037: pWriter
1038: .println(" // InstanceId is mandatory");
1039: pWriter
1040: .println(" if (lModifiedRecord.InstanceId == null)");
1041: pWriter
1042: .println(" throw new PSAttributeConstraintViolationException(\""
1043: + lEntityStylesheet
1044: .getStorageRecordFullName()
1045: + ".InstanceId is not expected to be undefined for update() operation.\");");
1046: pWriter
1047: .println(" if (lModifiedRecord.InstanceId.isEmpty())");
1048: pWriter
1049: .println(" throw new PSAttributeConstraintViolationException(\""
1050: + lEntityStylesheet
1051: .getStorageRecordFullName()
1052: + ".InstanceId is not expected to be empty for update() operation.\");");
1053: pWriter
1054: .println(" if (lModifiedRecord.InstanceId.isConcealed())");
1055: pWriter
1056: .println(" throw new PSAttributeConstraintViolationException(\""
1057: + lEntityStylesheet
1058: .getStorageRecordFullName()
1059: + ".InstanceId is not expected to be concealed for update() operation.\");");
1060: pWriter
1061: .println(" // VersionId is mandatory");
1062: pWriter
1063: .println(" if (lModifiedRecord.VersionId == null)");
1064: pWriter
1065: .println(" throw new PSAttributeConstraintViolationException(\""
1066: + lEntityStylesheet
1067: .getStorageRecordFullName()
1068: + ".VersionId is not expected to be undefined for update() operation.\");");
1069: pWriter
1070: .println(" if (lModifiedRecord.VersionId.isEmpty())");
1071: pWriter
1072: .println(" throw new PSAttributeConstraintViolationException(\""
1073: + lEntityStylesheet
1074: .getStorageRecordFullName()
1075: + ".VersionId is not expected to be empty for update() operation.\");");
1076: pWriter
1077: .println(" if (lModifiedRecord.VersionId.isConcealed())");
1078: pWriter
1079: .println(" throw new PSAttributeConstraintViolationException(\""
1080: + lEntityStylesheet
1081: .getStorageRecordFullName()
1082: + ".VersionId is not expected to be concealed for update() operation.\");");
1083: pWriter
1084: .println(" lProposedTextOfUpdate.setLength(0);");
1085: pWriter
1086: .println(" lProposedTextOfUpdate.append(\"UPDATE "
1087: + lEntityTableName
1088: + " SET "
1089: + lVersionIdColumnName + " = ?\");");
1090: if (lHasState) {
1091: pWriter
1092: .println(" // State may not be submitted for update, which is perfectly valid");
1093: pWriter
1094: .println(" if (lModifiedRecord."
1095: + lEntityStylesheet
1096: .getStateStorageStructureAttributeName()
1097: + " != null)");
1098: pWriter.println(" {");
1099: pWriter
1100: .println(" if (lModifiedRecord."
1101: + lEntityStylesheet
1102: .getStateStorageStructureAttributeName()
1103: + ".isEmpty())");
1104: pWriter
1105: .println(" throw new PSAttributeConstraintViolationException(\""
1106: + lEntityStylesheet
1107: .getStorageRecordFullName()
1108: + "."
1109: + lEntityStylesheet
1110: .getStateStorageStructureAttributeName()
1111: + " is not expected to be empty for update() operation.\");");
1112: pWriter
1113: .println(" if (lModifiedRecord."
1114: + lEntityStylesheet
1115: .getStateStorageStructureAttributeName()
1116: + ".isConcealed())");
1117: pWriter
1118: .println(" throw new PSAttributeConstraintViolationException(\""
1119: + lEntityStylesheet
1120: .getStorageRecordFullName()
1121: + "."
1122: + lEntityStylesheet
1123: .getStateStorageStructureAttributeName()
1124: + " is not expected to be concealed for update() operation.\");");
1125: pWriter
1126: .println(" lProposedTextOfUpdate.append(\" ,"
1127: + lStateColumnName + " = ?\");");
1128: pWriter.println(" }");
1129: }
1130: // Deal with attributes
1131: if (lHasBlobs || lHasClobs) {
1132: // Special deferred lob processing
1133: pWriter
1134: .println(" LobOperationDetail lThisRecordLobOperation = null; // Will be created if required");
1135: }
1136: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
1137: .hasNext();) {
1138: Attribute lAttribute = (Attribute) lAttributesIterator
1139: .next();
1140: STAttributeStylesheet lAttributeStylesheet = CodeGenerationStylesheetAccessor
1141: .getAttributeStylesheet(lAttribute);
1142: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
1143: .getAttributeColumn(lAttribute);
1144: String lAttributeColumnName = lRelationalEntityTableAttribute
1145: .getColumnNameOverride();
1146: if (lAttributeColumnName == null
1147: || lAttributeColumnName.length() == 0)
1148: lAttributeColumnName = lRelationalEntityTableAttribute
1149: .getColumnNameSuggestion();
1150: DataType lAttributeDatatype = lAttribute.getDataType();
1151: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
1152: .getDatatypeTranslationStylesheet(lAttribute
1153: .getDataType());
1154: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
1155: .createFromName(lAttributeDatatypeTranslationStylesheet
1156: .getSqlTypeName());
1157: pWriter
1158: .println(" if (lModifiedRecord."
1159: + lAttributeStylesheet
1160: .getNormalisedName()
1161: + " != null)");
1162: pWriter.println(" {");
1163: pWriter
1164: .println(" if (lModifiedRecord."
1165: + lAttributeStylesheet
1166: .getNormalisedName()
1167: + ".isConcealed())");
1168: pWriter
1169: .println(" throw new PSAttributeConstraintViolationException(\""
1170: + lEntityStylesheet
1171: .getStorageRecordFullName()
1172: + "."
1173: + lAttributeStylesheet
1174: .getNormalisedName()
1175: + " is not expected to be concealed for update() operation.\");");
1176: if (lAttribute.isOptional()) {
1177: // Do not even bother inserting optional attribute - null will just appear automatically
1178: pWriter.println(" // "
1179: + lAttribute.getName() + " is optional");
1180: if (lAttributeDatatypeSqlType
1181: .equals(DataTypeTranslationMetadata.SQL_BLOB)) {
1182: pWriter
1183: .println(" if (lModifiedRecord."
1184: + lAttributeStylesheet
1185: .getNormalisedName()
1186: + ".isEmpty() == false)");
1187: pWriter.println(" {");
1188: pWriter
1189: .println(" lProposedTextOfUpdate.append(\", "
1190: + lAttributeColumnName
1191: + " = empty_blob()\");");
1192: pWriter
1193: .println(" if (lThisRecordLobOperation == null)");
1194: pWriter
1195: .println(" lThisRecordLobOperation = new LobOperationDetail();");
1196: pWriter
1197: .println(" lThisRecordLobOperation.ColumnNames.add(\""
1198: + lAttributeColumnName + "\");");
1199: pWriter
1200: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
1201: + getUniqueDatatypeName(lAttributeDatatype)
1202: + "(lModifiedRecord."
1203: + lAttributeStylesheet
1204: .getNormalisedName()
1205: + "));");
1206: pWriter.println(" }");
1207: pWriter.println(" else");
1208: pWriter
1209: .println(" lProposedTextOfUpdate.append(\", "
1210: + lAttributeColumnName
1211: + " = ?\");");
1212: } else if (lAttributeDatatypeSqlType
1213: .equals(DataTypeTranslationMetadata.SQL_CLOB)) {
1214: pWriter
1215: .println(" if (lModifiedRecord."
1216: + lAttributeStylesheet
1217: .getNormalisedName()
1218: + ".isEmpty() == false)");
1219: pWriter.println(" {");
1220: pWriter
1221: .println(" lProposedTextOfUpdate.append(\", "
1222: + lAttributeColumnName
1223: + " = empty_clob()\");");
1224: pWriter
1225: .println(" if (lThisRecordLobOperation == null)");
1226: pWriter
1227: .println(" lThisRecordLobOperation = new LobOperationDetail();");
1228: pWriter
1229: .println(" lThisRecordLobOperation.ColumnNames.add(\""
1230: + lAttributeColumnName + "\");");
1231: pWriter
1232: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
1233: + getUniqueDatatypeName(lAttributeDatatype)
1234: + "(lModifiedRecord."
1235: + lAttributeStylesheet
1236: .getNormalisedName()
1237: + "));");
1238: pWriter.println(" }");
1239: pWriter.println(" else");
1240: pWriter
1241: .println(" lProposedTextOfUpdate.append(\", "
1242: + lAttributeColumnName
1243: + " = ?\");");
1244: } else {
1245: // Ordinary attribute
1246: pWriter
1247: .println(" lProposedTextOfUpdate.append(\", "
1248: + lAttributeColumnName
1249: + " = ?\");");
1250: }
1251: } else {
1252: pWriter.println(" // "
1253: + lAttribute.getName() + " is mandatory");
1254: pWriter
1255: .println(" if (lModifiedRecord."
1256: + lAttributeStylesheet
1257: .getNormalisedName()
1258: + ".isEmpty())");
1259: pWriter
1260: .println(" throw new PSAttributeConstraintViolationException(\""
1261: + lEntityStylesheet
1262: .getStorageRecordFullName()
1263: + "."
1264: + lAttributeStylesheet
1265: .getNormalisedName()
1266: + " is not expected to be empty for update() operation.\");");
1267: if (lAttributeDatatypeSqlType
1268: .equals(DataTypeTranslationMetadata.SQL_BLOB)) {
1269: pWriter
1270: .println(" lProposedTextOfUpdate.append(\", "
1271: + lAttributeColumnName
1272: + " = empty_blob()\");");
1273: pWriter
1274: .println(" if (lThisRecordLobOperation == null)");
1275: pWriter
1276: .println(" lThisRecordLobOperation = new LobOperationDetail();");
1277: pWriter
1278: .println(" lThisRecordLobOperation.ColumnNames.add(\""
1279: + lAttributeColumnName + "\");");
1280: pWriter
1281: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
1282: + getUniqueDatatypeName(lAttributeDatatype)
1283: + "(lModifiedRecord."
1284: + lAttributeStylesheet
1285: .getNormalisedName()
1286: + "));");
1287: } else if (lAttributeDatatypeSqlType
1288: .equals(DataTypeTranslationMetadata.SQL_CLOB)) {
1289: pWriter
1290: .println(" lProposedTextOfUpdate.append(\", "
1291: + lAttributeColumnName
1292: + " = empty_clob()\");");
1293: pWriter
1294: .println(" if (lThisRecordLobOperation == null)");
1295: pWriter
1296: .println(" lThisRecordLobOperation = new LobOperationDetail();");
1297: pWriter
1298: .println(" lThisRecordLobOperation.ColumnNames.add(\""
1299: + lAttributeColumnName + "\");");
1300: pWriter
1301: .println(" lThisRecordLobOperation.ColumnData.add(TypesConvertor.getSqlValueFrom"
1302: + getUniqueDatatypeName(lAttributeDatatype)
1303: + "(lModifiedRecord."
1304: + lAttributeStylesheet
1305: .getNormalisedName()
1306: + "));");
1307: } else {
1308: // Ordinary attribute
1309: pWriter
1310: .println(" lProposedTextOfUpdate.append(\", "
1311: + lAttributeColumnName
1312: + " = ?\");");
1313: }
1314: }
1315: pWriter.println(" }");
1316: }
1317: if (lHasBlobs || lHasClobs) {
1318: pWriter
1319: .println(" if (lThisRecordLobOperation != null)");
1320: pWriter.println(" {");
1321: pWriter
1322: .println(" lThisRecordLobOperation.InstanceId = lModifiedRecord.InstanceId;");
1323: pWriter
1324: .println(" if (lLobOperations == null)");
1325: pWriter
1326: .println(" lLobOperations = new ArrayList();");
1327: pWriter
1328: .println(" lLobOperations.add(lThisRecordLobOperation);");
1329: pWriter.println(" }");
1330: }
1331: // Deal with associations
1332: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
1333: .hasNext();) {
1334: AssociationRole lReference = (AssociationRole) lReferencesIterator
1335: .next();
1336: // Association constraint is only necessary if this entity has a reference
1337: if (CommonUtil.doesEntityStoreReference(lReference)) {
1338: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
1339: .getReferenceColumn(lReference);
1340: String lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
1341: .getColumnNameOverride();
1342: if (lAssociationRoleInstanceIdColumnName == null
1343: || lAssociationRoleInstanceIdColumnName
1344: .length() == 0)
1345: lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
1346: .getColumnNameSuggestion();
1347:
1348: // Singular multiplicities resolved simply by having the other entity id as the member of the structure
1349: pWriter
1350: .println(" if (lModifiedRecord."
1351: + lReference.getName()
1352: + "InstanceId != null)");
1353: pWriter.println(" {");
1354: pWriter
1355: .println(" if (lModifiedRecord."
1356: + lReference.getName()
1357: + "InstanceId.isConcealed())");
1358: pWriter
1359: .println(" throw new PSAttributeConstraintViolationException(\""
1360: + lEntityStylesheet
1361: .getStorageRecordFullName()
1362: + "."
1363: + lReference.getName()
1364: + "InstanceId is not expected to be concealed for update() operation.\");");
1365: // If cardinality is mandatory we need to disallow empty value
1366: if (!lReference.isOptional()) {
1367: pWriter
1368: .println(" if (lModifiedRecord."
1369: + lReference.getName()
1370: + "InstanceId.isEmpty())");
1371: pWriter
1372: .println(" throw new PSAttributeConstraintViolationException(\""
1373: + lEntityStylesheet
1374: .getStorageRecordFullName()
1375: + "."
1376: + lReference.getName()
1377: + "InstanceId is not expected to be empty for update() operation.\");");
1378: }
1379: pWriter
1380: .println(" lProposedTextOfUpdate.append(\","
1381: + lAssociationRoleInstanceIdColumnName
1382: + " = ?\");");
1383: pWriter.println(" }");
1384: }
1385: }
1386: pWriter
1387: .println(" lProposedTextOfUpdate.append(\" WHERE "
1388: + lInstanceIdColumnName
1389: + " = ? AND "
1390: + lVersionIdColumnName + " = ?\");");
1391: pWriter
1392: .println(" // We have built the statement for this insertion. Compare with saved one and make a decision to continue current batch or not");
1393: pWriter
1394: .println(" String lProposedTextOfUpdateStatement = lProposedTextOfUpdate.toString();");
1395: if (lUpdateInBatches) {
1396: pWriter
1397: .println(" if (lCurrentStatement != null)");
1398: pWriter.println(" {");
1399: pWriter
1400: .println(" if (!lCurrentTextOfUpdateStatement.equals(lProposedTextOfUpdateStatement))");
1401: pWriter.println(" {");
1402: // Do the previous statement
1403: pWriter
1404: .println(" int[] lBatchResult = lCurrentStatement.executeBatch();");
1405: pWriter
1406: .println(" lCurrentStatement.close();");
1407: pWriter
1408: .println(" lCurrentStatement = null;");
1409: // Verify that every statement has resulted in one and only one update
1410: pWriter
1411: .println(" for (int lBatchResultIndex = 0; lBatchResultIndex < lBatchResult.length; lBatchResultIndex++)");
1412: pWriter.println(" {");
1413: pWriter
1414: .println(" if (lBatchResult[lBatchResultIndex] != 1)");
1415: pWriter
1416: .println(" throw new PSUpdateDataIntegrityViolationException(\"Unable to update "
1417: + pEntity.getName()
1418: + " record with Instance Id \" + pModifiedRecords[lCurrentBatchBaseIndex + lBatchResultIndex].InstanceId);");
1419: pWriter.println(" }");
1420: pWriter.println(" }");
1421: pWriter.println(" }");
1422: pWriter
1423: .println(" if (lCurrentStatement == null)");
1424: pWriter.println(" {");
1425: pWriter
1426: .println(" lCurrentTextOfUpdateStatement = lProposedTextOfUpdateStatement;");
1427: pWriter
1428: .println(" sLogger.debug(\"About to execute SQL statement: \" + lCurrentTextOfUpdateStatement + \";\");");
1429: pWriter
1430: .println(" lCurrentStatement = pConnection.prepareCall(lCurrentTextOfUpdateStatement);");
1431: pWriter
1432: .println(" lCurrentBatchBaseIndex = i;");
1433: pWriter.println(" }");
1434: } else {
1435: pWriter
1436: .println(" if (lCurrentStatement != null)");
1437: pWriter.println(" {");
1438: pWriter
1439: .println(" if (!lCurrentTextOfUpdateStatement.equals(lProposedTextOfUpdateStatement))");
1440: pWriter.println(" {");
1441: // Do the previous statement
1442: pWriter
1443: .println(" lCurrentStatement.close();");
1444: pWriter
1445: .println(" lCurrentStatement = null;");
1446: pWriter.println(" }");
1447: pWriter.println(" }");
1448: pWriter
1449: .println(" if (lCurrentStatement == null)");
1450: pWriter.println(" {");
1451: pWriter
1452: .println(" lCurrentTextOfUpdateStatement = lProposedTextOfUpdateStatement;");
1453: pWriter
1454: .println(" sLogger.debug(\"About to execute SQL statement: \" + lCurrentTextOfUpdateStatement + \";\");");
1455: pWriter
1456: .println(" lCurrentStatement = pConnection.prepareStatement(lCurrentTextOfUpdateStatement);");
1457: pWriter.println(" }");
1458: }
1459:
1460: // Now populate the statement
1461: pWriter
1462: .println(" int lParameterIndex = 1;");
1463: pWriter
1464: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lModifiedRecord."
1465: + lEntityStylesheet
1466: .getVersionIdStorageStructureAttributeName()
1467: + ");");
1468: pWriter
1469: .println(" lCurrentStatement."
1470: + getDataBaseMetaData()
1471: .suggestStatementSetMethod(
1472: lVersionIdDatatype)
1473: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1474: + getUniqueDatatypeName(lVersionIdDatatype)
1475: + "(lModifiedRecord."
1476: + lEntityStylesheet
1477: .getVersionIdStorageStructureAttributeName()
1478: + "));");
1479: if (lHasState) {
1480: pWriter
1481: .println(" if (lModifiedRecord."
1482: + lEntityStylesheet
1483: .getStateStorageStructureAttributeName()
1484: + " != null)");
1485: pWriter.println(" {");
1486: pWriter
1487: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lModifiedRecord."
1488: + lEntityStylesheet
1489: .getStateStorageStructureAttributeName()
1490: + ");");
1491: pWriter
1492: .println(" lCurrentStatement."
1493: + getDataBaseMetaData()
1494: .suggestStatementSetMethod(
1495: lStateDatatype)
1496: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1497: + getUniqueDatatypeName(lStateDatatype)
1498: + "(lModifiedRecord."
1499: + lEntityStylesheet
1500: .getStateStorageStructureAttributeName()
1501: + "));");
1502: pWriter.println(" }");
1503: }
1504: // Deal with attributes
1505: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
1506: .hasNext();) {
1507: Attribute lAttribute = (Attribute) lAttributesIterator
1508: .next();
1509: STAttributeStylesheet lAttributeStylesheet = CodeGenerationStylesheetAccessor
1510: .getAttributeStylesheet(lAttribute);
1511: DataType lAttributeDatatype = lAttribute.getDataType();
1512: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
1513: .getDatatypeTranslationStylesheet(lAttribute
1514: .getDataType());
1515: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
1516: .createFromName(lAttributeDatatypeTranslationStylesheet
1517: .getSqlTypeName());
1518: pWriter
1519: .println(" if (lModifiedRecord."
1520: + lAttributeStylesheet
1521: .getNormalisedName()
1522: + " != null)");
1523: pWriter.println(" {");
1524: if (lAttribute.isOptional()) {
1525: pWriter
1526: .println(" if (lModifiedRecord."
1527: + lAttributeStylesheet
1528: .getNormalisedName()
1529: + ".isEmpty())");
1530: pWriter.println(" {");
1531: pWriter
1532: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" is null\");");
1533: pWriter
1534: .println(" lCurrentStatement.setNull( lParameterIndex++, "
1535: + getDataBaseMetaData()
1536: .suggestJDBCMetadataId(
1537: lAttributeDatatype)
1538: + ");");
1539: pWriter.println(" }");
1540: if (lAttributeDatatypeSqlType
1541: .equals(DataTypeTranslationMetadata.SQL_BLOB) == false
1542: && lAttributeDatatypeSqlType
1543: .equals(DataTypeTranslationMetadata.SQL_CLOB) == false)
1544:
1545: {
1546: pWriter.println(" else");
1547: pWriter.println(" {");
1548: // Limit output at 30 characters we only do it for attributes as other parameters are quite short an also might be important for debugging
1549: pWriter
1550: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + com.metaboss.util.StringUtils.suggestTruncatedOutput(lModifiedRecord."
1551: + lAttributeStylesheet
1552: .getNormalisedName()
1553: + ".toString(),30));");
1554: pWriter
1555: .println(" lCurrentStatement."
1556: + getDataBaseMetaData()
1557: .suggestStatementSetMethod(
1558: lAttributeDatatype)
1559: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1560: + getUniqueDatatypeName(lAttributeDatatype)
1561: + "(lModifiedRecord."
1562: + lAttributeStylesheet
1563: .getNormalisedName()
1564: + "));");
1565: pWriter.println(" }");
1566: }
1567: } else {
1568: if (lAttributeDatatypeSqlType
1569: .equals(DataTypeTranslationMetadata.SQL_BLOB) == false
1570: && lAttributeDatatypeSqlType
1571: .equals(DataTypeTranslationMetadata.SQL_CLOB) == false)
1572:
1573: {
1574: // Limit output at 30 characters we only do it for attributes as other parameters are quite short an also might be important for debugging
1575: pWriter
1576: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + com.metaboss.util.StringUtils.suggestTruncatedOutput(lModifiedRecord."
1577: + lAttributeStylesheet
1578: .getNormalisedName()
1579: + ".toString(),30));");
1580: pWriter
1581: .println(" lCurrentStatement."
1582: + getDataBaseMetaData()
1583: .suggestStatementSetMethod(
1584: lAttributeDatatype)
1585: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1586: + getUniqueDatatypeName(lAttributeDatatype)
1587: + "(lModifiedRecord."
1588: + lAttributeStylesheet
1589: .getNormalisedName()
1590: + "));");
1591: }
1592: }
1593: pWriter.println(" }");
1594: }
1595: // Deal with associations
1596: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
1597: .hasNext();) {
1598: AssociationRole lRole = (AssociationRole) lReferencesIterator
1599: .next();
1600: // Association constraint is only necessary if this entity has a reference
1601: if (CommonUtil.doesEntityStoreReference(lRole)) {
1602: DataType lRoleEntityInstanceIdDatatype = lRole
1603: .getEntity().getInstanceIdDataType();
1604: pWriter
1605: .println(" if (lModifiedRecord."
1606: + lRole.getName()
1607: + "InstanceId != null)");
1608: pWriter.println(" {");
1609: if (lRole.isOptional()) {
1610: pWriter
1611: .println(" if (lModifiedRecord."
1612: + lRole.getName()
1613: + "InstanceId.isEmpty())");
1614: pWriter.println(" {");
1615: pWriter
1616: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" is null\");");
1617: pWriter
1618: .println(" lCurrentStatement.setNull( lParameterIndex++, "
1619: + getDataBaseMetaData()
1620: .suggestJDBCMetadataId(
1621: lRoleEntityInstanceIdDatatype)
1622: + ");");
1623: pWriter.println(" }");
1624: pWriter.println(" else");
1625: pWriter.println(" {");
1626: pWriter
1627: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lModifiedRecord."
1628: + lRole.getName()
1629: + "InstanceId);");
1630: pWriter
1631: .println(" lCurrentStatement."
1632: + getDataBaseMetaData()
1633: .suggestStatementSetMethod(
1634: lRoleEntityInstanceIdDatatype)
1635: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1636: + getUniqueDatatypeName(lRoleEntityInstanceIdDatatype)
1637: + "(lModifiedRecord."
1638: + lRole.getName()
1639: + "InstanceId));");
1640: pWriter.println(" }");
1641: } else {
1642: pWriter
1643: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lModifiedRecord."
1644: + lRole.getName()
1645: + "InstanceId);");
1646: pWriter
1647: .println(" lCurrentStatement."
1648: + getDataBaseMetaData()
1649: .suggestStatementSetMethod(
1650: lRoleEntityInstanceIdDatatype)
1651: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1652: + getUniqueDatatypeName(lRoleEntityInstanceIdDatatype)
1653: + "(lModifiedRecord."
1654: + lRole.getName()
1655: + "InstanceId));");
1656: }
1657: pWriter.println(" }");
1658: }
1659: }
1660: pWriter
1661: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lModifiedRecord."
1662: + lEntityStylesheet
1663: .getInstanceIdStorageStructureAttributeName()
1664: + ");");
1665: pWriter
1666: .println(" lCurrentStatement."
1667: + getDataBaseMetaData()
1668: .suggestStatementSetMethod(
1669: lInstanceIdDatatype)
1670: + "( lParameterIndex++, TypesConvertor.getSqlValueFrom"
1671: + getUniqueDatatypeName(lInstanceIdDatatype)
1672: + "(lModifiedRecord."
1673: + lEntityStylesheet
1674: .getInstanceIdStorageStructureAttributeName()
1675: + "));");
1676: pWriter
1677: .println(" "
1678: + lVersionIdDatatypeStylesheet
1679: .getClassFullName()
1680: + " lPreviousVersionId = lModifiedRecord."
1681: + lEntityStylesheet
1682: .getVersionIdStorageStructureAttributeName()
1683: + ".getPrevious();");
1684: pWriter
1685: .println(" sLogger.debug(\"Parameter \" + lParameterIndex + \" value: \" + lPreviousVersionId);");
1686: pWriter
1687: .println(" lCurrentStatement."
1688: + getDataBaseMetaData()
1689: .suggestStatementSetMethod(
1690: lVersionIdDatatype)
1691: + "(lParameterIndex++, TypesConvertor.getSqlValueFrom"
1692: + getUniqueDatatypeName(lVersionIdDatatype)
1693: + "(lPreviousVersionId));");
1694: if (lUpdateInBatches) {
1695: pWriter
1696: .println(" lCurrentStatement.addBatch();");
1697: pWriter.println(" }");
1698: pWriter
1699: .println(" int[] lBatchResult = lCurrentStatement.executeBatch();");
1700: pWriter
1701: .println(" lCurrentStatement.close();");
1702: pWriter
1703: .println(" lCurrentStatement = null;");
1704: // Verify that every statement has resulted in one and only one update
1705: pWriter
1706: .println(" for (int lBatchResultIndex = 0; lBatchResultIndex < lBatchResult.length; lBatchResultIndex++)");
1707: pWriter.println(" {");
1708: pWriter
1709: .println(" if (lBatchResult[lBatchResultIndex] != 1)");
1710: pWriter
1711: .println(" throw new PSUpdateDataIntegrityViolationException(\"Unable to update "
1712: + pEntity.getName()
1713: + " record with Instance Id \" + pModifiedRecords[lCurrentBatchBaseIndex + lBatchResultIndex].InstanceId);");
1714: pWriter.println(" }");
1715: } else {
1716: pWriter
1717: .println(" if (lCurrentStatement.executeUpdate() != 1)");
1718: pWriter
1719: .println(" throw new PSUpdateDataIntegrityViolationException(\"Unable to update "
1720: + pEntity.getName()
1721: + " record with Instance Id \" + pModifiedRecords[i].InstanceId);");
1722: pWriter.println(" }");
1723: pWriter
1724: .println(" lCurrentStatement.close();");
1725: pWriter
1726: .println(" lCurrentStatement = null;");
1727: }
1728: if (lHasBlobs || lHasClobs) {
1729: pWriter.println(" // Look after Lobs");
1730: pWriter
1731: .println(" if (lLobOperations != null)");
1732: pWriter
1733: .println(" save"
1734: + pEntity.getName()
1735: + "Lobs(pConnection, (LobOperationDetail[])lLobOperations.toArray(new LobOperationDetail[lLobOperations.size()]));");
1736: }
1737: pWriter.println(" }");
1738: pWriter.println(" finally");
1739: pWriter.println(" {");
1740: pWriter
1741: .println(" if (lCurrentStatement != null)");
1742: pWriter
1743: .println(" lCurrentStatement.close();");
1744: pWriter.println(" }");
1745: pWriter.println(" }");
1746: pWriter
1747: .println(" catch(DataTypeInvalidOperationForEmptyInstanceException e)");
1748: pWriter.println(" {");
1749: pWriter
1750: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code must check for empty instance\",e);");
1751: pWriter.println(" }");
1752: pWriter
1753: .println(" catch(DataTypeInvalidOperationForConcealedInstanceException e)");
1754: pWriter.println(" {");
1755: pWriter
1756: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code must check for concealed instance\",e);");
1757: pWriter.println(" }");
1758: writeSQLExceptionHandlerForUpdateEntity(pWriter, pEntity,
1759: lEntityTable);
1760: pWriter.println(" }");
1761: }
1762: }
1763:
1764: // This hepler writes out additional helper methods may be required by the derived implementation generators
1765: // This hepler writes out the helper method to save lobs into the entity record
1766: // Oracle has somewhat specific implementation of this (may be it can use generic too - need to check)
1767: protected void writeOptionalServiceImplementationHelpers(
1768: PrintWriter pWriter, Entity pEntity,
1769: DomainRelationalStorageDefinition pDomainStorage)
1770: throws BOException, BSException {
1771: STEntityStylesheet lEntityStylesheet = CodeGenerationStylesheetAccessor
1772: .getEntityStylesheet(pEntity);
1773: Collection lAttributes = pEntity.getAttributes();
1774: // Find out if this entity has LOBs (can only be in attributes)
1775: boolean lHasBlobs = false;
1776: boolean lHasClobs = false;
1777: for (Iterator lAttributesIterator = lAttributes.iterator(); ((lHasBlobs == false) || (lHasClobs == false))
1778: && (lAttributesIterator.hasNext());) {
1779: Attribute lAttribute = (Attribute) lAttributesIterator
1780: .next();
1781: STDatatypeTranslationStylesheet lAttributeDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
1782: .getDatatypeTranslationStylesheet(lAttribute
1783: .getDataType());
1784: DataTypeTranslationMetadata.SqlType lAttributeDatatypeSqlType = DataTypeTranslationMetadata.SqlType
1785: .createFromName(lAttributeDatatypeTranslationStylesheet
1786: .getSqlTypeName());
1787: if (lAttributeDatatypeSqlType
1788: .equals(DataTypeTranslationMetadata.SQL_BLOB))
1789: lHasBlobs = true;
1790: else if (lAttributeDatatypeSqlType
1791: .equals(DataTypeTranslationMetadata.SQL_CLOB))
1792: lHasClobs = true;
1793: }
1794:
1795: if (lHasBlobs || lHasClobs) {
1796: RelationalEntityTable lEntityTable = pDomainStorage
1797: .getEntityTable(pEntity);
1798: String lEntityTableName = lEntityTable.getNameOverride();
1799: if (lEntityTableName == null
1800: || lEntityTableName.length() == 0)
1801: lEntityTableName = lEntityTable.getNameSuggestion();
1802: String lInstanceIdColumnName = lEntityTable
1803: .getInstanceIdColumnNameOverride();
1804: if (lInstanceIdColumnName == null
1805: || lInstanceIdColumnName.length() == 0)
1806: lInstanceIdColumnName = lEntityTable
1807: .getInstanceIdColumnNameSuggestion();
1808:
1809: pWriter.println(" // Helper. Saves pending lob updates");
1810: pWriter
1811: .println(" private void save"
1812: + pEntity.getName()
1813: + "Lobs(java.sql.Connection pDatabaseConnection, LobOperationDetail[] pLobOperations) throws PSException");
1814: pWriter.println(" {");
1815: pWriter.println(" try");
1816: pWriter.println(" {");
1817: pWriter
1818: .println(" java.sql.PreparedStatement lStatement = null;");
1819: pWriter
1820: .println(" java.sql.ResultSet lResultSet = null;");
1821: pWriter.println(" try");
1822: pWriter.println(" {");
1823: pWriter
1824: .println(" StringBuffer lSelectLocatorsStatementText = new StringBuffer();");
1825: pWriter
1826: .println(" for (int i = 0; i < pLobOperations.length; i++)");
1827: pWriter.println(" {");
1828: pWriter
1829: .println(" LobOperationDetail lLobOperationDetail = pLobOperations[i];");
1830: pWriter
1831: .println(" lSelectLocatorsStatementText.setLength(0);");
1832: pWriter
1833: .println(" lSelectLocatorsStatementText.append(\"SELECT \");");
1834: pWriter
1835: .println(" Iterator lColumnNamesIter = lLobOperationDetail.ColumnNames.iterator();");
1836: pWriter.println(" while(true)");
1837: pWriter.println(" {");
1838: pWriter
1839: .println(" lSelectLocatorsStatementText.append((String)lColumnNamesIter.next());");
1840: pWriter
1841: .println(" if (!lColumnNamesIter.hasNext())");
1842: pWriter.println(" break;");
1843: pWriter
1844: .println(" lSelectLocatorsStatementText.append(\",\");");
1845: pWriter.println(" }");
1846: pWriter
1847: .println(" lSelectLocatorsStatementText.append(\" FROM "
1848: + lEntityTableName
1849: + " WHERE "
1850: + lInstanceIdColumnName + " = ?\");");
1851: pWriter
1852: .println(" String lSelectLocatorsStatementString = lSelectLocatorsStatementText.toString();");
1853: pWriter
1854: .println(" sLogger.debug(\"About to execute SQL statement: \" + lSelectLocatorsStatementString + \";\");");
1855: pWriter
1856: .println(" lStatement = pDatabaseConnection.prepareStatement(lSelectLocatorsStatementString);");
1857: pWriter
1858: .println(" sLogger.debug(\"Parameter 1 value: \" + lLobOperationDetail.InstanceId);");
1859: pWriter
1860: .println(" lStatement.setString(1, TypesConvertor.getSqlValueFrom"
1861: + getUniqueDatatypeName(pEntity
1862: .getInstanceIdDataType())
1863: + "(lLobOperationDetail.InstanceId));");
1864: pWriter
1865: .println(" lResultSet = lStatement.executeQuery();");
1866: pWriter
1867: .println(" if (!lResultSet.next())");
1868: pWriter
1869: .println(" throw new PSUnexpectedProgramConditionException(\"Unable to fetch lob locators details from the "
1870: + lEntityTableName + " table\");");
1871: pWriter
1872: .println(" Iterator lColumnDataIter = lLobOperationDetail.ColumnData.iterator();");
1873: pWriter
1874: .println(" for (int j = 1; lColumnDataIter.hasNext(); j++)");
1875: pWriter.println(" {");
1876: if (lHasBlobs && (!lHasClobs)) {
1877: // Only blobs
1878: pWriter
1879: .println(" oracle.sql.BLOB lBlob = (oracle.sql.BLOB)lResultSet.getBlob(j);");
1880: pWriter
1881: .println(" java.io.OutputStream lOutputStream = lBlob.getBinaryOutputStream();");
1882: pWriter
1883: .println(" lOutputStream.write((byte[])lColumnDataIter.next());");
1884: pWriter
1885: .println(" lOutputStream.flush();");
1886: } else if ((!lHasBlobs) && lHasClobs) {
1887: // Only clobs
1888: pWriter
1889: .println(" oracle.sql.CLOB lClob = (oracle.sql.CLOB)lResultSet.getClob(j);");
1890: pWriter
1891: .println(" java.io.Writer lWriter = lClob.getCharacterOutputStream();");
1892: pWriter
1893: .println(" lWriter.write((String)lColumnDataIter.next());");
1894: pWriter
1895: .println(" lWriter.flush();");
1896: } else {
1897: // Distringuish between clobs and blobs based on the type of data
1898: // String for clobs and byte[] for blobs
1899: pWriter
1900: .println(" Object lDataToSave = lColumnDataIter.next();");
1901: pWriter
1902: .println(" if (lDataToSave instanceof String)");
1903: pWriter.println(" {");
1904: pWriter
1905: .println(" oracle.sql.CLOB lClob = (oracle.sql.CLOB)lResultSet.getClob(j);");
1906: pWriter
1907: .println(" java.io.Writer lWriter = lClob.getCharacterOutputStream();");
1908: pWriter
1909: .println(" lWriter.write((String)lDataToSave);");
1910: pWriter
1911: .println(" lWriter.flush();");
1912: pWriter.println(" }");
1913: pWriter.println(" else");
1914: pWriter
1915: .println(" if (lDataToSave.getClass().isArray() && lDataToSave.getClass().getComponentType().equals(Byte.TYPE))");
1916: pWriter.println(" {");
1917: pWriter
1918: .println(" oracle.sql.BLOB lBlob = (oracle.sql.BLOB)lResultSet.getBlob(j);");
1919: pWriter
1920: .println(" java.io.OutputStream lOutputStream = lBlob.getBinaryOutputStream();");
1921: pWriter
1922: .println(" lOutputStream.write((byte[])lDataToSave);");
1923: pWriter
1924: .println(" lOutputStream.flush();");
1925: pWriter.println(" }");
1926: pWriter.println(" else");
1927: pWriter
1928: .println(" throw new PSUnexpectedProgramConditionException(\"Unexpected data type supplied to save"
1929: + pEntity.getName()
1930: + "Lobs() operation\");");
1931: }
1932: pWriter.println(" }");
1933: pWriter.println(" lStatement.close();");
1934: pWriter.println(" lStatement = null;");
1935: pWriter.println(" lResultSet.close();");
1936: pWriter.println(" lResultSet = null;");
1937: pWriter.println(" }");
1938: pWriter.println(" }");
1939: pWriter.println(" finally");
1940: pWriter.println(" {");
1941: pWriter.println(" if (lStatement != null)");
1942: pWriter.println(" lStatement.close();");
1943: pWriter.println(" if (lResultSet != null)");
1944: pWriter.println(" lResultSet.close();");
1945: pWriter.println(" }");
1946: pWriter.println(" }");
1947: pWriter
1948: .println(" catch(DataTypeInvalidOperationForEmptyInstanceException e)");
1949: pWriter.println(" {");
1950: pWriter
1951: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code checks for empty instance\",e);");
1952: pWriter.println(" }");
1953: pWriter
1954: .println(" catch(DataTypeInvalidOperationForConcealedInstanceException e)");
1955: pWriter.println(" {");
1956: pWriter
1957: .println(" throw new PSUnexpectedProgramConditionException(\"Should not occur as generated code checks for concealed instance\",e);");
1958: pWriter.println(" }");
1959: pWriter.println(" catch(java.io.IOException e)");
1960: pWriter.println(" {");
1961: pWriter
1962: .print(" throw new PSException(\"java.io.IOException caught while saving lobs from the the ");
1963: pWriter.print(lEntityStylesheet.getStorageRecordFullName());
1964: pWriter.println("\", e);");
1965: pWriter.println(" }");
1966: pWriter.println(" catch(java.sql.SQLException e)");
1967: pWriter.println(" {");
1968: pWriter
1969: .println(" throw new PSDataSourceOperationInvocationException(\"Error while trying to save Lobs from "
1970: + lEntityStylesheet
1971: .getStorageRecordFullName()
1972: + "\", e);");
1973: pWriter.println(" }");
1974: pWriter.println(" }");
1975: }
1976: }
1977: }
|