0001: /*
0002: * $Id: DatabaseUtil.java,v 1.12 2004/02/03 08:14:41 jonesde Exp $
0003: *
0004: * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
0005: *
0006: * Permission is hereby granted, free of charge, to any person obtaining a
0007: * copy of this software and associated documentation files (the "Software"),
0008: * to deal in the Software without restriction, including without limitation
0009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010: * and/or sell copies of the Software, and to permit persons to whom the
0011: * Software is furnished to do so, subject to the following conditions:
0012: *
0013: * The above copyright notice and this permission notice shall be included
0014: * in all copies or substantial portions of the Software.
0015: *
0016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
0021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
0022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023: */
0024: package org.ofbiz.entity.jdbc;
0025:
0026: import java.sql.*;
0027: import java.util.*;
0028:
0029: import org.ofbiz.base.util.*;
0030: import org.ofbiz.entity.*;
0031: import org.ofbiz.entity.config.*;
0032: import org.ofbiz.entity.model.*;
0033:
0034: /**
0035: * Utilities for Entity Database Maintenance
0036: *
0037: * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
0038: * @version $Revision: 1.12 $
0039: * @since 2.0
0040: */
0041: public class DatabaseUtil {
0042:
0043: public static final String module = DatabaseUtil.class.getName();
0044:
0045: protected String helperName;
0046: protected ModelFieldTypeReader modelFieldTypeReader;
0047: protected EntityConfigUtil.DatasourceInfo datasourceInfo;
0048:
0049: public DatabaseUtil(String helperName) {
0050: this .helperName = helperName;
0051: this .modelFieldTypeReader = ModelFieldTypeReader
0052: .getModelFieldTypeReader(helperName);
0053: this .datasourceInfo = EntityConfigUtil
0054: .getDatasourceInfo(helperName);
0055: }
0056:
0057: protected Connection getConnection() throws SQLException,
0058: GenericEntityException {
0059: Connection connection = ConnectionFactory
0060: .getConnection(helperName);
0061: connection.setAutoCommit(true);
0062: return connection;
0063: }
0064:
0065: public EntityConfigUtil.DatasourceInfo getDatasourceInfo() {
0066: return this .datasourceInfo;
0067: }
0068:
0069: /* ====================================================================== */
0070:
0071: /* ====================================================================== */
0072:
0073: public void checkDb(Map modelEntities, List messages,
0074: boolean addMissing) {
0075: UtilTimer timer = new UtilTimer();
0076: timer.timerString("Start - Before Get Database Meta Data");
0077:
0078: // get ALL tables from this database
0079: TreeSet tableNames = this .getTableNames(messages);
0080: TreeSet fkTableNames = tableNames == null ? null : new TreeSet(
0081: tableNames);
0082: TreeSet indexTableNames = tableNames == null ? null
0083: : new TreeSet(tableNames);
0084:
0085: if (tableNames == null) {
0086: String message = "Could not get table name information from the database, aborting.";
0087: if (messages != null)
0088: messages.add(message);
0089: Debug.logError(message, module);
0090: return;
0091: }
0092: timer.timerString("After Get All Table Names");
0093:
0094: // get ALL column info, put into hashmap by table name
0095: Map colInfo = this .getColumnInfo(tableNames, messages);
0096: if (colInfo == null) {
0097: String message = "Could not get column information from the database, aborting.";
0098: if (messages != null)
0099: messages.add(message);
0100: Debug.logError(message, module);
0101: return;
0102: }
0103: timer.timerString("After Get All Column Info");
0104:
0105: // -make sure all entities have a corresponding table
0106: // -list all tables that do not have a corresponding entity
0107: // -display message if number of table columns does not match number of entity fields
0108: // -list all columns that do not have a corresponding field
0109: // -make sure each corresponding column is of the correct type
0110: // -list all fields that do not have a corresponding column
0111:
0112: timer.timerString("Before Individual Table/Column Check");
0113:
0114: ArrayList modelEntityList = new ArrayList(modelEntities
0115: .values());
0116: // sort using compareTo method on ModelEntity
0117: Collections.sort(modelEntityList);
0118: Iterator modelEntityIter = modelEntityList.iterator();
0119: int curEnt = 0;
0120: int totalEnt = modelEntityList.size();
0121: List entitiesAdded = new LinkedList();
0122: while (modelEntityIter.hasNext()) {
0123: curEnt++;
0124: ModelEntity entity = (ModelEntity) modelEntityIter.next();
0125:
0126: // if this is a view entity, do not check it...
0127: if (entity instanceof ModelViewEntity) {
0128: String entMessage = "(" + timer.timeSinceLast()
0129: + "ms) NOT Checking #" + curEnt + "/"
0130: + totalEnt + " View Entity "
0131: + entity.getEntityName();
0132: Debug.logVerbose(entMessage, module);
0133: if (messages != null)
0134: messages.add(entMessage);
0135: continue;
0136: }
0137:
0138: String entMessage = "(" + timer.timeSinceLast()
0139: + "ms) Checking #" + curEnt + "/" + totalEnt
0140: + " Entity " + entity.getEntityName()
0141: + " with table "
0142: + entity.getTableName(datasourceInfo);
0143:
0144: Debug.logVerbose(entMessage, module);
0145: if (messages != null)
0146: messages.add(entMessage);
0147:
0148: // -make sure all entities have a corresponding table
0149: if (tableNames
0150: .contains(entity.getTableName(datasourceInfo))) {
0151: tableNames.remove(entity.getTableName(datasourceInfo));
0152:
0153: if (colInfo != null) {
0154: Map fieldColNames = new HashMap();
0155: for (int fnum = 0; fnum < entity.getFieldsSize(); fnum++) {
0156: ModelField field = entity.getField(fnum);
0157: fieldColNames.put(field.getColName(), field);
0158: }
0159:
0160: List colList = (List) colInfo.get(entity
0161: .getTableName(datasourceInfo));
0162: int numCols = 0;
0163:
0164: if (colList != null) {
0165: for (; numCols < colList.size(); numCols++) {
0166: ColumnCheckInfo ccInfo = (ColumnCheckInfo) colList
0167: .get(numCols);
0168:
0169: // -list all columns that do not have a corresponding field
0170: if (fieldColNames
0171: .containsKey(ccInfo.columnName)) {
0172: ModelField field = null;
0173:
0174: field = (ModelField) fieldColNames
0175: .remove(ccInfo.columnName);
0176: ModelFieldType modelFieldType = modelFieldTypeReader
0177: .getModelFieldType(field
0178: .getType());
0179:
0180: if (modelFieldType != null) {
0181: // make sure each corresponding column is of the correct type
0182: String fullTypeStr = modelFieldType
0183: .getSqlType();
0184: String typeName;
0185: int columnSize = -1;
0186: int decimalDigits = -1;
0187:
0188: int openParen = fullTypeStr
0189: .indexOf('(');
0190: int closeParen = fullTypeStr
0191: .indexOf(')');
0192: int comma = fullTypeStr
0193: .indexOf(',');
0194:
0195: if (openParen > 0 && closeParen > 0
0196: && closeParen > openParen) {
0197: typeName = fullTypeStr
0198: .substring(0, openParen);
0199: if (comma > 0
0200: && comma > openParen
0201: && comma < closeParen) {
0202: String csStr = fullTypeStr
0203: .substring(
0204: openParen + 1,
0205: comma);
0206: try {
0207: columnSize = Integer
0208: .parseInt(csStr);
0209: } catch (NumberFormatException e) {
0210: Debug.logError(e,
0211: module);
0212: }
0213:
0214: String ddStr = fullTypeStr
0215: .substring(
0216: comma + 1,
0217: closeParen);
0218: try {
0219: decimalDigits = Integer
0220: .parseInt(ddStr);
0221: } catch (NumberFormatException e) {
0222: Debug.logError(e,
0223: module);
0224: }
0225: } else {
0226: String csStr = fullTypeStr
0227: .substring(
0228: openParen + 1,
0229: closeParen);
0230: try {
0231: columnSize = Integer
0232: .parseInt(csStr);
0233: } catch (NumberFormatException e) {
0234: Debug.logError(e,
0235: module);
0236: }
0237: }
0238: } else {
0239: typeName = fullTypeStr;
0240: }
0241:
0242: // override the default typeName with the sqlTypeAlias if it is specified
0243: if (UtilValidate
0244: .isNotEmpty(modelFieldType
0245: .getSqlTypeAlias())) {
0246: typeName = modelFieldType
0247: .getSqlTypeAlias();
0248: }
0249:
0250: // NOTE: this may need a toUpperCase in some cases, keep an eye on it, okay just compare with ignore case
0251: if (!ccInfo.typeName
0252: .equalsIgnoreCase(typeName)) {
0253: String message = "WARNING: Column \""
0254: + ccInfo.columnName
0255: + "\" of table \""
0256: + entity
0257: .getTableName(datasourceInfo)
0258: + "\" of entity \""
0259: + entity
0260: .getEntityName()
0261: + "\" is of type \""
0262: + ccInfo.typeName
0263: + "\" in the database, but is defined as type \""
0264: + typeName
0265: + "\" in the entity definition.";
0266: Debug.logError(message, module);
0267: if (messages != null)
0268: messages.add(message);
0269: }
0270: if (columnSize != -1
0271: && ccInfo.columnSize != -1
0272: && columnSize != ccInfo.columnSize) {
0273: String message = "WARNING: Column \""
0274: + ccInfo.columnName
0275: + "\" of table \""
0276: + entity
0277: .getTableName(datasourceInfo)
0278: + "\" of entity \""
0279: + entity
0280: .getEntityName()
0281: + "\" has a column size of \""
0282: + ccInfo.columnSize
0283: + "\" in the database, but is defined to have a column size of \""
0284: + columnSize
0285: + "\" in the entity definition.";
0286: Debug.logWarning(message,
0287: module);
0288: if (messages != null)
0289: messages.add(message);
0290: }
0291: if (decimalDigits != -1
0292: && decimalDigits != ccInfo.decimalDigits) {
0293: String message = "WARNING: Column \""
0294: + ccInfo.columnName
0295: + "\" of table \""
0296: + entity
0297: .getTableName(datasourceInfo)
0298: + "\" of entity \""
0299: + entity
0300: .getEntityName()
0301: + "\" has a decimalDigits of \""
0302: + ccInfo.decimalDigits
0303: + "\" in the database, but is defined to have a decimalDigits of \""
0304: + decimalDigits
0305: + "\" in the entity definition.";
0306: Debug.logWarning(message,
0307: module);
0308: if (messages != null)
0309: messages.add(message);
0310: }
0311: } else {
0312: String message = "Column \""
0313: + ccInfo.columnName
0314: + "\" of table \""
0315: + entity
0316: .getTableName(datasourceInfo)
0317: + "\" of entity \""
0318: + entity.getEntityName()
0319: + "\" has a field type name of \""
0320: + field.getType()
0321: + "\" which is not found in the field type definitions";
0322: Debug.logError(message, module);
0323: if (messages != null)
0324: messages.add(message);
0325: }
0326: } else {
0327: String message = "Column \""
0328: + ccInfo.columnName
0329: + "\" of table \""
0330: + entity
0331: .getTableName(datasourceInfo)
0332: + "\" of entity \""
0333: + entity.getEntityName()
0334: + "\" exists in the database but has no corresponding field";
0335: Debug.logWarning(message, module);
0336: if (messages != null)
0337: messages.add(message);
0338: }
0339: }
0340: }
0341:
0342: // -display message if number of table columns does not match number of entity fields
0343: if (numCols != entity.getFieldsSize()) {
0344: String message = "Entity \""
0345: + entity.getEntityName() + "\" has "
0346: + entity.getFieldsSize()
0347: + " fields but table \""
0348: + entity.getTableName(datasourceInfo)
0349: + "\" has " + numCols + " columns.";
0350: Debug.logWarning(message, module);
0351: if (messages != null)
0352: messages.add(message);
0353: }
0354:
0355: // -list all fields that do not have a corresponding column
0356: Iterator fcnIter = fieldColNames.keySet()
0357: .iterator();
0358: while (fcnIter.hasNext()) {
0359: String colName = (String) fcnIter.next();
0360: ModelField field = (ModelField) fieldColNames
0361: .get(colName);
0362: String message = "Field \""
0363: + field.getName()
0364: + "\" of entity \""
0365: + entity.getEntityName()
0366: + "\" is missing its corresponding column \""
0367: + field.getColName() + "\"";
0368:
0369: Debug.logWarning(message, module);
0370: if (messages != null)
0371: messages.add(message);
0372:
0373: if (addMissing) {
0374: // add the column
0375: String errMsg = addColumn(entity, field);
0376:
0377: if (errMsg != null && errMsg.length() > 0) {
0378: message = "Could not add column \""
0379: + field.getColName()
0380: + "\" to table \""
0381: + entity
0382: .getTableName(datasourceInfo)
0383: + "\": " + errMsg;
0384: Debug.logError(message, module);
0385: if (messages != null)
0386: messages.add(message);
0387: } else {
0388: message = "Added column \""
0389: + field.getColName()
0390: + "\" to table \""
0391: + entity
0392: .getTableName(datasourceInfo)
0393: + "\"";
0394: Debug.logImportant(message, module);
0395: if (messages != null)
0396: messages.add(message);
0397: }
0398: }
0399: }
0400: }
0401: } else {
0402: String message = "Entity \"" + entity.getEntityName()
0403: + "\" has no table in the database";
0404: Debug.logWarning(message, module);
0405: if (messages != null)
0406: messages.add(message);
0407:
0408: if (addMissing) {
0409: // create the table
0410: String errMsg = createTable(entity, modelEntities,
0411: false, datasourceInfo.usePkConstraintNames,
0412: datasourceInfo.constraintNameClipLength,
0413: datasourceInfo.fkStyle,
0414: datasourceInfo.useFkInitiallyDeferred);
0415: if (errMsg != null && errMsg.length() > 0) {
0416: message = "Could not create table \""
0417: + entity.getTableName(datasourceInfo)
0418: + "\": " + errMsg;
0419: Debug.logError(message, module);
0420: if (messages != null)
0421: messages.add(message);
0422: } else {
0423: entitiesAdded.add(entity);
0424: message = "Created table \""
0425: + entity.getTableName(datasourceInfo)
0426: + "\"";
0427: Debug.logImportant(message, module);
0428: if (messages != null)
0429: messages.add(message);
0430: }
0431: }
0432: }
0433: }
0434:
0435: timer.timerString("After Individual Table/Column Check");
0436:
0437: // -list all tables that do not have a corresponding entity
0438: Iterator tableNamesIter = tableNames.iterator();
0439: while (tableNamesIter != null && tableNamesIter.hasNext()) {
0440: String tableName = (String) tableNamesIter.next();
0441: String message = "Table named \""
0442: + tableName
0443: + "\" exists in the database but has no corresponding entity";
0444: Debug.logWarning(message, module);
0445: if (messages != null)
0446: messages.add(message);
0447: }
0448:
0449: // for each newly added table, add fks
0450: if (datasourceInfo.useFks) {
0451: Iterator eaIter = entitiesAdded.iterator();
0452: while (eaIter.hasNext()) {
0453: ModelEntity curEntity = (ModelEntity) eaIter.next();
0454: this
0455: .createForeignKeys(
0456: curEntity,
0457: modelEntities,
0458: datasourceInfo.constraintNameClipLength,
0459: datasourceInfo.fkStyle,
0460: datasourceInfo.useFkInitiallyDeferred,
0461: messages);
0462: }
0463: }
0464: // for each newly added table, add fk indices
0465: if (datasourceInfo.useFkIndices) {
0466: Iterator eaIter = entitiesAdded.iterator();
0467: while (eaIter.hasNext()) {
0468: ModelEntity curEntity = (ModelEntity) eaIter.next();
0469: String indErrMsg = this .createForeignKeyIndices(
0470: curEntity,
0471: datasourceInfo.constraintNameClipLength);
0472: if (indErrMsg != null && indErrMsg.length() > 0) {
0473: String message = "Could not create foreign key indices for entity \""
0474: + curEntity.getEntityName()
0475: + "\": "
0476: + indErrMsg;
0477: Debug.logError(message, module);
0478: if (messages != null)
0479: messages.add(message);
0480: } else {
0481: String message = "Created foreign key indices for entity \""
0482: + curEntity.getEntityName() + "\"";
0483: Debug.logImportant(message, module);
0484: if (messages != null)
0485: messages.add(message);
0486: }
0487: }
0488: }
0489: // for each newly added table, add declared indexes
0490: if (datasourceInfo.useIndices) {
0491: Iterator eaIter = entitiesAdded.iterator();
0492: while (eaIter.hasNext()) {
0493: ModelEntity curEntity = (ModelEntity) eaIter.next();
0494: String indErrMsg = this
0495: .createDeclaredIndices(curEntity);
0496: if (indErrMsg != null && indErrMsg.length() > 0) {
0497: String message = "Could not create declared indices for entity \""
0498: + curEntity.getEntityName()
0499: + "\": "
0500: + indErrMsg;
0501: Debug.logError(message, module);
0502: if (messages != null)
0503: messages.add(message);
0504: } else {
0505: String message = "Created declared indices for entity \""
0506: + curEntity.getEntityName() + "\"";
0507: Debug.logImportant(message, module);
0508: if (messages != null)
0509: messages.add(message);
0510: }
0511: }
0512: }
0513:
0514: // make sure each one-relation has an FK
0515: if (datasourceInfo.useFks
0516: && datasourceInfo.checkForeignKeysOnStart) {
0517: // NOTE: This ISN'T working for Postgres or MySQL, who knows about others, may be from JDBC driver bugs...
0518: int numFksCreated = 0;
0519: // TODO: check each key-map to make sure it exists in the FK, if any differences warn and then remove FK and recreate it
0520:
0521: // get ALL column info, put into hashmap by table name
0522: Map refTableInfoMap = this .getReferenceInfo(fkTableNames,
0523: messages);
0524:
0525: // Debug.logVerbose("Ref Info Map: " + refTableInfoMap, module);
0526:
0527: if (refTableInfoMap == null) {
0528: // uh oh, something happened while getting info...
0529: if (Debug.verboseOn())
0530: Debug.logVerbose("Ref Table Info Map is null",
0531: module);
0532: } else {
0533: Iterator refModelEntityIter = modelEntityList
0534: .iterator();
0535: while (refModelEntityIter.hasNext()) {
0536: ModelEntity entity = (ModelEntity) refModelEntityIter
0537: .next();
0538: String entityName = entity.getEntityName();
0539: // if this is a view entity, do not check it...
0540: if (entity instanceof ModelViewEntity) {
0541: String entMessage = "NOT Checking View Entity "
0542: + entity.getEntityName();
0543: Debug.logVerbose(entMessage, module);
0544: if (messages != null) {
0545: messages.add(entMessage);
0546: }
0547: continue;
0548: }
0549:
0550: // get existing FK map for this table
0551: Map rcInfoMap = (Map) refTableInfoMap.get(entity
0552: .getTableName(datasourceInfo));
0553: // Debug.logVerbose("Got ref info for table " + entity.getTableName(datasourceInfo) + ": " + rcInfoMap, module);
0554:
0555: // go through each relation to see if an FK already exists
0556: Iterator relations = entity.getRelationsIterator();
0557: boolean createdConstraints = false;
0558: while (relations.hasNext()) {
0559: ModelRelation modelRelation = (ModelRelation) relations
0560: .next();
0561: if (!"one".equals(modelRelation.getType())) {
0562: continue;
0563: }
0564:
0565: ModelEntity relModelEntity = (ModelEntity) modelEntities
0566: .get(modelRelation.getRelEntityName());
0567: String relConstraintName = makeFkConstraintName(
0568: modelRelation,
0569: datasourceInfo.constraintNameClipLength);
0570: ReferenceCheckInfo rcInfo = null;
0571:
0572: if (rcInfoMap != null) {
0573: rcInfo = (ReferenceCheckInfo) rcInfoMap
0574: .get(relConstraintName);
0575: }
0576:
0577: if (rcInfo != null) {
0578: rcInfoMap.remove(relConstraintName);
0579: } else {
0580: // if not, create one
0581: if (Debug.verboseOn())
0582: Debug.logVerbose(
0583: "No Foreign Key Constraint "
0584: + relConstraintName
0585: + " found in entity "
0586: + entityName, module);
0587: String errMsg = createForeignKey(
0588: entity,
0589: modelRelation,
0590: relModelEntity,
0591: datasourceInfo.constraintNameClipLength,
0592: datasourceInfo.fkStyle,
0593: datasourceInfo.useFkInitiallyDeferred);
0594:
0595: if (errMsg != null && errMsg.length() > 0) {
0596: String message = "Could not create foreign key "
0597: + relConstraintName
0598: + " for entity \""
0599: + entity.getEntityName()
0600: + "\": " + errMsg;
0601: Debug.logError(message, module);
0602: if (messages != null)
0603: messages.add(message);
0604: } else {
0605: String message = "Created foreign key "
0606: + relConstraintName
0607: + " for entity \""
0608: + entity.getEntityName() + "\"";
0609: Debug.logVerbose(message, module);
0610: if (messages != null)
0611: messages.add(message);
0612: createdConstraints = true;
0613: numFksCreated++;
0614: }
0615: }
0616: }
0617: if (createdConstraints) {
0618: String message = "Created foreign key(s) for entity \""
0619: + entity.getEntityName() + "\"";
0620: Debug.logImportant(message, module);
0621: if (messages != null)
0622: messages.add(message);
0623: }
0624:
0625: // show foreign key references that exist but are unknown
0626: if (rcInfoMap != null) {
0627: Iterator rcInfoKeysLeft = rcInfoMap.keySet()
0628: .iterator();
0629: while (rcInfoKeysLeft.hasNext()) {
0630: String rcKeyLeft = (String) rcInfoKeysLeft
0631: .next();
0632: String message = "Unknown Foreign Key Constraint "
0633: + rcKeyLeft
0634: + " found in table "
0635: + entity
0636: .getTableName(datasourceInfo);
0637: Debug.logImportant(message, module);
0638: if (messages != null)
0639: messages.add(message);
0640: }
0641: }
0642: }
0643: }
0644: if (Debug.infoOn())
0645: Debug.logInfo("Created " + numFksCreated + " fk refs",
0646: module);
0647: }
0648:
0649: // make sure each one-relation has an index
0650: if (datasourceInfo.useFkIndices
0651: && datasourceInfo.checkFkIndicesOnStart) {
0652: int numIndicesCreated = 0;
0653: // TODO: check each key-map to make sure it exists in the index, if any differences warn and then remove the index and recreate it
0654:
0655: // TODO: also check the declared indices on start, if the datasourceInfo.checkIndicesOnStart flag is set
0656:
0657: // get ALL column info, put into hashmap by table name
0658: Map tableIndexListMap = this .getIndexInfo(indexTableNames,
0659: messages);
0660:
0661: // Debug.logVerbose("Ref Info Map: " + refTableInfoMap, module);
0662:
0663: if (tableIndexListMap == null) {
0664: // uh oh, something happened while getting info...
0665: if (Debug.verboseOn())
0666: Debug.logVerbose("Ref Table Info Map is null",
0667: module);
0668: } else {
0669: Iterator refModelEntityIter = modelEntityList
0670: .iterator();
0671: while (refModelEntityIter.hasNext()) {
0672: ModelEntity entity = (ModelEntity) refModelEntityIter
0673: .next();
0674: String entityName = entity.getEntityName();
0675: // if this is a view entity, do not check it...
0676: if (entity instanceof ModelViewEntity) {
0677: String entMessage = "NOT Checking View Entity "
0678: + entity.getEntityName();
0679: Debug.logVerbose(entMessage, module);
0680: if (messages != null)
0681: messages.add(entMessage);
0682: continue;
0683: }
0684:
0685: // get existing index list for this table
0686: TreeSet tableIndexList = (TreeSet) tableIndexListMap
0687: .get(entity.getTableName(datasourceInfo));
0688:
0689: // Debug.logVerbose("Got ind info for table " + entity.getTableName(datasourceInfo) + ": " + tableIndexList, module);
0690:
0691: if (tableIndexList == null) {
0692: // evidently no indexes in the database for this table, do the create all
0693: String indErrMsg = this
0694: .createForeignKeyIndices(
0695: entity,
0696: datasourceInfo.constraintNameClipLength);
0697: if (indErrMsg != null && indErrMsg.length() > 0) {
0698: String message = "Could not create foreign key indices for entity \""
0699: + entity.getEntityName()
0700: + "\": "
0701: + indErrMsg;
0702: Debug.logError(message, module);
0703: if (messages != null)
0704: messages.add(message);
0705: } else {
0706: String message = "Created foreign key indices for entity \""
0707: + entity.getEntityName() + "\"";
0708: Debug.logImportant(message, module);
0709: if (messages != null)
0710: messages.add(message);
0711: }
0712: } else {
0713: // go through each relation to see if an FK already exists
0714: boolean createdConstraints = false;
0715: Iterator relations = entity
0716: .getRelationsIterator();
0717: while (relations.hasNext()) {
0718: ModelRelation modelRelation = (ModelRelation) relations
0719: .next();
0720: if (!"one".equals(modelRelation.getType())) {
0721: continue;
0722: }
0723:
0724: String relConstraintName = makeFkConstraintName(
0725: modelRelation,
0726: datasourceInfo.constraintNameClipLength);
0727: if (tableIndexList
0728: .contains(relConstraintName)) {
0729: tableIndexList
0730: .remove(relConstraintName);
0731: } else {
0732: // if not, create one
0733: if (Debug.verboseOn())
0734: Debug.logVerbose("No Index "
0735: + relConstraintName
0736: + " found for entity "
0737: + entityName, module);
0738: String errMsg = createForeignKeyIndex(
0739: entity,
0740: modelRelation,
0741: datasourceInfo.constraintNameClipLength);
0742: if (errMsg != null
0743: && errMsg.length() > 0) {
0744: String message = "Could not create foreign key index "
0745: + relConstraintName
0746: + " for entity \""
0747: + entity.getEntityName()
0748: + "\": " + errMsg;
0749: Debug.logError(message, module);
0750: if (messages != null)
0751: messages.add(message);
0752: } else {
0753: String message = "Created foreign key index "
0754: + relConstraintName
0755: + " for entity \""
0756: + entity.getEntityName()
0757: + "\"";
0758: Debug.logVerbose(message, module);
0759: if (messages != null)
0760: messages.add(message);
0761: createdConstraints = true;
0762: numIndicesCreated++;
0763: }
0764: }
0765: }
0766: if (createdConstraints) {
0767: String message = "Created foreign key index/indices for entity \""
0768: + entity.getEntityName() + "\"";
0769: Debug.logImportant(message, module);
0770: if (messages != null)
0771: messages.add(message);
0772: }
0773: }
0774:
0775: // show foreign key references that exist but are unknown
0776: if (tableIndexList != null) {
0777: Iterator tableIndexListIter = tableIndexList
0778: .iterator();
0779: while (tableIndexListIter.hasNext()) {
0780: String indexLeft = (String) tableIndexListIter
0781: .next();
0782: String message = "Unknown Index "
0783: + indexLeft
0784: + " found in table "
0785: + entity
0786: .getTableName(datasourceInfo);
0787: Debug.logImportant(message, module);
0788: if (messages != null)
0789: messages.add(message);
0790: }
0791: }
0792: }
0793: }
0794: if (Debug.infoOn())
0795: Debug.logInfo("Created " + numIndicesCreated
0796: + " indices", module);
0797: }
0798:
0799: timer.timerString("Finished Checking Entity Database");
0800: }
0801:
0802: /** Creates a list of ModelEntity objects based on meta data from the database */
0803: public List induceModelFromDb(Collection messages) {
0804: // get ALL tables from this database
0805: TreeSet tableNames = this .getTableNames(messages);
0806:
0807: // get ALL column info, put into hashmap by table name
0808: Map colInfo = this .getColumnInfo(tableNames, messages);
0809:
0810: // go through each table and make a ModelEntity object, add to list
0811: // for each entity make corresponding ModelField objects
0812: // then print out XML for the entities/fields
0813: List newEntList = new LinkedList();
0814:
0815: boolean isCaseSensitive = false;
0816: DatabaseMetaData dbData = this .getDatabaseMetaData(null,
0817: messages);
0818: if (dbData != null) {
0819: try {
0820: isCaseSensitive = dbData.supportsMixedCaseIdentifiers();
0821: } catch (SQLException e) {
0822: Debug
0823: .logError(
0824: e,
0825: "Error getting db meta data about case sensitive",
0826: module);
0827: }
0828: }
0829:
0830: // iterate over the table names is alphabetical order
0831: Iterator tableNamesIter = new TreeSet(colInfo.keySet())
0832: .iterator();
0833: while (tableNamesIter.hasNext()) {
0834: String tableName = (String) tableNamesIter.next();
0835: List colList = (ArrayList) colInfo.get(tableName);
0836: ModelEntity newEntity = new ModelEntity(tableName, colList,
0837: modelFieldTypeReader, isCaseSensitive);
0838: newEntList.add(newEntity);
0839: }
0840:
0841: return newEntList;
0842: }
0843:
0844: public DatabaseMetaData getDatabaseMetaData(Connection connection,
0845: Collection messages) {
0846: if (connection == null) {
0847: try {
0848: connection = getConnection();
0849: } catch (SQLException sqle) {
0850: String message = "Unable to esablish a connection with the database... Error was:"
0851: + sqle.toString();
0852: Debug.logError(message, module);
0853: if (messages != null)
0854: messages.add(message);
0855: return null;
0856: } catch (GenericEntityException e) {
0857: String message = "Unable to esablish a connection with the database... Error was:"
0858: + e.toString();
0859: Debug.logError(message, module);
0860: if (messages != null)
0861: messages.add(message);
0862: return null;
0863: }
0864: }
0865:
0866: if (connection == null) {
0867: String message = "Unable to esablish a connection with the database, no additional information available.";
0868: Debug.logError(message, module);
0869: if (messages != null)
0870: messages.add(message);
0871: return null;
0872: }
0873:
0874: DatabaseMetaData dbData = null;
0875: try {
0876: dbData = connection.getMetaData();
0877: } catch (SQLException sqle) {
0878: String message = "Unable to get database meta data... Error was:"
0879: + sqle.toString();
0880: Debug.logError(message, module);
0881: if (messages != null) {
0882: messages.add(message);
0883: }
0884: return null;
0885: }
0886:
0887: if (dbData == null) {
0888: Debug
0889: .logWarning(
0890: "Unable to get database meta data; method returned null",
0891: module);
0892: }
0893:
0894: return dbData;
0895: }
0896:
0897: public void printDbMiscData(DatabaseMetaData dbData) {
0898: if (dbData == null) {
0899: return;
0900: }
0901: // Database Info
0902: if (Debug.infoOn()) {
0903: try {
0904: Debug.logInfo("Database Product Name is "
0905: + dbData.getDatabaseProductName(), module);
0906: Debug.logInfo("Database Product Version is "
0907: + dbData.getDatabaseProductVersion(), module);
0908: } catch (SQLException sqle) {
0909: Debug
0910: .logWarning(
0911: "Unable to get Database name & version information",
0912: module);
0913: }
0914: }
0915: // JDBC Driver Info
0916: if (Debug.infoOn()) {
0917: try {
0918: Debug.logInfo("Database Driver Name is "
0919: + dbData.getDriverName(), module);
0920: Debug.logInfo("Database Driver Version is "
0921: + dbData.getDriverVersion(), module);
0922: } catch (SQLException sqle) {
0923: Debug
0924: .logWarning(
0925: "Unable to get Driver name & version information",
0926: module);
0927: }
0928: }
0929: // Db/Driver support settings
0930: if (Debug.infoOn()) {
0931: try {
0932: Debug
0933: .logInfo(
0934: "Database Setting/Support Information (those with a * should be true):",
0935: module);
0936: Debug.logInfo("- supports transactions ["
0937: + dbData.supportsTransactions() + "]*", module);
0938: Debug
0939: .logInfo(
0940: "- isolation None ["
0941: + dbData
0942: .supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE)
0943: + "]", module);
0944: Debug
0945: .logInfo(
0946: "- isolation ReadCommitted ["
0947: + dbData
0948: .supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)
0949: + "]", module);
0950: Debug
0951: .logInfo(
0952: "- isolation ReadUncommitted["
0953: + dbData
0954: .supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)
0955: + "]", module);
0956: Debug
0957: .logInfo(
0958: "- isolation RepeatableRead ["
0959: + dbData
0960: .supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ)
0961: + "]", module);
0962: Debug
0963: .logInfo(
0964: "- isolation Serializable ["
0965: + dbData
0966: .supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)
0967: + "]", module);
0968: Debug.logInfo("- is case sensitive ["
0969: + dbData.supportsMixedCaseIdentifiers() + "]",
0970: module);
0971: Debug.logInfo("- stores LowerCase ["
0972: + dbData.storesLowerCaseIdentifiers() + "]",
0973: module);
0974: Debug.logInfo("- stores MixedCase ["
0975: + dbData.storesMixedCaseIdentifiers() + "]",
0976: module);
0977: Debug.logInfo("- stores UpperCase ["
0978: + dbData.storesUpperCaseIdentifiers() + "]",
0979: module);
0980: Debug.logInfo("- max table name length ["
0981: + dbData.getMaxTableNameLength() + "]", module);
0982: Debug
0983: .logInfo(
0984: "- max column name length ["
0985: + dbData
0986: .getMaxColumnNameLength()
0987: + "]", module);
0988: Debug
0989: .logInfo(
0990: "- max schema name length ["
0991: + dbData
0992: .getMaxSchemaNameLength()
0993: + "]", module);
0994: Debug.logInfo("- concurrent connections ["
0995: + dbData.getMaxConnections() + "]", module);
0996: Debug.logInfo("- concurrent statements ["
0997: + dbData.getMaxStatements() + "]", module);
0998: Debug.logInfo("- ANSI SQL92 Entry ["
0999: + dbData.supportsANSI92EntryLevelSQL() + "]",
1000: module);
1001: Debug.logInfo("- ANSI SQL92 Itermediate ["
1002: + dbData.supportsANSI92IntermediateSQL() + "]",
1003: module);
1004: Debug.logInfo("- ANSI SQL92 Full ["
1005: + dbData.supportsANSI92FullSQL() + "]", module);
1006: Debug
1007: .logInfo(
1008: "- ODBC SQL Grammar Core ["
1009: + dbData
1010: .supportsCoreSQLGrammar()
1011: + "]", module);
1012: Debug.logInfo("- ODBC SQL Grammar Extended["
1013: + dbData.supportsExtendedSQLGrammar() + "]",
1014: module);
1015: Debug.logInfo("- ODBC SQL Grammar Minimum ["
1016: + dbData.supportsMinimumSQLGrammar() + "]",
1017: module);
1018: Debug.logInfo("- outer joins ["
1019: + dbData.supportsOuterJoins() + "]*", module);
1020: Debug.logInfo("- limited outer joins ["
1021: + dbData.supportsLimitedOuterJoins() + "]",
1022: module);
1023: Debug
1024: .logInfo(
1025: "- full outer joins ["
1026: + dbData
1027: .supportsFullOuterJoins()
1028: + "]", module);
1029: Debug.logInfo("- group by ["
1030: + dbData.supportsGroupBy() + "]*", module);
1031: Debug.logInfo("- group by not in select ["
1032: + dbData.supportsGroupByUnrelated() + "]",
1033: module);
1034: Debug
1035: .logInfo(
1036: "- column aliasing ["
1037: + dbData
1038: .supportsColumnAliasing()
1039: + "]", module);
1040: Debug.logInfo("- order by not in select ["
1041: + dbData.supportsOrderByUnrelated() + "]",
1042: module);
1043: // this doesn't work in HSQLDB, other databases? Debug.logInfo("- named parameters [" + dbData.supportsNamedParameters() + "]", module);
1044: Debug.logInfo("- alter table add column ["
1045: + dbData.supportsAlterTableWithAddColumn()
1046: + "]*", module);
1047: Debug.logInfo("- non-nullable column ["
1048: + dbData.supportsNonNullableColumns() + "]*",
1049: module);
1050: } catch (Exception e) {
1051: Debug
1052: .logWarning(
1053: e,
1054: "Unable to get misc. support/setting information",
1055: module);
1056: }
1057: }
1058: }
1059:
1060: public TreeSet getTableNames(Collection messages) {
1061: Connection connection = null;
1062:
1063: try {
1064: connection = getConnection();
1065: } catch (SQLException sqle) {
1066: String message = "Unable to esablish a connection with the database... Error was:"
1067: + sqle.toString();
1068: Debug.logError(message, module);
1069: if (messages != null)
1070: messages.add(message);
1071: return null;
1072: } catch (GenericEntityException e) {
1073: String message = "Unable to esablish a connection with the database... Error was:"
1074: + e.toString();
1075: Debug.logError(message, module);
1076: if (messages != null)
1077: messages.add(message);
1078: return null;
1079: }
1080:
1081: if (connection == null) {
1082: String message = "Unable to esablish a connection with the database, no additional information available.";
1083: Debug.logError(message, module);
1084: if (messages != null)
1085: messages.add(message);
1086: return null;
1087: }
1088:
1089: DatabaseMetaData dbData = this .getDatabaseMetaData(connection,
1090: messages);
1091: if (dbData == null) {
1092: return null;
1093: }
1094:
1095: printDbMiscData(dbData);
1096: if (Debug.infoOn())
1097: Debug.logInfo("Getting Table Info From Database", module);
1098:
1099: // get ALL tables from this database
1100: TreeSet tableNames = new TreeSet();
1101: ResultSet tableSet = null;
1102:
1103: String lookupSchemaName = null;
1104: try {
1105: String[] types = { "TABLE", "VIEW", "ALIAS", "SYNONYM" };
1106: if (dbData.supportsSchemasInTableDefinitions()) {
1107: if (this .datasourceInfo.schemaName != null
1108: && this .datasourceInfo.schemaName.length() > 0) {
1109: lookupSchemaName = this .datasourceInfo.schemaName;
1110: } else {
1111: lookupSchemaName = dbData.getUserName();
1112: }
1113: }
1114: tableSet = dbData.getTables(null, lookupSchemaName, null,
1115: types);
1116: if (tableSet == null) {
1117: Debug.logWarning("getTables returned null set", module);
1118: }
1119: } catch (SQLException sqle) {
1120: String message = "Unable to get list of table information, let's try the create anyway... Error was:"
1121: + sqle.toString();
1122: Debug.logError(message, module);
1123: if (messages != null)
1124: messages.add(message);
1125:
1126: try {
1127: connection.close();
1128: } catch (SQLException sqle2) {
1129: String message2 = "Unable to close database connection, continuing anyway... Error was:"
1130: + sqle2.toString();
1131: Debug.logError(message2, module);
1132: if (messages != null)
1133: messages.add(message2);
1134: }
1135: // we are returning an empty set here because databases like SapDB throw an exception when there are no tables in the database
1136: return tableNames;
1137: }
1138:
1139: try {
1140: boolean needsUpperCase = false;
1141: try {
1142: needsUpperCase = dbData.storesLowerCaseIdentifiers()
1143: || dbData.storesMixedCaseIdentifiers();
1144: } catch (SQLException sqle) {
1145: String message = "Error getting identifier case information... Error was:"
1146: + sqle.toString();
1147: Debug.logError(message, module);
1148: if (messages != null)
1149: messages.add(message);
1150: }
1151: while (tableSet.next()) {
1152: try {
1153: String tableName = tableSet.getString("TABLE_NAME");
1154: // for those databases which do not return the schema name with the table name (pgsql 7.3)
1155: boolean appendSchemaName = false;
1156: if (tableName != null && lookupSchemaName != null
1157: && !tableName.startsWith(lookupSchemaName)) {
1158: appendSchemaName = true;
1159: }
1160: if (needsUpperCase && tableName != null) {
1161: tableName = tableName.toUpperCase();
1162: }
1163: if (appendSchemaName) {
1164: tableName = lookupSchemaName + "." + tableName;
1165: }
1166:
1167: // NOTE: this may need a toUpperCase in some cases, keep an eye on it, okay for now just do a compare with equalsIgnoreCase
1168: String tableType = tableSet.getString("TABLE_TYPE");
1169: // only allow certain table types
1170: if (tableType != null
1171: && !"TABLE".equalsIgnoreCase(tableType)
1172: && !"VIEW".equalsIgnoreCase(tableType)
1173: && !"ALIAS".equalsIgnoreCase(tableType)
1174: && !"SYNONYM".equalsIgnoreCase(tableType)) {
1175: continue;
1176: }
1177:
1178: // String remarks = tableSet.getString("REMARKS");
1179: tableNames.add(tableName);
1180: // if (Debug.infoOn()) Debug.logInfo("Found table named \"" + tableName + "\" of type \"" + tableType + "\" with remarks: " + remarks, module);
1181: } catch (SQLException sqle) {
1182: String message = "Error getting table information... Error was:"
1183: + sqle.toString();
1184: Debug.logError(message, module);
1185: if (messages != null)
1186: messages.add(message);
1187: continue;
1188: }
1189: }
1190: } catch (SQLException sqle) {
1191: String message = "Error getting next table information... Error was:"
1192: + sqle.toString();
1193: Debug.logError(message, module);
1194: if (messages != null)
1195: messages.add(message);
1196: } finally {
1197: try {
1198: tableSet.close();
1199: } catch (SQLException sqle) {
1200: String message = "Unable to close ResultSet for table list, continuing anyway... Error was:"
1201: + sqle.toString();
1202: Debug.logError(message, module);
1203: if (messages != null)
1204: messages.add(message);
1205: }
1206:
1207: try {
1208: connection.close();
1209: } catch (SQLException sqle) {
1210: String message = "Unable to close database connection, continuing anyway... Error was:"
1211: + sqle.toString();
1212: Debug.logError(message, module);
1213: if (messages != null)
1214: messages.add(message);
1215: }
1216: }
1217: return tableNames;
1218: }
1219:
1220: public Map getColumnInfo(Set tableNames, Collection messages) {
1221: // if there are no tableNames, don't even try to get the columns
1222: if (tableNames.size() == 0) {
1223: return new HashMap();
1224: }
1225:
1226: Connection connection = null;
1227: try {
1228: connection = getConnection();
1229: } catch (SQLException sqle) {
1230: String message = "Unable to esablish a connection with the database... Error was:"
1231: + sqle.toString();
1232: Debug.logError(message, module);
1233: if (messages != null)
1234: messages.add(message);
1235: return null;
1236: } catch (GenericEntityException e) {
1237: String message = "Unable to esablish a connection with the database... Error was:"
1238: + e.toString();
1239: Debug.logError(message, module);
1240: if (messages != null)
1241: messages.add(message);
1242: return null;
1243: }
1244:
1245: DatabaseMetaData dbData = null;
1246: try {
1247: dbData = connection.getMetaData();
1248: } catch (SQLException sqle) {
1249: String message = "Unable to get database meta data... Error was:"
1250: + sqle.toString();
1251: Debug.logError(message, module);
1252: if (messages != null)
1253: messages.add(message);
1254:
1255: try {
1256: connection.close();
1257: } catch (SQLException sqle2) {
1258: String message2 = "Unable to close database connection, continuing anyway... Error was:"
1259: + sqle2.toString();
1260: Debug.logError(message2, module);
1261: if (messages != null)
1262: messages.add(message2);
1263: }
1264: return null;
1265: }
1266:
1267: if (Debug.infoOn())
1268: Debug.logInfo("Getting Column Info From Database", module);
1269:
1270: Map colInfo = new HashMap();
1271: String lookupSchemaName = null;
1272: try {
1273: if (dbData.supportsSchemasInTableDefinitions()) {
1274: if (this .datasourceInfo.schemaName != null
1275: && this .datasourceInfo.schemaName.length() > 0) {
1276: lookupSchemaName = this .datasourceInfo.schemaName;
1277: } else {
1278: lookupSchemaName = dbData.getUserName();
1279: }
1280: }
1281:
1282: boolean needsUpperCase = false;
1283: try {
1284: needsUpperCase = dbData.storesLowerCaseIdentifiers()
1285: || dbData.storesMixedCaseIdentifiers();
1286: } catch (SQLException sqle) {
1287: String message = "Error getting identifier case information... Error was:"
1288: + sqle.toString();
1289: Debug.logError(message, module);
1290: if (messages != null)
1291: messages.add(message);
1292: }
1293:
1294: ResultSet rsCols = dbData.getColumns(null,
1295: lookupSchemaName, null, null);
1296: while (rsCols.next()) {
1297: try {
1298: ColumnCheckInfo ccInfo = new ColumnCheckInfo();
1299:
1300: ccInfo.tableName = rsCols.getString("TABLE_NAME");
1301: // for those databases which do not return the schema name with the table name (pgsql 7.3)
1302: boolean appendSchemaName = false;
1303: if (ccInfo.tableName != null
1304: && lookupSchemaName != null
1305: && !ccInfo.tableName
1306: .startsWith(lookupSchemaName)) {
1307: appendSchemaName = true;
1308: }
1309: if (needsUpperCase && ccInfo.tableName != null) {
1310: ccInfo.tableName = ccInfo.tableName
1311: .toUpperCase();
1312: }
1313: if (appendSchemaName) {
1314: ccInfo.tableName = lookupSchemaName + "."
1315: + ccInfo.tableName;
1316: }
1317: // ignore the column info if the table name is not in the list we are concerned with
1318: if (!tableNames.contains(ccInfo.tableName)) {
1319: continue;
1320: }
1321:
1322: ccInfo.columnName = rsCols.getString("COLUMN_NAME");
1323: if (needsUpperCase && ccInfo.columnName != null) {
1324: ccInfo.columnName = ccInfo.columnName
1325: .toUpperCase();
1326: }
1327: // NOTE: this may need a toUpperCase in some cases, keep an eye on it
1328: ccInfo.typeName = rsCols.getString("TYPE_NAME");
1329: ccInfo.columnSize = rsCols.getInt("COLUMN_SIZE");
1330: ccInfo.decimalDigits = rsCols
1331: .getInt("DECIMAL_DIGITS");
1332: // NOTE: this may need a toUpperCase in some cases, keep an eye on it
1333: ccInfo.isNullable = rsCols.getString("IS_NULLABLE");
1334:
1335: List tableColInfo = (List) colInfo
1336: .get(ccInfo.tableName);
1337: if (tableColInfo == null) {
1338: tableColInfo = new ArrayList();
1339: colInfo.put(ccInfo.tableName, tableColInfo);
1340: }
1341: tableColInfo.add(ccInfo);
1342: } catch (SQLException sqle) {
1343: String message = "Error getting column info for column. Error was:"
1344: + sqle.toString();
1345: Debug.logError(message, module);
1346: if (messages != null)
1347: messages.add(message);
1348: continue;
1349: }
1350: }
1351:
1352: try {
1353: rsCols.close();
1354: } catch (SQLException sqle) {
1355: String message = "Unable to close ResultSet for column list, continuing anyway... Error was:"
1356: + sqle.toString();
1357: Debug.logError(message, module);
1358: if (messages != null)
1359: messages.add(message);
1360: }
1361: } catch (SQLException sqle) {
1362: String message = "Error getting column meta data for Error was:"
1363: + sqle.toString() + ". Not checking columns.";
1364: Debug.logError(message, module);
1365: if (messages != null)
1366: messages.add(message);
1367: // we are returning an empty set in this case because databases like SapDB throw an exception when there are no tables in the database
1368: // colInfo = null;
1369: } finally {
1370: try {
1371: connection.close();
1372: } catch (SQLException sqle) {
1373: String message = "Unable to close database connection, continuing anyway... Error was:"
1374: + sqle.toString();
1375: Debug.logError(message, module);
1376: if (messages != null)
1377: messages.add(message);
1378: }
1379: }
1380: return colInfo;
1381: }
1382:
1383: public Map getReferenceInfo(Set tableNames, Collection messages) {
1384: Connection connection = null;
1385: try {
1386: connection = getConnection();
1387: } catch (SQLException sqle) {
1388: String message = "Unable to esablish a connection with the database... Error was:"
1389: + sqle.toString();
1390: Debug.logError(message, module);
1391: if (messages != null)
1392: messages.add(message);
1393: return null;
1394: } catch (GenericEntityException e) {
1395: String message = "Unable to esablish a connection with the database... Error was:"
1396: + e.toString();
1397: Debug.logError(message, module);
1398: if (messages != null)
1399: messages.add(message);
1400: return null;
1401: }
1402:
1403: DatabaseMetaData dbData = null;
1404: try {
1405: dbData = connection.getMetaData();
1406: } catch (SQLException sqle) {
1407: String message = "Unable to get database meta data... Error was:"
1408: + sqle.toString();
1409: Debug.logError(message, module);
1410: if (messages != null)
1411: messages.add(message);
1412:
1413: try {
1414: connection.close();
1415: } catch (SQLException sqle2) {
1416: String message2 = "Unable to close database connection, continuing anyway... Error was:"
1417: + sqle2.toString();
1418: Debug.logError(message2, module);
1419: if (messages != null)
1420: messages.add(message2);
1421: }
1422: return null;
1423: }
1424:
1425: /*
1426: try {
1427: if (Debug.infoOn()) Debug.logInfo("Database Product Name is " + dbData.getDatabaseProductName(), module);
1428: if (Debug.infoOn()) Debug.logInfo("Database Product Version is " + dbData.getDatabaseProductVersion(), module);
1429: } catch (SQLException sqle) {
1430: Debug.logWarning("Unable to get Database name & version information", module);
1431: }
1432: try {
1433: if (Debug.infoOn()) Debug.logInfo("Database Driver Name is " + dbData.getDriverName(), module);
1434: if (Debug.infoOn()) Debug.logInfo("Database Driver Version is " + dbData.getDriverVersion(), module);
1435: } catch (SQLException sqle) {
1436: Debug.logWarning("Unable to get Driver name & version information", module);
1437: }
1438: */
1439:
1440: if (Debug.infoOn())
1441: Debug
1442: .logInfo(
1443: "Getting Foreign Key (Reference) Info From Database",
1444: module);
1445:
1446: Map refInfo = new HashMap();
1447:
1448: try {
1449: // ResultSet rsCols = dbData.getCrossReference(null, null, null, null, null, null);
1450: String lookupSchemaName = null;
1451: if (dbData.supportsSchemasInTableDefinitions()) {
1452: if (this .datasourceInfo.schemaName != null
1453: && this .datasourceInfo.schemaName.length() > 0) {
1454: lookupSchemaName = this .datasourceInfo.schemaName;
1455: } else {
1456: lookupSchemaName = dbData.getUserName();
1457: }
1458: }
1459:
1460: boolean needsUpperCase = false;
1461: try {
1462: needsUpperCase = dbData.storesLowerCaseIdentifiers()
1463: || dbData.storesMixedCaseIdentifiers();
1464: } catch (SQLException sqle) {
1465: String message = "Error getting identifier case information... Error was:"
1466: + sqle.toString();
1467: Debug.logError(message, module);
1468: if (messages != null)
1469: messages.add(message);
1470: }
1471:
1472: ResultSet rsCols = dbData.getImportedKeys(null,
1473: lookupSchemaName, null);
1474: int totalFkRefs = 0;
1475:
1476: // Iterator tableNamesIter = tableNames.iterator();
1477: // while (tableNamesIter.hasNext()) {
1478: // String tableName = (String) tableNamesIter.next();
1479: // ResultSet rsCols = dbData.getImportedKeys(null, null, tableName);
1480: // Debug.logVerbose("Getting imported keys for table " + tableName, module);
1481:
1482: while (rsCols.next()) {
1483: try {
1484: ReferenceCheckInfo rcInfo = new ReferenceCheckInfo();
1485:
1486: rcInfo.pkTableName = rsCols
1487: .getString("PKTABLE_NAME");
1488: if (needsUpperCase && rcInfo.pkTableName != null) {
1489: rcInfo.pkTableName = rcInfo.pkTableName
1490: .toUpperCase();
1491: }
1492: rcInfo.pkColumnName = rsCols
1493: .getString("PKCOLUMN_NAME");
1494: if (needsUpperCase && rcInfo.pkColumnName != null) {
1495: rcInfo.pkColumnName = rcInfo.pkColumnName
1496: .toUpperCase();
1497: }
1498:
1499: rcInfo.fkTableName = rsCols
1500: .getString("FKTABLE_NAME");
1501: if (needsUpperCase && rcInfo.fkTableName != null) {
1502: rcInfo.fkTableName = rcInfo.fkTableName
1503: .toUpperCase();
1504: }
1505: // ignore the column info if the FK table name is not in the list we are concerned with
1506: if (!tableNames.contains(rcInfo.fkTableName)) {
1507: continue;
1508: }
1509: rcInfo.fkColumnName = rsCols
1510: .getString("FKCOLUMN_NAME");
1511: if (needsUpperCase && rcInfo.fkColumnName != null) {
1512: rcInfo.fkColumnName = rcInfo.fkColumnName
1513: .toUpperCase();
1514: }
1515: rcInfo.fkName = rsCols.getString("FK_NAME");
1516: if (needsUpperCase && rcInfo.fkName != null) {
1517: rcInfo.fkName = rcInfo.fkName.toUpperCase();
1518: }
1519:
1520: if (Debug.verboseOn())
1521: Debug.logVerbose("Got: " + rcInfo.toString(),
1522: module);
1523:
1524: Map tableRefInfo = (Map) refInfo
1525: .get(rcInfo.fkTableName);
1526: if (tableRefInfo == null) {
1527: tableRefInfo = new HashMap();
1528: refInfo.put(rcInfo.fkTableName, tableRefInfo);
1529: if (Debug.verboseOn())
1530: Debug.logVerbose(
1531: "Adding new Map for table: "
1532: + rcInfo.fkTableName,
1533: module);
1534: }
1535: if (!tableRefInfo.containsKey(rcInfo.fkName))
1536: totalFkRefs++;
1537: tableRefInfo.put(rcInfo.fkName, rcInfo);
1538: } catch (SQLException sqle) {
1539: String message = "Error getting fk reference info for table. Error was:"
1540: + sqle.toString();
1541: Debug.logError(message, module);
1542: if (messages != null)
1543: messages.add(message);
1544: continue;
1545: }
1546: }
1547:
1548: // if (Debug.infoOn()) Debug.logInfo("There are " + totalFkRefs + " in the database", module);
1549: try {
1550: rsCols.close();
1551: } catch (SQLException sqle) {
1552: String message = "Unable to close ResultSet for fk reference list, continuing anyway... Error was:"
1553: + sqle.toString();
1554: Debug.logError(message, module);
1555: if (messages != null)
1556: messages.add(message);
1557: }
1558: // }
1559: if (Debug.infoOn())
1560: Debug.logInfo("There are " + totalFkRefs
1561: + " foreign key refs in the database", module);
1562:
1563: } catch (SQLException sqle) {
1564: String message = "Error getting fk reference meta data Error was:"
1565: + sqle.toString() + ". Not checking fk refs.";
1566: Debug.logError(message, module);
1567: if (messages != null)
1568: messages.add(message);
1569: refInfo = null;
1570: } finally {
1571: try {
1572: connection.close();
1573: } catch (SQLException sqle) {
1574: String message = "Unable to close database connection, continuing anyway... Error was:"
1575: + sqle.toString();
1576: Debug.logError(message, module);
1577: if (messages != null)
1578: messages.add(message);
1579: }
1580: }
1581: return refInfo;
1582: }
1583:
1584: public Map getIndexInfo(Set tableNames, Collection messages) {
1585: Connection connection = null;
1586:
1587: try {
1588: connection = getConnection();
1589: } catch (SQLException sqle) {
1590: String message = "Unable to esablish a connection with the database... Error was:"
1591: + sqle.toString();
1592: Debug.logError(message, module);
1593: if (messages != null)
1594: messages.add(message);
1595: return null;
1596: } catch (GenericEntityException e) {
1597: String message = "Unable to esablish a connection with the database... Error was:"
1598: + e.toString();
1599: Debug.logError(message, module);
1600: if (messages != null)
1601: messages.add(message);
1602: return null;
1603: }
1604:
1605: DatabaseMetaData dbData = null;
1606: try {
1607: dbData = connection.getMetaData();
1608: } catch (SQLException sqle) {
1609: String message = "Unable to get database meta data... Error was:"
1610: + sqle.toString();
1611: Debug.logError(message, module);
1612: if (messages != null)
1613: messages.add(message);
1614:
1615: try {
1616: connection.close();
1617: } catch (SQLException sqle2) {
1618: String message2 = "Unable to close database connection, continuing anyway... Error was:"
1619: + sqle2.toString();
1620: Debug.logError(message2, module);
1621: if (messages != null)
1622: messages.add(message2);
1623: }
1624: return null;
1625: }
1626:
1627: boolean needsUpperCase = false;
1628: try {
1629: needsUpperCase = dbData.storesLowerCaseIdentifiers()
1630: || dbData.storesMixedCaseIdentifiers();
1631: } catch (SQLException sqle) {
1632: String message = "Error getting identifier case information... Error was:"
1633: + sqle.toString();
1634: Debug.logError(message, module);
1635: if (messages != null)
1636: messages.add(message);
1637: }
1638:
1639: if (Debug.infoOn())
1640: Debug.logInfo("Getting Index Info From Database", module);
1641:
1642: Map indexInfo = new HashMap();
1643: try {
1644: int totalIndices = 0;
1645: Iterator tableNamesIter = tableNames.iterator();
1646: while (tableNamesIter.hasNext()) {
1647: String curTableName = (String) tableNamesIter.next();
1648:
1649: String lookupSchemaName = null;
1650: if (dbData.supportsSchemasInTableDefinitions()) {
1651: if (this .datasourceInfo.schemaName != null
1652: && this .datasourceInfo.schemaName.length() > 0) {
1653: lookupSchemaName = this .datasourceInfo.schemaName;
1654: } else {
1655: lookupSchemaName = dbData.getUserName();
1656: }
1657: }
1658:
1659: ResultSet rsCols = null;
1660: try {
1661: // false for unique, we don't really use unique indexes
1662: // true for approximate, don't really care if stats are up-to-date
1663: rsCols = dbData
1664: .getIndexInfo(null, lookupSchemaName,
1665: curTableName, false, true);
1666: } catch (Exception e) {
1667: Debug.logWarning(e,
1668: "Error getting index info for table: "
1669: + curTableName
1670: + " using lookupSchemaName "
1671: + lookupSchemaName, module);
1672: }
1673:
1674: while (rsCols != null && rsCols.next()) {
1675: // NOTE: The code in this block may look funny, but it is designed so that the wrapping loop can be removed
1676: try {
1677: // skip all index info for statistics
1678: if (rsCols.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic)
1679: continue;
1680:
1681: // HACK: for now skip all "unique" indexes since our foreign key indices are not unique, but the primary key ones are
1682: if (!rsCols.getBoolean("NON_UNIQUE"))
1683: continue;
1684:
1685: String tableName = rsCols
1686: .getString("TABLE_NAME");
1687: if (needsUpperCase && tableName != null) {
1688: tableName = tableName.toUpperCase();
1689: }
1690: if (!tableNames.contains(tableName))
1691: continue;
1692:
1693: String indexName = rsCols
1694: .getString("INDEX_NAME");
1695: if (needsUpperCase && indexName != null) {
1696: indexName = indexName.toUpperCase();
1697: }
1698:
1699: TreeSet tableIndexList = (TreeSet) indexInfo
1700: .get(tableName);
1701: if (tableIndexList == null) {
1702: tableIndexList = new TreeSet();
1703: indexInfo.put(tableName, tableIndexList);
1704: if (Debug.verboseOn())
1705: Debug.logVerbose(
1706: "Adding new Map for table: "
1707: + tableName, module);
1708: }
1709: if (!tableIndexList.contains(indexName))
1710: totalIndices++;
1711: tableIndexList.add(indexName);
1712: } catch (SQLException sqle) {
1713: String message = "Error getting fk reference info for table. Error was:"
1714: + sqle.toString();
1715: Debug.logError(message, module);
1716: if (messages != null)
1717: messages.add(message);
1718: continue;
1719: }
1720: }
1721:
1722: // if (Debug.infoOn()) Debug.logInfo("There are " + totalIndices + " indices in the database", module);
1723: if (rsCols != null) {
1724: try {
1725: rsCols.close();
1726: } catch (SQLException sqle) {
1727: String message = "Unable to close ResultSet for fk reference list, continuing anyway... Error was:"
1728: + sqle.toString();
1729: Debug.logError(message, module);
1730: if (messages != null)
1731: messages.add(message);
1732: }
1733: }
1734: }
1735: if (Debug.infoOn())
1736: Debug.logInfo("There are " + totalIndices
1737: + " indices in the database", module);
1738:
1739: } catch (SQLException sqle) {
1740: String message = "Error getting fk reference meta data Error was:"
1741: + sqle.toString() + ". Not checking fk refs.";
1742: Debug.logError(message, module);
1743: if (messages != null)
1744: messages.add(message);
1745: indexInfo = null;
1746: } finally {
1747: try {
1748: connection.close();
1749: } catch (SQLException sqle) {
1750: String message = "Unable to close database connection, continuing anyway... Error was:"
1751: + sqle.toString();
1752: Debug.logError(message, module);
1753: if (messages != null)
1754: messages.add(message);
1755: }
1756: }
1757: return indexInfo;
1758: }
1759:
1760: /* ====================================================================== */
1761:
1762: /* ====================================================================== */
1763:
1764: public String createTable(ModelEntity entity, Map modelEntities,
1765: boolean addFks, boolean usePkConstraintNames,
1766: int constraintNameClipLength, String fkStyle,
1767: boolean useFkInitiallyDeferred) {
1768: if (entity == null) {
1769: return "ModelEntity was null and is required to create a table";
1770: }
1771: if (entity instanceof ModelViewEntity) {
1772: return "ERROR: Cannot create table for a view entity";
1773: }
1774:
1775: Connection connection = null;
1776: Statement stmt = null;
1777:
1778: try {
1779: connection = getConnection();
1780: } catch (SQLException sqle) {
1781: return "Unable to esablish a connection with the database... Error was: "
1782: + sqle.toString();
1783: } catch (GenericEntityException e) {
1784: return "Unable to esablish a connection with the database... Error was: "
1785: + e.toString();
1786: }
1787:
1788: StringBuffer sqlBuf = new StringBuffer("CREATE TABLE ");
1789: sqlBuf.append(entity.getTableName(datasourceInfo));
1790: sqlBuf.append(" (");
1791: for (int i = 0; i < entity.getFieldsSize(); i++) {
1792: ModelField field = entity.getField(i);
1793: ModelFieldType type = modelFieldTypeReader
1794: .getModelFieldType(field.getType());
1795:
1796: if (type == null) {
1797: return "Field type [" + type
1798: + "] not found for field [" + field.getName()
1799: + "] of entity [" + entity.getEntityName()
1800: + "], not creating table.";
1801: }
1802:
1803: sqlBuf.append(field.getColName());
1804: sqlBuf.append(" ");
1805: sqlBuf.append(type.getSqlType());
1806: if (field.getIsPk()) {
1807: sqlBuf.append(" NOT NULL, ");
1808: } else {
1809: sqlBuf.append(", ");
1810: }
1811: }
1812: String pkName = "PK_" + entity.getPlainTableName();
1813:
1814: if (pkName.length() > constraintNameClipLength) {
1815: pkName = pkName.substring(0, constraintNameClipLength);
1816: }
1817:
1818: if (usePkConstraintNames) {
1819: sqlBuf.append("CONSTRAINT ");
1820: sqlBuf.append(pkName);
1821: }
1822: sqlBuf.append(" PRIMARY KEY (");
1823: sqlBuf.append(entity.colNameString(entity.getPksCopy()));
1824: sqlBuf.append(")");
1825:
1826: if (addFks) {
1827: // NOTE: This is kind of a bad idea anyway since ordering table creations is crazy, if not impossible
1828:
1829: // go through the relationships to see if any foreign keys need to be added
1830: Iterator relationsIter = entity.getRelationsIterator();
1831:
1832: while (relationsIter.hasNext()) {
1833: ModelRelation modelRelation = (ModelRelation) relationsIter
1834: .next();
1835:
1836: if ("one".equals(modelRelation.getType())) {
1837: ModelEntity relModelEntity = (ModelEntity) modelEntities
1838: .get(modelRelation.getRelEntityName());
1839:
1840: if (relModelEntity == null) {
1841: Debug.logError(
1842: "Error adding foreign key: ModelEntity was null for related entity name "
1843: + modelRelation
1844: .getRelEntityName(),
1845: module);
1846: continue;
1847: }
1848: if (relModelEntity instanceof ModelViewEntity) {
1849: Debug
1850: .logError(
1851: "Error adding foreign key: related entity is a view entity for related entity name "
1852: + modelRelation
1853: .getRelEntityName(),
1854: module);
1855: continue;
1856: }
1857:
1858: String fkConstraintClause = makeFkConstraintClause(
1859: entity, modelRelation, relModelEntity,
1860: constraintNameClipLength, fkStyle,
1861: useFkInitiallyDeferred);
1862: if (UtilValidate.isNotEmpty(fkConstraintClause)) {
1863: sqlBuf.append(", ");
1864: sqlBuf.append(fkConstraintClause);
1865: } else {
1866: continue;
1867: }
1868: }
1869: }
1870: }
1871:
1872: sqlBuf.append(")");
1873: if (Debug.verboseOn())
1874: Debug.logVerbose("[createTable] sql=" + sqlBuf.toString(),
1875: module);
1876: try {
1877: stmt = connection.createStatement();
1878: stmt.executeUpdate(sqlBuf.toString());
1879: } catch (SQLException sqle) {
1880: return "SQL Exception while executing the following:\n"
1881: + sqlBuf.toString() + "\nError was: "
1882: + sqle.toString();
1883: } finally {
1884: try {
1885: if (stmt != null)
1886: stmt.close();
1887: } catch (SQLException sqle) {
1888: Debug.logError(sqle, module);
1889: }
1890: try {
1891: if (connection != null)
1892: connection.close();
1893: } catch (SQLException sqle) {
1894: Debug.logError(sqle, module);
1895: }
1896: }
1897: return null;
1898: }
1899:
1900: public void deleteTable(ModelEntity entity, List messages) {
1901: if (entity == null) {
1902: String errMsg = "ModelEntity was null and is required to delete a table";
1903: Debug.logError(errMsg, module);
1904: if (messages != null)
1905: messages.add(errMsg);
1906: return;
1907: }
1908: if (entity instanceof ModelViewEntity) {
1909: //String errMsg = "ERROR: Cannot delete table for a view entity";
1910: //Debug.logError(errMsg, module);
1911: //if (messages != null) messages.add(errMsg);
1912: return;
1913: }
1914:
1915: Connection connection = null;
1916: Statement stmt = null;
1917: try {
1918: connection = getConnection();
1919: } catch (SQLException sqle) {
1920: String errMsg = "Unable to esablish a connection with the database... Error was: "
1921: + sqle.toString();
1922: Debug.logError(errMsg, module);
1923: if (messages != null)
1924: messages.add(errMsg);
1925: return;
1926: } catch (GenericEntityException e) {
1927: String errMsg = "Unable to esablish a connection with the database... Error was: "
1928: + e.toString();
1929: Debug.logError(errMsg, module);
1930: if (messages != null)
1931: messages.add(errMsg);
1932: return;
1933: }
1934:
1935: String message = "Deleting table for entity \""
1936: + entity.getEntityName() + "\"";
1937: Debug.logImportant(message, module);
1938: if (messages != null)
1939: messages.add(message);
1940:
1941: StringBuffer sqlBuf = new StringBuffer("DROP TABLE ");
1942: sqlBuf.append(entity.getTableName(datasourceInfo));
1943: if (Debug.verboseOn())
1944: Debug.logVerbose("[deleteTable] sql=" + sqlBuf.toString(),
1945: module);
1946: try {
1947: stmt = connection.createStatement();
1948: stmt.executeUpdate(sqlBuf.toString());
1949: } catch (SQLException sqle) {
1950: String errMsg = "SQL Exception while executing the following:\n"
1951: + sqlBuf.toString()
1952: + "\nError was: "
1953: + sqle.toString();
1954: Debug.logError(errMsg, module);
1955: if (messages != null)
1956: messages.add(errMsg);
1957: } finally {
1958: try {
1959: if (stmt != null)
1960: stmt.close();
1961: } catch (SQLException sqle) {
1962: Debug.logError(sqle, module);
1963: }
1964: try {
1965: if (connection != null)
1966: connection.close();
1967: } catch (SQLException sqle) {
1968: Debug.logError(sqle, module);
1969: }
1970: }
1971: }
1972:
1973: public String addColumn(ModelEntity entity, ModelField field) {
1974: if (entity == null || field == null)
1975: return "ModelEntity or ModelField where null, cannot add column";
1976: if (entity instanceof ModelViewEntity) {
1977: return "ERROR: Cannot add column for a view entity";
1978: }
1979:
1980: Connection connection = null;
1981: Statement stmt = null;
1982:
1983: try {
1984: connection = getConnection();
1985: } catch (SQLException sqle) {
1986: return "Unable to esablish a connection with the database... Error was: "
1987: + sqle.toString();
1988: } catch (GenericEntityException e) {
1989: return "Unable to esablish a connection with the database... Error was: "
1990: + e.toString();
1991: }
1992:
1993: ModelFieldType type = modelFieldTypeReader
1994: .getModelFieldType(field.getType());
1995:
1996: if (type == null) {
1997: return "Field type [" + type + "] not found for field ["
1998: + field.getName() + "] of entity ["
1999: + entity.getEntityName() + "], not adding column.";
2000: }
2001:
2002: StringBuffer sqlBuf = new StringBuffer("ALTER TABLE ");
2003: sqlBuf.append(entity.getTableName(datasourceInfo));
2004: sqlBuf.append(" ADD ");
2005: sqlBuf.append(field.getColName());
2006: sqlBuf.append(" ");
2007: sqlBuf.append(type.getSqlType());
2008:
2009: String sql = sqlBuf.toString();
2010: if (Debug.infoOn())
2011: Debug.logInfo("[addColumn] sql=" + sql, module);
2012: try {
2013: stmt = connection.createStatement();
2014: stmt.executeUpdate(sql);
2015: } catch (SQLException sqle) {
2016: // if that failed try the alternate syntax real quick
2017: String sql2 = "ALTER TABLE "
2018: + entity.getTableName(datasourceInfo)
2019: + " ADD COLUMN " + field.getColName() + " "
2020: + type.getSqlType();
2021: if (Debug.infoOn())
2022: Debug.logInfo("[addColumn] sql failed, trying sql2="
2023: + sql2, module);
2024: try {
2025: stmt = connection.createStatement();
2026: stmt.executeUpdate(sql2);
2027: } catch (SQLException sqle2) {
2028: // if this also fails report original error, not this error...
2029: return "SQL Exception while executing the following:\n"
2030: + sql + "\nError was: " + sqle.toString();
2031: }
2032: } finally {
2033: try {
2034: if (stmt != null) {
2035: stmt.close();
2036: }
2037: } catch (SQLException sqle) {
2038: Debug.logError(sqle, module);
2039: }
2040: try {
2041: if (connection != null) {
2042: connection.close();
2043: }
2044: } catch (SQLException sqle) {
2045: Debug.logError(sqle, module);
2046: }
2047: }
2048: return null;
2049: }
2050:
2051: /* ====================================================================== */
2052:
2053: /* ====================================================================== */
2054: public String makeFkConstraintName(ModelRelation modelRelation,
2055: int constraintNameClipLength) {
2056: String relConstraintName = modelRelation.getFkName();
2057:
2058: if (relConstraintName == null
2059: || relConstraintName.length() == 0) {
2060: relConstraintName = modelRelation.getTitle()
2061: + modelRelation.getRelEntityName();
2062: relConstraintName = relConstraintName.toUpperCase();
2063: }
2064:
2065: if (relConstraintName.length() > constraintNameClipLength) {
2066: relConstraintName = relConstraintName.substring(0,
2067: constraintNameClipLength);
2068: }
2069:
2070: return relConstraintName;
2071: }
2072:
2073: /* ====================================================================== */
2074:
2075: /* ====================================================================== */
2076: public void createForeignKeys(ModelEntity entity,
2077: Map modelEntities, List messages) {
2078: this .createForeignKeys(entity, modelEntities,
2079: datasourceInfo.constraintNameClipLength,
2080: datasourceInfo.fkStyle,
2081: datasourceInfo.useFkInitiallyDeferred, messages);
2082: }
2083:
2084: public void createForeignKeys(ModelEntity entity,
2085: Map modelEntities, int constraintNameClipLength,
2086: String fkStyle, boolean useFkInitiallyDeferred,
2087: List messages) {
2088: if (entity == null) {
2089: String errMsg = "ModelEntity was null and is required to create foreign keys for a table";
2090: Debug.logError(errMsg, module);
2091: if (messages != null)
2092: messages.add(errMsg);
2093: return;
2094: }
2095: if (entity instanceof ModelViewEntity) {
2096: //String errMsg = "ERROR: Cannot create foreign keys for a view entity";
2097: //Debug.logError(errMsg, module);
2098: //if (messages != null) messages.add(errMsg);
2099: return;
2100: }
2101:
2102: String message = "Creating foreign keys for entity \""
2103: + entity.getEntityName() + "\"";
2104: Debug.logImportant(message, module);
2105: if (messages != null)
2106: messages.add(message);
2107:
2108: // go through the relationships to see if any foreign keys need to be added
2109: Iterator relationsIter = entity.getRelationsIterator();
2110: while (relationsIter.hasNext()) {
2111: ModelRelation modelRelation = (ModelRelation) relationsIter
2112: .next();
2113:
2114: if ("one".equals(modelRelation.getType())) {
2115: ModelEntity relModelEntity = (ModelEntity) modelEntities
2116: .get(modelRelation.getRelEntityName());
2117:
2118: if (relModelEntity == null) {
2119: String errMsg = "Error adding foreign key: ModelEntity was null for related entity name "
2120: + modelRelation.getRelEntityName();
2121: Debug.logError(errMsg, module);
2122: if (messages != null)
2123: messages.add(errMsg);
2124: continue;
2125: }
2126: if (relModelEntity instanceof ModelViewEntity) {
2127: String errMsg = "Error adding foreign key: related entity is a view entity for related entity name "
2128: + modelRelation.getRelEntityName();
2129: Debug.logError(errMsg, module);
2130: if (messages != null)
2131: messages.add(errMsg);
2132: continue;
2133: }
2134:
2135: String retMsg = createForeignKey(entity, modelRelation,
2136: relModelEntity, constraintNameClipLength,
2137: fkStyle, useFkInitiallyDeferred);
2138: if (retMsg != null && retMsg.length() > 0) {
2139: Debug.logError(retMsg, module);
2140: if (messages != null)
2141: messages.add(retMsg);
2142: }
2143: }
2144: }
2145: }
2146:
2147: public String createForeignKey(ModelEntity entity,
2148: ModelRelation modelRelation, ModelEntity relModelEntity,
2149: int constraintNameClipLength, String fkStyle,
2150: boolean useFkInitiallyDeferred) {
2151: Connection connection = null;
2152: Statement stmt = null;
2153:
2154: try {
2155: connection = getConnection();
2156: } catch (SQLException sqle) {
2157: return "Unable to esablish a connection with the database... Error was: "
2158: + sqle.toString();
2159: } catch (GenericEntityException e) {
2160: return "Unable to esablish a connection with the database... Error was: "
2161: + e.toString();
2162: }
2163:
2164: // now add constraint clause
2165: StringBuffer sqlBuf = new StringBuffer("ALTER TABLE ");
2166: sqlBuf.append(entity.getTableName(datasourceInfo));
2167: sqlBuf.append(" ADD ");
2168: String fkConstraintClause = makeFkConstraintClause(entity,
2169: modelRelation, relModelEntity,
2170: constraintNameClipLength, fkStyle,
2171: useFkInitiallyDeferred);
2172: if (UtilValidate.isEmpty(fkConstraintClause)) {
2173: return "Error creating foreign key constraint clause, see log for details";
2174: }
2175: sqlBuf.append(fkConstraintClause);
2176:
2177: if (Debug.verboseOn())
2178: Debug.logVerbose("[createForeignKey] sql="
2179: + sqlBuf.toString(), module);
2180: try {
2181: stmt = connection.createStatement();
2182: stmt.executeUpdate(sqlBuf.toString());
2183: } catch (SQLException sqle) {
2184: return "SQL Exception while executing the following:\n"
2185: + sqlBuf.toString() + "\nError was: "
2186: + sqle.toString();
2187: } finally {
2188: try {
2189: if (stmt != null) {
2190: stmt.close();
2191: }
2192: } catch (SQLException sqle) {
2193: Debug.logError(sqle, module);
2194: }
2195: try {
2196: if (connection != null) {
2197: connection.close();
2198: }
2199: } catch (SQLException sqle) {
2200: Debug.logError(sqle, module);
2201: }
2202: }
2203: return null;
2204: }
2205:
2206: public String makeFkConstraintClause(ModelEntity entity,
2207: ModelRelation modelRelation, ModelEntity relModelEntity,
2208: int constraintNameClipLength, String fkStyle,
2209: boolean useFkInitiallyDeferred) {
2210: // make the two column lists
2211: Iterator keyMapsIter = modelRelation.getKeyMapsIterator();
2212: StringBuffer mainCols = new StringBuffer();
2213: StringBuffer relCols = new StringBuffer();
2214:
2215: while (keyMapsIter.hasNext()) {
2216: ModelKeyMap keyMap = (ModelKeyMap) keyMapsIter.next();
2217:
2218: ModelField mainField = entity.getField(keyMap
2219: .getFieldName());
2220: if (mainField == null) {
2221: Debug.logError(
2222: "Bad key-map in entity ["
2223: + entity.getEntityName()
2224: + "] relation to ["
2225: + modelRelation.getTitle()
2226: + modelRelation.getRelEntityName()
2227: + "] for field ["
2228: + keyMap.getFieldName() + "]", module);
2229: return null;
2230: }
2231:
2232: if (mainCols.length() > 0) {
2233: mainCols.append(", ");
2234: }
2235: mainCols.append(mainField.getColName());
2236:
2237: ModelField relField = relModelEntity.getField(keyMap
2238: .getRelFieldName());
2239:
2240: if (relCols.length() > 0) {
2241: relCols.append(", ");
2242: }
2243: relCols.append(relField.getColName());
2244: }
2245:
2246: StringBuffer sqlBuf = new StringBuffer("");
2247:
2248: if ("name_constraint".equals(fkStyle)) {
2249: sqlBuf.append("CONSTRAINT ");
2250: String relConstraintName = makeFkConstraintName(
2251: modelRelation, constraintNameClipLength);
2252:
2253: sqlBuf.append(relConstraintName);
2254:
2255: sqlBuf.append(" FOREIGN KEY (");
2256: sqlBuf.append(mainCols.toString());
2257: sqlBuf.append(") REFERENCES ");
2258: sqlBuf.append(relModelEntity.getTableName(datasourceInfo));
2259: sqlBuf.append(" (");
2260: sqlBuf.append(relCols.toString());
2261: sqlBuf.append(")");
2262: if (useFkInitiallyDeferred) {
2263: sqlBuf.append(" INITIALLY DEFERRED");
2264: }
2265: } else if ("name_fk".equals(fkStyle)) {
2266: sqlBuf.append(" FOREIGN KEY ");
2267: String relConstraintName = makeFkConstraintName(
2268: modelRelation, constraintNameClipLength);
2269:
2270: sqlBuf.append(relConstraintName);
2271: sqlBuf.append(" (");
2272: sqlBuf.append(mainCols.toString());
2273: sqlBuf.append(") REFERENCES ");
2274: sqlBuf.append(relModelEntity.getTableName(datasourceInfo));
2275: sqlBuf.append(" (");
2276: sqlBuf.append(relCols.toString());
2277: sqlBuf.append(")");
2278: if (useFkInitiallyDeferred) {
2279: sqlBuf.append(" INITIALLY DEFERRED");
2280: }
2281: } else {
2282: String emsg = "ERROR: fk-style specified for this data-source is not valid: "
2283: + fkStyle;
2284:
2285: Debug.logError(emsg, module);
2286: throw new IllegalArgumentException(emsg);
2287: }
2288:
2289: return sqlBuf.toString();
2290: }
2291:
2292: public void deleteForeignKeys(ModelEntity entity,
2293: Map modelEntities, List messages) {
2294: this .deleteForeignKeys(entity, modelEntities,
2295: datasourceInfo.constraintNameClipLength, messages);
2296: }
2297:
2298: public void deleteForeignKeys(ModelEntity entity,
2299: Map modelEntities, int constraintNameClipLength,
2300: List messages) {
2301: if (entity == null) {
2302: String errMsg = "ModelEntity was null and is required to delete foreign keys for a table";
2303: if (messages != null)
2304: messages.add(errMsg);
2305: Debug.logError(errMsg, module);
2306: return;
2307: }
2308: if (entity instanceof ModelViewEntity) {
2309: //String errMsg = "ERROR: Cannot delete foreign keys for a view entity";
2310: //if (messages != null) messages.add(errMsg);
2311: //Debug.logError(errMsg, module);
2312: return;
2313: }
2314:
2315: String message = "Deleting foreign keys for entity \""
2316: + entity.getEntityName() + "\"";
2317: Debug.logImportant(message, module);
2318: if (messages != null)
2319: messages.add(message);
2320:
2321: // go through the relationships to see if any foreign keys need to be added
2322: Iterator relationsIter = entity.getRelationsIterator();
2323: while (relationsIter.hasNext()) {
2324: ModelRelation modelRelation = (ModelRelation) relationsIter
2325: .next();
2326:
2327: if ("one".equals(modelRelation.getType())) {
2328: ModelEntity relModelEntity = (ModelEntity) modelEntities
2329: .get(modelRelation.getRelEntityName());
2330:
2331: if (relModelEntity == null) {
2332: String errMsg = "Error removing foreign key: ModelEntity was null for related entity name "
2333: + modelRelation.getRelEntityName();
2334: if (messages != null)
2335: messages.add(errMsg);
2336: Debug.logError(errMsg, module);
2337: continue;
2338: }
2339: if (relModelEntity instanceof ModelViewEntity) {
2340: String errMsg = "Error removing foreign key: related entity is a view entity for related entity name "
2341: + modelRelation.getRelEntityName();
2342: if (messages != null)
2343: messages.add(errMsg);
2344: Debug.logError(errMsg, module);
2345: continue;
2346: }
2347:
2348: String retMsg = deleteForeignKey(entity, modelRelation,
2349: relModelEntity, constraintNameClipLength);
2350: if (retMsg != null && retMsg.length() > 0) {
2351: if (messages != null)
2352: messages.add(retMsg);
2353: Debug.logError(retMsg, module);
2354: }
2355: }
2356: }
2357: }
2358:
2359: public String deleteForeignKey(ModelEntity entity,
2360: ModelRelation modelRelation, ModelEntity relModelEntity,
2361: int constraintNameClipLength) {
2362: Connection connection = null;
2363: Statement stmt = null;
2364:
2365: try {
2366: connection = getConnection();
2367: } catch (SQLException sqle) {
2368: return "Unable to esablish a connection with the database... Error was: "
2369: + sqle.toString();
2370: } catch (GenericEntityException e) {
2371: return "Unable to esablish a connection with the database... Error was: "
2372: + e.toString();
2373: }
2374:
2375: String relConstraintName = makeFkConstraintName(modelRelation,
2376: constraintNameClipLength);
2377:
2378: // now add constraint clause
2379: StringBuffer sqlBuf = new StringBuffer("ALTER TABLE ");
2380: sqlBuf.append(entity.getTableName(datasourceInfo));
2381: sqlBuf.append(" DROP CONSTRAINT ");
2382: sqlBuf.append(relConstraintName);
2383:
2384: if (Debug.verboseOn())
2385: Debug.logVerbose("[deleteForeignKey] sql="
2386: + sqlBuf.toString(), module);
2387: try {
2388: stmt = connection.createStatement();
2389: stmt.executeUpdate(sqlBuf.toString());
2390: } catch (SQLException sqle) {
2391: return "SQL Exception while executing the following:\n"
2392: + sqlBuf.toString() + "\nError was: "
2393: + sqle.toString();
2394: } finally {
2395: try {
2396: if (stmt != null)
2397: stmt.close();
2398: } catch (SQLException sqle) {
2399: Debug.logError(sqle, module);
2400: }
2401: try {
2402: if (connection != null)
2403: connection.close();
2404: } catch (SQLException sqle) {
2405: Debug.logError(sqle, module);
2406: }
2407: }
2408: return null;
2409: }
2410:
2411: /* ====================================================================== */
2412: /* ====================================================================== */
2413: public String createDeclaredIndices(ModelEntity entity) {
2414: if (entity == null) {
2415: return "ModelEntity was null and is required to create declared indices for a table";
2416: }
2417: if (entity instanceof ModelViewEntity) {
2418: return "ERROR: Cannot create declared indices for a view entity";
2419: }
2420:
2421: StringBuffer retMsgsBuffer = new StringBuffer();
2422:
2423: // go through the indexes to see if any need to be added
2424: Iterator indexesIter = entity.getIndexesIterator();
2425: while (indexesIter.hasNext()) {
2426: ModelIndex modelIndex = (ModelIndex) indexesIter.next();
2427:
2428: String retMsg = createDeclaredIndex(entity, modelIndex);
2429:
2430: if (retMsg != null && retMsg.length() > 0) {
2431: if (retMsgsBuffer.length() > 0) {
2432: retMsgsBuffer.append("\n");
2433: }
2434: retMsgsBuffer.append(retMsg);
2435: }
2436: }
2437: if (retMsgsBuffer.length() > 0) {
2438: return retMsgsBuffer.toString();
2439: } else {
2440: return null;
2441: }
2442: }
2443:
2444: public String createDeclaredIndex(ModelEntity entity,
2445: ModelIndex modelIndex) {
2446: Connection connection = null;
2447: Statement stmt = null;
2448:
2449: try {
2450: connection = getConnection();
2451: } catch (SQLException sqle) {
2452: return "Unable to esablish a connection with the database... Error was: "
2453: + sqle.toString();
2454: } catch (GenericEntityException e) {
2455: return "Unable to esablish a connection with the database... Error was: "
2456: + e.toString();
2457: }
2458:
2459: String createIndexSql = makeIndexClause(entity, modelIndex);
2460: if (Debug.verboseOn())
2461: Debug.logVerbose("[createForeignKeyIndex] index sql="
2462: + createIndexSql, module);
2463:
2464: try {
2465: stmt = connection.createStatement();
2466: stmt.executeUpdate(createIndexSql);
2467: } catch (SQLException sqle) {
2468: return "SQL Exception while executing the following:\n"
2469: + createIndexSql + "\nError was: "
2470: + sqle.toString();
2471: } finally {
2472: try {
2473: if (stmt != null)
2474: stmt.close();
2475: } catch (SQLException sqle) {
2476: Debug.logError(sqle, module);
2477: }
2478: try {
2479: if (connection != null)
2480: connection.close();
2481: } catch (SQLException sqle) {
2482: Debug.logError(sqle, module);
2483: }
2484: }
2485: return null;
2486: }
2487:
2488: public String makeIndexClause(ModelEntity entity,
2489: ModelIndex modelIndex) {
2490: Iterator fieldNamesIter = modelIndex.getIndexFieldsIterator();
2491: StringBuffer mainCols = new StringBuffer();
2492:
2493: while (fieldNamesIter.hasNext()) {
2494: String fieldName = (String) fieldNamesIter.next();
2495: ModelField mainField = entity.getField(fieldName);
2496: if (mainCols.length() > 0) {
2497: mainCols.append(", ");
2498: }
2499: mainCols.append(mainField.getColName());
2500: }
2501:
2502: StringBuffer indexSqlBuf = new StringBuffer("CREATE ");
2503: if (modelIndex.getUnique()) {
2504: indexSqlBuf.append("UNIQUE ");
2505: }
2506: indexSqlBuf.append("INDEX ");
2507: indexSqlBuf.append(modelIndex.getName());
2508: indexSqlBuf.append(" ON ");
2509: indexSqlBuf.append(entity.getTableName(datasourceInfo));
2510:
2511: indexSqlBuf.append(" (");
2512: indexSqlBuf.append(mainCols.toString());
2513: indexSqlBuf.append(")");
2514:
2515: return indexSqlBuf.toString();
2516: }
2517:
2518: public String deleteDeclaredIndices(ModelEntity entity) {
2519: if (entity == null) {
2520: return "ModelEntity was null and is required to delete foreign keys indices for a table";
2521: }
2522: if (entity instanceof ModelViewEntity) {
2523: return "ERROR: Cannot delete foreign keys indices for a view entity";
2524: }
2525:
2526: StringBuffer retMsgsBuffer = new StringBuffer();
2527:
2528: // go through the relationships to see if any foreign keys need to be added
2529: Iterator indexesIter = entity.getIndexesIterator();
2530: while (indexesIter.hasNext()) {
2531: ModelIndex modelIndex = (ModelIndex) indexesIter.next();
2532: String retMsg = deleteDeclaredIndex(entity, modelIndex);
2533: if (retMsg != null && retMsg.length() > 0) {
2534: if (retMsgsBuffer.length() > 0) {
2535: retMsgsBuffer.append("\n");
2536: }
2537: retMsgsBuffer.append(retMsg);
2538: }
2539: }
2540:
2541: if (retMsgsBuffer.length() > 0) {
2542: return retMsgsBuffer.toString();
2543: } else {
2544: return null;
2545: }
2546: }
2547:
2548: public String deleteDeclaredIndex(ModelEntity entity,
2549: ModelIndex modelIndex) {
2550: Connection connection = null;
2551: Statement stmt = null;
2552:
2553: try {
2554: connection = getConnection();
2555: } catch (SQLException sqle) {
2556: return "Unable to esablish a connection with the database... Error was: "
2557: + sqle.toString();
2558: } catch (GenericEntityException e) {
2559: return "Unable to esablish a connection with the database... Error was: "
2560: + e.toString();
2561: }
2562:
2563: // TODO: also remove the constraing if this was a unique index, in most databases dropping the index does not drop the constraint
2564:
2565: StringBuffer indexSqlBuf = new StringBuffer("DROP INDEX ");
2566: indexSqlBuf.append(entity.getTableName(datasourceInfo));
2567: indexSqlBuf.append(".");
2568: indexSqlBuf.append(modelIndex.getName());
2569:
2570: String deleteIndexSql = indexSqlBuf.toString();
2571: if (Debug.verboseOn())
2572: Debug.logVerbose("[deleteDeclaredIndex] index sql="
2573: + deleteIndexSql, module);
2574:
2575: try {
2576: stmt = connection.createStatement();
2577: stmt.executeUpdate(deleteIndexSql);
2578: } catch (SQLException sqle) {
2579: return "SQL Exception while executing the following:\n"
2580: + deleteIndexSql + "\nError was: "
2581: + sqle.toString();
2582: } finally {
2583: try {
2584: if (stmt != null)
2585: stmt.close();
2586: } catch (SQLException sqle) {
2587: Debug.logError(sqle, module);
2588: }
2589: try {
2590: if (connection != null)
2591: connection.close();
2592: } catch (SQLException sqle) {
2593: Debug.logError(sqle, module);
2594: }
2595: }
2596: return null;
2597: }
2598:
2599: /* ====================================================================== */
2600:
2601: /* ====================================================================== */
2602: public String createForeignKeyIndices(ModelEntity entity,
2603: int constraintNameClipLength) {
2604: if (entity == null) {
2605: return "ModelEntity was null and is required to create foreign keys indices for a table";
2606: }
2607: if (entity instanceof ModelViewEntity) {
2608: return "ERROR: Cannot create foreign keys indices for a view entity";
2609: }
2610:
2611: StringBuffer retMsgsBuffer = new StringBuffer();
2612:
2613: // go through the relationships to see if any foreign keys need to be added
2614: Iterator relationsIter = entity.getRelationsIterator();
2615:
2616: while (relationsIter.hasNext()) {
2617: ModelRelation modelRelation = (ModelRelation) relationsIter
2618: .next();
2619:
2620: if ("one".equals(modelRelation.getType())) {
2621: String retMsg = createForeignKeyIndex(entity,
2622: modelRelation, constraintNameClipLength);
2623:
2624: if (retMsg != null && retMsg.length() > 0) {
2625: if (retMsgsBuffer.length() > 0) {
2626: retMsgsBuffer.append("\n");
2627: }
2628: retMsgsBuffer.append(retMsg);
2629: }
2630: }
2631: }
2632: if (retMsgsBuffer.length() > 0) {
2633: return retMsgsBuffer.toString();
2634: } else {
2635: return null;
2636: }
2637: }
2638:
2639: public String createForeignKeyIndex(ModelEntity entity,
2640: ModelRelation modelRelation, int constraintNameClipLength) {
2641: Connection connection = null;
2642: Statement stmt = null;
2643:
2644: try {
2645: connection = getConnection();
2646: } catch (SQLException sqle) {
2647: return "Unable to esablish a connection with the database... Error was: "
2648: + sqle.toString();
2649: } catch (GenericEntityException e) {
2650: return "Unable to esablish a connection with the database... Error was: "
2651: + e.toString();
2652: }
2653:
2654: String createIndexSql = makeFkIndexClause(entity,
2655: modelRelation, constraintNameClipLength);
2656: if (UtilValidate.isEmpty(createIndexSql)) {
2657: return "Error creating foreign key index clause, see log for details";
2658: }
2659:
2660: if (Debug.verboseOn())
2661: Debug.logVerbose("[createForeignKeyIndex] index sql="
2662: + createIndexSql, module);
2663:
2664: try {
2665: stmt = connection.createStatement();
2666: stmt.executeUpdate(createIndexSql);
2667: } catch (SQLException sqle) {
2668: return "SQL Exception while executing the following:\n"
2669: + createIndexSql + "\nError was: "
2670: + sqle.toString();
2671: } finally {
2672: try {
2673: if (stmt != null)
2674: stmt.close();
2675: } catch (SQLException sqle) {
2676: Debug.logError(sqle, module);
2677: }
2678: try {
2679: if (connection != null)
2680: connection.close();
2681: } catch (SQLException sqle) {
2682: Debug.logError(sqle, module);
2683: }
2684: }
2685: return null;
2686: }
2687:
2688: public String makeFkIndexClause(ModelEntity entity,
2689: ModelRelation modelRelation, int constraintNameClipLength) {
2690: Iterator keyMapsIter = modelRelation.getKeyMapsIterator();
2691: StringBuffer mainCols = new StringBuffer();
2692:
2693: while (keyMapsIter.hasNext()) {
2694: ModelKeyMap keyMap = (ModelKeyMap) keyMapsIter.next();
2695: ModelField mainField = entity.getField(keyMap
2696: .getFieldName());
2697:
2698: if (mainField == null) {
2699: Debug.logError(
2700: "Bad key-map in entity ["
2701: + entity.getEntityName()
2702: + "] relation to ["
2703: + modelRelation.getTitle()
2704: + modelRelation.getRelEntityName()
2705: + "] for field ["
2706: + keyMap.getFieldName() + "]", module);
2707: return null;
2708: }
2709:
2710: if (mainCols.length() > 0) {
2711: mainCols.append(", ");
2712: }
2713: mainCols.append(mainField.getColName());
2714: }
2715:
2716: StringBuffer indexSqlBuf = new StringBuffer("CREATE INDEX ");
2717: String relConstraintName = makeFkConstraintName(modelRelation,
2718: constraintNameClipLength);
2719:
2720: indexSqlBuf.append(relConstraintName);
2721: indexSqlBuf.append(" ON ");
2722: indexSqlBuf.append(entity.getTableName(datasourceInfo));
2723:
2724: indexSqlBuf.append(" (");
2725: indexSqlBuf.append(mainCols.toString());
2726: indexSqlBuf.append(")");
2727:
2728: return indexSqlBuf.toString();
2729: }
2730:
2731: public String deleteForeignKeyIndices(ModelEntity entity,
2732: int constraintNameClipLength) {
2733: if (entity == null) {
2734: return "ModelEntity was null and is required to delete foreign keys indices for a table";
2735: }
2736: if (entity instanceof ModelViewEntity) {
2737: return "ERROR: Cannot delete foreign keys indices for a view entity";
2738: }
2739:
2740: StringBuffer retMsgsBuffer = new StringBuffer();
2741:
2742: // go through the relationships to see if any foreign keys need to be added
2743: Iterator relationsIter = entity.getRelationsIterator();
2744:
2745: while (relationsIter.hasNext()) {
2746: ModelRelation modelRelation = (ModelRelation) relationsIter
2747: .next();
2748:
2749: if ("one".equals(modelRelation.getType())) {
2750: String retMsg = deleteForeignKeyIndex(entity,
2751: modelRelation, constraintNameClipLength);
2752:
2753: if (retMsg != null && retMsg.length() > 0) {
2754: if (retMsgsBuffer.length() > 0) {
2755: retMsgsBuffer.append("\n");
2756: }
2757: retMsgsBuffer.append(retMsg);
2758: }
2759: }
2760: }
2761: if (retMsgsBuffer.length() > 0) {
2762: return retMsgsBuffer.toString();
2763: } else {
2764: return null;
2765: }
2766: }
2767:
2768: public String deleteForeignKeyIndex(ModelEntity entity,
2769: ModelRelation modelRelation, int constraintNameClipLength) {
2770: Connection connection = null;
2771: Statement stmt = null;
2772:
2773: try {
2774: connection = getConnection();
2775: } catch (SQLException sqle) {
2776: return "Unable to esablish a connection with the database... Error was: "
2777: + sqle.toString();
2778: } catch (GenericEntityException e) {
2779: return "Unable to esablish a connection with the database... Error was: "
2780: + e.toString();
2781: }
2782:
2783: StringBuffer indexSqlBuf = new StringBuffer("DROP INDEX ");
2784: String relConstraintName = makeFkConstraintName(modelRelation,
2785: constraintNameClipLength);
2786:
2787: indexSqlBuf.append(entity.getTableName(datasourceInfo));
2788: indexSqlBuf.append(".");
2789: indexSqlBuf.append(relConstraintName);
2790:
2791: String deleteIndexSql = indexSqlBuf.toString();
2792:
2793: if (Debug.verboseOn())
2794: Debug.logVerbose("[deleteForeignKeyIndex] index sql="
2795: + deleteIndexSql, module);
2796:
2797: try {
2798: stmt = connection.createStatement();
2799: stmt.executeUpdate(deleteIndexSql);
2800: } catch (SQLException sqle) {
2801: return "SQL Exception while executing the following:\n"
2802: + deleteIndexSql + "\nError was: "
2803: + sqle.toString();
2804: } finally {
2805: try {
2806: if (stmt != null) {
2807: stmt.close();
2808: }
2809: } catch (SQLException sqle) {
2810: Debug.logError(sqle, module);
2811: }
2812: try {
2813: if (connection != null) {
2814: connection.close();
2815: }
2816: } catch (SQLException sqle) {
2817: Debug.logError(sqle, module);
2818: }
2819: }
2820: return null;
2821: }
2822:
2823: /* ====================================================================== */
2824:
2825: /* ====================================================================== */
2826: public static class ColumnCheckInfo {
2827: public String tableName;
2828: public String columnName;
2829: public String typeName;
2830: public int columnSize;
2831: public int decimalDigits;
2832: public String isNullable; // YES/NO or "" = ie nobody knows
2833: }
2834:
2835: public static class ReferenceCheckInfo {
2836: public String pkTableName;
2837:
2838: /** Comma separated list of column names in the related tables primary key */
2839: public String pkColumnName;
2840: public String fkName;
2841: public String fkTableName;
2842:
2843: /** Comma separated list of column names in the primary tables foreign keys */
2844: public String fkColumnName;
2845:
2846: public String toString() {
2847: return "FK Reference from table " + fkTableName
2848: + " called " + fkName + " to PK in table "
2849: + pkTableName;
2850: }
2851: }
2852: }
|