0001: /*******************************************************************************
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: *******************************************************************************/package org.ofbiz.entity.datasource;
0019:
0020: import java.sql.ResultSet;
0021: import java.sql.SQLException;
0022: import java.sql.Timestamp;
0023: import java.util.Collection;
0024: import java.util.Collections;
0025: import java.util.Iterator;
0026: import java.util.LinkedList;
0027: import java.util.List;
0028: import java.util.Map;
0029: import java.util.Set;
0030: import java.util.TreeSet;
0031:
0032: import javolution.util.FastList;
0033: import javolution.util.FastMap;
0034: import javolution.util.FastSet;
0035:
0036: import org.ofbiz.base.util.Debug;
0037: import org.ofbiz.base.util.UtilValidate;
0038: import org.ofbiz.entity.*;
0039: import org.ofbiz.entity.condition.EntityCondition;
0040: import org.ofbiz.entity.condition.EntityConditionParam;
0041: import org.ofbiz.entity.config.DatasourceInfo;
0042: import org.ofbiz.entity.config.EntityConfigUtil;
0043: import org.ofbiz.entity.jdbc.DatabaseUtil;
0044: import org.ofbiz.entity.jdbc.SQLProcessor;
0045: import org.ofbiz.entity.jdbc.SqlJdbcUtil;
0046: import org.ofbiz.entity.model.ModelEntity;
0047: import org.ofbiz.entity.model.ModelField;
0048: import org.ofbiz.entity.model.ModelFieldTypeReader;
0049: import org.ofbiz.entity.model.ModelKeyMap;
0050: import org.ofbiz.entity.model.ModelRelation;
0051: import org.ofbiz.entity.model.ModelViewEntity;
0052: import org.ofbiz.entity.transaction.TransactionUtil;
0053: import org.ofbiz.entity.util.EntityFindOptions;
0054: import org.ofbiz.entity.util.EntityListIterator;
0055:
0056: /**
0057: * Generic Entity Data Access Object - Handles persisntence for any defined entity.
0058: *
0059: */
0060: public class GenericDAO {
0061:
0062: public static final String module = GenericDAO.class.getName();
0063:
0064: protected static Map genericDAOs = FastMap.newInstance();
0065: protected String helperName;
0066: protected ModelFieldTypeReader modelFieldTypeReader = null;
0067: protected DatasourceInfo datasourceInfo;
0068:
0069: public static GenericDAO getGenericDAO(String helperName) {
0070: GenericDAO newGenericDAO = (GenericDAO) genericDAOs
0071: .get(helperName);
0072:
0073: if (newGenericDAO == null) { // don't want to block here
0074: synchronized (GenericDAO.class) {
0075: newGenericDAO = (GenericDAO) genericDAOs
0076: .get(helperName);
0077: if (newGenericDAO == null) {
0078: newGenericDAO = new GenericDAO(helperName);
0079: genericDAOs.put(helperName, newGenericDAO);
0080: }
0081: }
0082: }
0083: return newGenericDAO;
0084: }
0085:
0086: public GenericDAO(String helperName) {
0087: this .helperName = helperName;
0088: this .modelFieldTypeReader = ModelFieldTypeReader
0089: .getModelFieldTypeReader(helperName);
0090: this .datasourceInfo = EntityConfigUtil
0091: .getDatasourceInfo(helperName);
0092: }
0093:
0094: private void addFieldIfMissing(List fieldsToSave, String fieldName,
0095: ModelEntity modelEntity) {
0096: Iterator fieldsToSaveIter = fieldsToSave.iterator();
0097: while (fieldsToSaveIter.hasNext()) {
0098: ModelField fieldToSave = (ModelField) fieldsToSaveIter
0099: .next();
0100: if (fieldName.equals(fieldToSave.getName())) {
0101: return;
0102: }
0103: }
0104: // at this point we didn't find it
0105: fieldsToSave.add(modelEntity.getField(fieldName));
0106: }
0107:
0108: public int insert(GenericEntity entity)
0109: throws GenericEntityException {
0110: ModelEntity modelEntity = entity.getModelEntity();
0111:
0112: if (modelEntity == null) {
0113: throw new GenericModelException(
0114: "Could not find ModelEntity record for entityName: "
0115: + entity.getEntityName());
0116: }
0117:
0118: SQLProcessor sqlP = new SQLProcessor(helperName);
0119:
0120: try {
0121: return singleInsert(entity, modelEntity, modelEntity
0122: .getFieldsCopy(), sqlP);
0123: } catch (GenericEntityException e) {
0124: sqlP.rollback();
0125: throw new GenericEntityException(
0126: "Exception while inserting the following entity: "
0127: + entity.toString(), e);
0128: } finally {
0129: sqlP.close();
0130: }
0131: }
0132:
0133: private int singleInsert(GenericEntity entity,
0134: ModelEntity modelEntity, List fieldsToSave,
0135: SQLProcessor sqlP) throws GenericEntityException {
0136: if (modelEntity instanceof ModelViewEntity) {
0137: return singleUpdateView(entity,
0138: (ModelViewEntity) modelEntity, fieldsToSave, sqlP);
0139: }
0140:
0141: // if we have a STAMP_TX_FIELD or CREATE_STAMP_TX_FIELD then set it with NOW, always do this before the STAMP_FIELD
0142: // NOTE: these fairly complicated if statements have a few objectives:
0143: // 1. don't run the TransationUtil.getTransaction*Stamp() methods when we don't need to
0144: // 2. don't set the stamp values if it is from an EntitySync (ie maintain original values), unless the stamps are null then set it anyway, ie even if it was from an EntitySync (also used for imports and such)
0145: boolean stampTxIsField = modelEntity
0146: .isField(ModelEntity.STAMP_TX_FIELD);
0147: boolean createStampTxIsField = modelEntity
0148: .isField(ModelEntity.CREATE_STAMP_TX_FIELD);
0149: if ((stampTxIsField || createStampTxIsField)
0150: && (!entity.getIsFromEntitySync()
0151: || (stampTxIsField && entity
0152: .get(ModelEntity.STAMP_TX_FIELD) == null) || (createStampTxIsField && entity
0153: .get(ModelEntity.CREATE_STAMP_TX_FIELD) == null))) {
0154: Timestamp txStartStamp = TransactionUtil
0155: .getTransactionStartStamp();
0156: if (stampTxIsField
0157: && (!entity.getIsFromEntitySync() || entity
0158: .get(ModelEntity.STAMP_TX_FIELD) == null)) {
0159: entity.set(ModelEntity.STAMP_TX_FIELD, txStartStamp);
0160: addFieldIfMissing(fieldsToSave,
0161: ModelEntity.STAMP_TX_FIELD, modelEntity);
0162: }
0163: if (createStampTxIsField
0164: && (!entity.getIsFromEntitySync() || entity
0165: .get(ModelEntity.CREATE_STAMP_TX_FIELD) == null)) {
0166: entity.set(ModelEntity.CREATE_STAMP_TX_FIELD,
0167: txStartStamp);
0168: addFieldIfMissing(fieldsToSave,
0169: ModelEntity.CREATE_STAMP_TX_FIELD, modelEntity);
0170: }
0171: }
0172:
0173: // if we have a STAMP_FIELD or CREATE_STAMP_FIELD then set it with NOW
0174: boolean stampIsField = modelEntity
0175: .isField(ModelEntity.STAMP_FIELD);
0176: boolean createStampIsField = modelEntity
0177: .isField(ModelEntity.CREATE_STAMP_FIELD);
0178: if ((stampIsField || createStampIsField)
0179: && (!entity.getIsFromEntitySync()
0180: || (stampIsField && entity
0181: .get(ModelEntity.STAMP_FIELD) == null) || (createStampIsField && entity
0182: .get(ModelEntity.CREATE_STAMP_FIELD) == null))) {
0183: Timestamp startStamp = TransactionUtil
0184: .getTransactionUniqueNowStamp();
0185: if (stampIsField
0186: && (!entity.getIsFromEntitySync() || entity
0187: .get(ModelEntity.STAMP_FIELD) == null)) {
0188: entity.set(ModelEntity.STAMP_FIELD, startStamp);
0189: addFieldIfMissing(fieldsToSave,
0190: ModelEntity.STAMP_FIELD, modelEntity);
0191: }
0192: if (createStampIsField
0193: && (!entity.getIsFromEntitySync() || entity
0194: .get(ModelEntity.CREATE_STAMP_FIELD) == null)) {
0195: entity.set(ModelEntity.CREATE_STAMP_FIELD, startStamp);
0196: addFieldIfMissing(fieldsToSave,
0197: ModelEntity.CREATE_STAMP_FIELD, modelEntity);
0198: }
0199: }
0200:
0201: String sql = "INSERT INTO "
0202: + modelEntity.getTableName(datasourceInfo) + " ("
0203: + modelEntity.colNameString(fieldsToSave)
0204: + ") VALUES ("
0205: + modelEntity.fieldsStringList(fieldsToSave, "?", ", ")
0206: + ")";
0207:
0208: try {
0209: sqlP.prepareStatement(sql);
0210: SqlJdbcUtil.setValues(sqlP, fieldsToSave, entity,
0211: modelFieldTypeReader);
0212: int retVal = sqlP.executeUpdate();
0213:
0214: entity.synchronizedWithDatasource();
0215: return retVal;
0216: } catch (GenericEntityException e) {
0217: throw new GenericEntityException("while inserting: "
0218: + entity.toString(), e);
0219: } finally {
0220: sqlP.close();
0221: }
0222: }
0223:
0224: public int updateAll(GenericEntity entity)
0225: throws GenericEntityException {
0226: ModelEntity modelEntity = entity.getModelEntity();
0227:
0228: if (modelEntity == null) {
0229: throw new GenericModelException(
0230: "Could not find ModelEntity record for entityName: "
0231: + entity.getEntityName());
0232: }
0233:
0234: return customUpdate(entity, modelEntity, modelEntity
0235: .getNopksCopy());
0236: }
0237:
0238: public int update(GenericEntity entity)
0239: throws GenericEntityException {
0240: ModelEntity modelEntity = entity.getModelEntity();
0241:
0242: if (modelEntity == null) {
0243: throw new GenericModelException(
0244: "Could not find ModelEntity record for entityName: "
0245: + entity.getEntityName());
0246: }
0247:
0248: // we don't want to update ALL fields, just the nonpk fields that are in the passed GenericEntity
0249: List partialFields = FastList.newInstance();
0250: Collection keys = entity.getAllKeys();
0251:
0252: Iterator nopkIter = modelEntity.getNopksIterator();
0253: while (nopkIter.hasNext()) {
0254: ModelField curField = (ModelField) nopkIter.next();
0255: if (keys.contains(curField.getName())) {
0256: partialFields.add(curField);
0257: }
0258: }
0259:
0260: return customUpdate(entity, modelEntity, partialFields);
0261: }
0262:
0263: private int customUpdate(GenericEntity entity,
0264: ModelEntity modelEntity, List fieldsToSave)
0265: throws GenericEntityException {
0266: SQLProcessor sqlP = new SQLProcessor(helperName);
0267: try {
0268: return singleUpdate(entity, modelEntity, fieldsToSave, sqlP);
0269: } catch (GenericEntityException e) {
0270: sqlP.rollback();
0271: throw new GenericEntityException(
0272: "Exception while updating the following entity: "
0273: + entity.toString(), e);
0274: } finally {
0275: sqlP.close();
0276: }
0277: }
0278:
0279: private int singleUpdate(GenericEntity entity,
0280: ModelEntity modelEntity, List fieldsToSave,
0281: SQLProcessor sqlP) throws GenericEntityException {
0282: if (modelEntity instanceof ModelViewEntity) {
0283: return singleUpdateView(entity,
0284: (ModelViewEntity) modelEntity, fieldsToSave, sqlP);
0285: }
0286:
0287: // no non-primaryKey fields, update doesn't make sense, so don't do it
0288: if (fieldsToSave.size() <= 0) {
0289: if (Debug.verboseOn())
0290: Debug
0291: .logVerbose(
0292: "Trying to do an update on an entity with no non-PK fields, returning having done nothing; entity="
0293: + entity, module);
0294: // returning one because it was effectively updated, ie the same thing, so don't trigger any errors elsewhere
0295: return 1;
0296: }
0297:
0298: if (modelEntity.lock()) {
0299: GenericEntity entityCopy = GenericEntity
0300: .createGenericEntity(entity);
0301:
0302: select(entityCopy, sqlP);
0303: Object stampField = entity.get(ModelEntity.STAMP_FIELD);
0304:
0305: if ((stampField != null)
0306: && (!stampField.equals(entityCopy
0307: .get(ModelEntity.STAMP_FIELD)))) {
0308: String lockedTime = entityCopy.getTimestamp(
0309: ModelEntity.STAMP_FIELD).toString();
0310:
0311: throw new EntityLockedException(
0312: "You tried to update an old version of this data. Version locked: ("
0313: + lockedTime + ")");
0314: }
0315: }
0316:
0317: // if we have a STAMP_TX_FIELD then set it with NOW, always do this before the STAMP_FIELD
0318: // NOTE: these fairly complicated if statements have a few objectives:
0319: // 1. don't run the TransationUtil.getTransaction*Stamp() methods when we don't need to
0320: // 2. don't set the stamp values if it is from an EntitySync (ie maintain original values), unless the stamps are null then set it anyway, ie even if it was from an EntitySync (also used for imports and such)
0321: if (modelEntity.isField(ModelEntity.STAMP_TX_FIELD)
0322: && (!entity.getIsFromEntitySync() || entity
0323: .get(ModelEntity.STAMP_TX_FIELD) == null)) {
0324: entity.set(ModelEntity.STAMP_TX_FIELD, TransactionUtil
0325: .getTransactionStartStamp());
0326: addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_TX_FIELD,
0327: modelEntity);
0328: }
0329:
0330: // if we have a STAMP_FIELD then update it with NOW.
0331: if (modelEntity.isField(ModelEntity.STAMP_FIELD)
0332: && (!entity.getIsFromEntitySync() || entity
0333: .get(ModelEntity.STAMP_FIELD) == null)) {
0334: entity.set(ModelEntity.STAMP_FIELD, TransactionUtil
0335: .getTransactionUniqueNowStamp());
0336: addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_FIELD,
0337: modelEntity);
0338: }
0339:
0340: String sql = "UPDATE "
0341: + modelEntity.getTableName(datasourceInfo)
0342: + " SET "
0343: + modelEntity.colNameString(fieldsToSave, "=?, ", "=?",
0344: false)
0345: + " WHERE "
0346: + SqlJdbcUtil.makeWhereStringFromFields(modelEntity
0347: .getPksCopy(), entity, "AND");
0348:
0349: int retVal = 0;
0350:
0351: try {
0352: sqlP.prepareStatement(sql);
0353: SqlJdbcUtil.setValues(sqlP, fieldsToSave, entity,
0354: modelFieldTypeReader);
0355: SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity,
0356: modelFieldTypeReader);
0357: retVal = sqlP.executeUpdate();
0358: entity.synchronizedWithDatasource();
0359: } catch (GenericEntityException e) {
0360: throw new GenericEntityException("while updating: "
0361: + entity.toString(), e);
0362: } finally {
0363: sqlP.close();
0364: }
0365:
0366: if (retVal == 0) {
0367: throw new GenericEntityNotFoundException(
0368: "Tried to update an entity that does not exist.");
0369: }
0370: return retVal;
0371: }
0372:
0373: public int updateByCondition(ModelEntity modelEntity,
0374: Map fieldsToSet, EntityCondition condition)
0375: throws GenericEntityException {
0376: SQLProcessor sqlP = new SQLProcessor(helperName);
0377:
0378: try {
0379: return updateByCondition(modelEntity, fieldsToSet,
0380: condition, sqlP);
0381: } catch (GenericDataSourceException e) {
0382: sqlP.rollback();
0383: throw new GenericDataSourceException(
0384: "Generic Entity Exception occured in updateByCondition",
0385: e);
0386: } finally {
0387: sqlP.close();
0388: }
0389: }
0390:
0391: public int updateByCondition(ModelEntity modelEntity,
0392: Map fieldsToSet, EntityCondition condition,
0393: SQLProcessor sqlP) throws GenericEntityException {
0394: if (modelEntity == null || fieldsToSet == null
0395: || condition == null)
0396: return 0;
0397: if (modelEntity instanceof ModelViewEntity) {
0398: throw new org.ofbiz.entity.GenericNotImplementedException(
0399: "Operation updateByCondition not supported yet for view entities");
0400: }
0401:
0402: String sql = "UPDATE "
0403: + modelEntity.getTableName(datasourceInfo);
0404: sql += " SET ";
0405: Iterator i = fieldsToSet.keySet().iterator();
0406: List fieldList = new LinkedList();
0407: boolean firstField = true;
0408: while (i.hasNext()) {
0409: String name = (String) i.next();
0410: ModelField field = modelEntity.getField(name);
0411: if (field != null) {
0412: if (!firstField) {
0413: sql += ", ";
0414: } else {
0415: firstField = false;
0416: }
0417: sql += field.getColName() + " = ?";
0418: fieldList.add(field);
0419: }
0420: }
0421: sql += " WHERE "
0422: + condition.makeWhereString(modelEntity, null,
0423: this .datasourceInfo);
0424:
0425: try {
0426: sqlP.prepareStatement(sql);
0427: Iterator fi = fieldList.iterator();
0428: while (fi.hasNext()) {
0429: ModelField field = (ModelField) fi.next();
0430: Object value = fieldsToSet.get(field.getName());
0431: SqlJdbcUtil.setValue(sqlP, field, modelEntity
0432: .getEntityName(), value, modelFieldTypeReader);
0433: }
0434:
0435: return sqlP.executeUpdate();
0436: } finally {
0437: sqlP.close();
0438: }
0439: }
0440:
0441: /* ====================================================================== */
0442:
0443: /* ====================================================================== */
0444:
0445: /**
0446: * Try to update the given ModelViewEntity by trying to insert/update on the entities of which the view is composed.
0447: *
0448: * Works fine with standard O/R mapped models, but has some restrictions meeting more complicated view entities.
0449: * <li>A direct link is required, which means that one of the ModelViewLink field entries must have a value found
0450: * in the given view entity, for each ModelViewLink</li>
0451: * <li>For now, each member entity is updated iteratively, so if eg. the second member entity fails to update,
0452: * the first is written although. See code for details. Try to use "clean" views, until code is more robust ...</li>
0453: * <li>For now, aliased field names in views are not processed correctly, I guess. To be honest, I did not
0454: * find out how to construct such a view - so view fieldnames must have same named fields in member entities.</li>
0455: * <li>A new exception, e.g. GenericViewNotUpdatable, should be defined and thrown if the update fails</li>
0456: *
0457: */
0458: private int singleUpdateView(GenericEntity entity,
0459: ModelViewEntity modelViewEntity, List fieldsToSave,
0460: SQLProcessor sqlP) throws GenericEntityException {
0461: GenericDelegator delegator = entity.getDelegator();
0462:
0463: int retVal = 0;
0464: ModelEntity memberModelEntity = null;
0465:
0466: // Construct insert/update for each model entity
0467: Iterator meIter = modelViewEntity
0468: .getMemberModelMemberEntities().entrySet().iterator();
0469: while (meIter != null && meIter.hasNext()) {
0470: Map.Entry meMapEntry = (Map.Entry) meIter.next();
0471: ModelViewEntity.ModelMemberEntity modelMemberEntity = (ModelViewEntity.ModelMemberEntity) meMapEntry
0472: .getValue();
0473: String meName = modelMemberEntity.getEntityName();
0474: String meAlias = modelMemberEntity.getEntityAlias();
0475:
0476: if (Debug.verboseOn())
0477: Debug.logVerbose(
0478: "[singleUpdateView]: Processing MemberEntity "
0479: + meName + " with Alias " + meAlias,
0480: module);
0481: try {
0482: memberModelEntity = delegator.getModelReader()
0483: .getModelEntity(meName);
0484: } catch (GenericEntityException e) {
0485: throw new GenericEntityException(
0486: "Failed to get model entity for " + meName, e);
0487: }
0488:
0489: Map findByMap = FastMap.newInstance();
0490:
0491: // Now iterate the ModelViewLinks to construct the "WHERE" part for update/insert
0492: Iterator linkIter = modelViewEntity.getViewLinksIterator();
0493:
0494: while (linkIter != null && linkIter.hasNext()) {
0495: ModelViewEntity.ModelViewLink modelViewLink = (ModelViewEntity.ModelViewLink) linkIter
0496: .next();
0497:
0498: if (modelViewLink.getEntityAlias().equals(meAlias)
0499: || modelViewLink.getRelEntityAlias().equals(
0500: meAlias)) {
0501:
0502: Iterator kmIter = modelViewLink
0503: .getKeyMapsIterator();
0504:
0505: while (kmIter != null && kmIter.hasNext()) {
0506: ModelKeyMap keyMap = (ModelKeyMap) kmIter
0507: .next();
0508:
0509: String fieldName = "";
0510:
0511: if (modelViewLink.getEntityAlias().equals(
0512: meAlias)) {
0513: fieldName = keyMap.getFieldName();
0514: } else {
0515: fieldName = keyMap.getRelFieldName();
0516: }
0517:
0518: if (Debug.verboseOn())
0519: Debug
0520: .logVerbose(
0521: "[singleUpdateView]: --- Found field to set: "
0522: + meAlias + "."
0523: + fieldName, module);
0524: Object value = null;
0525:
0526: if (modelViewEntity.isField(keyMap
0527: .getFieldName())) {
0528: value = entity.get(keyMap.getFieldName());
0529: if (Debug.verboseOn())
0530: Debug.logVerbose(
0531: "[singleUpdateView]: --- Found map value: "
0532: + value.toString(),
0533: module);
0534: } else if (modelViewEntity.isField(keyMap
0535: .getRelFieldName())) {
0536: value = entity
0537: .get(keyMap.getRelFieldName());
0538: if (Debug.verboseOn())
0539: Debug.logVerbose(
0540: "[singleUpdateView]: --- Found map value: "
0541: + value.toString(),
0542: module);
0543: } else {
0544: throw new GenericNotImplementedException(
0545: "Update on view entities: no direct link found, unable to update");
0546: }
0547:
0548: findByMap.put(fieldName, value);
0549: }
0550: }
0551: }
0552:
0553: // Look what there already is in the database
0554: List meResult = null;
0555:
0556: try {
0557: meResult = delegator.findByAnd(meName, findByMap);
0558: } catch (GenericEntityException e) {
0559: throw new GenericEntityException(
0560: "Error while retrieving partial results for entity member: "
0561: + meName, e);
0562: }
0563: if (Debug.verboseOn())
0564: Debug.logVerbose("[singleUpdateView]: --- Found "
0565: + meResult.size()
0566: + " results for entity member " + meName,
0567: module);
0568:
0569: // Got results 0 -> INSERT, 1 -> UPDATE, >1 -> View is nor updatable
0570: GenericValue meGenericValue = null;
0571:
0572: if (meResult.size() == 0) {
0573: // Create new value to insert
0574: try {
0575: // Create new value to store
0576: meGenericValue = delegator.makeValue(meName,
0577: findByMap);
0578: } catch (Exception e) {
0579: throw new GenericEntityException(
0580: "Could not create new value for member entity"
0581: + meName + " of view "
0582: + modelViewEntity.getEntityName(),
0583: e);
0584: }
0585: } else if (meResult.size() == 1) {
0586: // Update existing value
0587: meGenericValue = (GenericValue) meResult.iterator()
0588: .next();
0589: } else {
0590: throw new GenericEntityException(
0591: "Found more than one result for member entity "
0592: + meName + " in view "
0593: + modelViewEntity.getEntityName()
0594: + " - this is no updatable view");
0595: }
0596:
0597: // Construct fieldsToSave list for this member entity
0598: List meFieldsToSave = FastList.newInstance();
0599: Iterator fieldIter = fieldsToSave.iterator();
0600:
0601: while (fieldIter != null && fieldIter.hasNext()) {
0602: ModelField modelField = (ModelField) fieldIter.next();
0603:
0604: if (memberModelEntity.isField(modelField.getName())) {
0605: ModelField meModelField = memberModelEntity
0606: .getField(modelField.getName());
0607:
0608: if (meModelField != null) {
0609: meGenericValue.set(meModelField.getName(),
0610: entity.get(modelField.getName()));
0611: meFieldsToSave.add(meModelField);
0612: if (Debug.verboseOn())
0613: Debug
0614: .logVerbose(
0615: "[singleUpdateView]: --- Added field to save: "
0616: + meModelField
0617: .getName()
0618: + " with value "
0619: + meGenericValue
0620: .get(meModelField
0621: .getName()),
0622: module);
0623: } else {
0624: throw new GenericEntityException(
0625: "Could not get field "
0626: + modelField.getName()
0627: + " from model entity "
0628: + memberModelEntity
0629: .getEntityName());
0630: }
0631: }
0632: }
0633:
0634: /*
0635: * Finally, do the insert/update
0636: * TODO:
0637: * Do the real inserts/updates outside the memberEntity-loop,
0638: * only if all of the found member entities are updatable.
0639: * This avoids partial creation of member entities, which would mean data inconsistency:
0640: * If not all member entities can be updated, then none should be updated
0641: */
0642: if (meResult.size() == 0) {
0643: retVal += singleInsert(meGenericValue,
0644: memberModelEntity, memberModelEntity
0645: .getFieldsCopy(), sqlP);
0646: } else {
0647: if (meFieldsToSave.size() > 0) {
0648: retVal += singleUpdate(meGenericValue,
0649: memberModelEntity, meFieldsToSave, sqlP);
0650: } else {
0651: if (Debug.verboseOn())
0652: Debug.logVerbose(
0653: "[singleUpdateView]: No update on member entity "
0654: + memberModelEntity
0655: .getEntityName()
0656: + " needed", module);
0657: }
0658: }
0659: }
0660:
0661: return retVal;
0662: }
0663:
0664: /* ====================================================================== */
0665:
0666: /* ====================================================================== */
0667:
0668: public void select(GenericEntity entity)
0669: throws GenericEntityException {
0670: SQLProcessor sqlP = new SQLProcessor(helperName);
0671:
0672: try {
0673: select(entity, sqlP);
0674: } finally {
0675: sqlP.close();
0676: }
0677: }
0678:
0679: public void select(GenericEntity entity, SQLProcessor sqlP)
0680: throws GenericEntityException {
0681: ModelEntity modelEntity = entity.getModelEntity();
0682:
0683: if (modelEntity == null) {
0684: throw new GenericModelException(
0685: "Could not find ModelEntity record for entityName: "
0686: + entity.getEntityName());
0687: }
0688:
0689: if (modelEntity.getPksSize() <= 0) {
0690: throw new GenericEntityException(
0691: "Entity has no primary keys, cannot select by primary key");
0692: }
0693:
0694: StringBuffer sqlBuffer = new StringBuffer("SELECT ");
0695:
0696: if (modelEntity.getNopksSize() > 0) {
0697: sqlBuffer.append(modelEntity.colNameString(modelEntity
0698: .getNopksCopy(), ", ", "",
0699: datasourceInfo.aliasViews));
0700: } else {
0701: sqlBuffer.append("*");
0702: }
0703:
0704: sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity,
0705: datasourceInfo));
0706: sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity,
0707: modelEntity.getPksCopy(), entity, "AND",
0708: datasourceInfo.joinStyle));
0709:
0710: try {
0711: sqlP.prepareStatement(sqlBuffer.toString(), true,
0712: ResultSet.TYPE_FORWARD_ONLY,
0713: ResultSet.CONCUR_READ_ONLY);
0714: SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity,
0715: modelFieldTypeReader);
0716: sqlP.executeQuery();
0717:
0718: if (sqlP.next()) {
0719: int idx = 1;
0720: Iterator nopkIter = modelEntity.getNopksIterator();
0721: while (nopkIter.hasNext()) {
0722: ModelField curField = (ModelField) nopkIter.next();
0723: SqlJdbcUtil.getValue(sqlP.getResultSet(), idx,
0724: curField, entity, modelFieldTypeReader);
0725: idx++;
0726: }
0727:
0728: entity.synchronizedWithDatasource();
0729: } else {
0730: // Debug.logWarning("[GenericDAO.select]: select failed, result set was empty for entity: " + entity.toString(), module);
0731: throw new GenericEntityNotFoundException(
0732: "Result set was empty for entity: "
0733: + entity.toString());
0734: }
0735: } finally {
0736: sqlP.close();
0737: }
0738: }
0739:
0740: public void partialSelect(GenericEntity entity, Set keys)
0741: throws GenericEntityException {
0742: ModelEntity modelEntity = entity.getModelEntity();
0743:
0744: if (modelEntity == null) {
0745: throw new GenericModelException(
0746: "Could not find ModelEntity record for entityName: "
0747: + entity.getEntityName());
0748: }
0749:
0750: if (modelEntity instanceof ModelViewEntity) {
0751: throw new org.ofbiz.entity.GenericNotImplementedException(
0752: "Operation partialSelect not supported yet for view entities");
0753: }
0754:
0755: /*
0756: if(entity == null || entity.<%=modelEntity.pkNameString(" == null || entity."," == null")%>) {
0757: Debug.logWarning("[GenericDAO.select]: Cannot select GenericEntity: required primary key field(s) missing.", module);
0758: return false;
0759: }
0760: */
0761: // we don't want to select ALL fields, just the nonpk fields that are in the passed GenericEntity
0762: List partialFields = FastList.newInstance();
0763:
0764: Set tempKeys = new TreeSet(keys);
0765:
0766: Iterator nopkIter = modelEntity.getNopksIterator();
0767: while (nopkIter.hasNext()) {
0768: ModelField curField = (ModelField) nopkIter.next();
0769: if (tempKeys.contains(curField.getName())) {
0770: partialFields.add(curField);
0771: tempKeys.remove(curField.getName());
0772: }
0773: }
0774:
0775: if (tempKeys.size() > 0) {
0776: throw new GenericModelException(
0777: "In partialSelect invalid field names specified: "
0778: + tempKeys.toString());
0779: }
0780:
0781: StringBuffer sqlBuffer = new StringBuffer("SELECT ");
0782:
0783: if (partialFields.size() > 0) {
0784: sqlBuffer.append(modelEntity.colNameString(partialFields,
0785: ", ", "", datasourceInfo.aliasViews));
0786: } else {
0787: sqlBuffer.append("*");
0788: }
0789: sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity,
0790: datasourceInfo));
0791: sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity,
0792: modelEntity.getPksCopy(), entity, "AND",
0793: datasourceInfo.joinStyle));
0794:
0795: SQLProcessor sqlP = new SQLProcessor(helperName);
0796:
0797: try {
0798: sqlP.prepareStatement(sqlBuffer.toString(), true,
0799: ResultSet.TYPE_FORWARD_ONLY,
0800: ResultSet.CONCUR_READ_ONLY);
0801: SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity,
0802: modelFieldTypeReader);
0803: sqlP.executeQuery();
0804:
0805: if (sqlP.next()) {
0806: for (int j = 0; j < partialFields.size(); j++) {
0807: ModelField curField = (ModelField) partialFields
0808: .get(j);
0809: SqlJdbcUtil.getValue(sqlP.getResultSet(), j + 1,
0810: curField, entity, modelFieldTypeReader);
0811: }
0812:
0813: entity.synchronizedWithDatasource();
0814: } else {
0815: // Debug.logWarning("[GenericDAO.select]: select failed, result set was empty.", module);
0816: throw new GenericEntityNotFoundException(
0817: "Result set was empty for entity: "
0818: + entity.toString());
0819: }
0820: } finally {
0821: sqlP.close();
0822: }
0823: }
0824:
0825: /* ====================================================================== */
0826: /* ====================================================================== */
0827:
0828: /** Finds GenericValues by the conditions specified in the EntityCondition object, the the EntityCondition javadoc for more details.
0829: *@param modelEntity The ModelEntity of the Entity as defined in the entity XML file
0830: *@param whereEntityCondition The EntityCondition object that specifies how to constrain this query before any groupings are done (if this is a view entity with group-by aliases)
0831: *@param havingEntityCondition The EntityCondition object that specifies how to constrain this query after any groupings are done (if this is a view entity with group-by aliases)
0832: *@param fieldsToSelect The fields of the named entity to get from the database; if empty or null all fields will be retreived
0833: *@param orderBy The fields of the named entity to order the query by; optionally add a " ASC" for ascending or " DESC" for descending
0834: *@param findOptions An instance of EntityFindOptions that specifies advanced query options. See the EntityFindOptions JavaDoc for more details.
0835: *@return EntityListIterator representing the result of the query: NOTE THAT THIS MUST BE CLOSED WHEN YOU ARE
0836: * DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT WILL MAINTAIN A DATABASE CONNECTION.
0837: */
0838: public EntityListIterator selectListIteratorByCondition(
0839: ModelEntity modelEntity,
0840: EntityCondition whereEntityCondition,
0841: EntityCondition havingEntityCondition,
0842: Collection fieldsToSelect, List orderBy,
0843: EntityFindOptions findOptions)
0844: throws GenericEntityException {
0845: if (modelEntity == null) {
0846: return null;
0847: }
0848:
0849: // if no find options passed, use default
0850: if (findOptions == null)
0851: findOptions = new EntityFindOptions();
0852:
0853: boolean verboseOn = Debug.verboseOn();
0854:
0855: if (verboseOn) {
0856: // put this inside an if statement so that we don't have to generate the string when not used...
0857: Debug.logVerbose(
0858: "Doing selectListIteratorByCondition with whereEntityCondition: "
0859: + whereEntityCondition, module);
0860: }
0861:
0862: // make two ArrayLists of fields, one for fields to select and the other for where clause fields (to find by)
0863: List selectFields = FastList.newInstance();
0864: if (fieldsToSelect != null && fieldsToSelect.size() > 0) {
0865: Set tempKeys = FastSet.newInstance();
0866: tempKeys.addAll(fieldsToSelect);
0867: Iterator fieldIter = modelEntity.getFieldsIterator();
0868: while (fieldIter.hasNext()) {
0869: ModelField curField = (ModelField) fieldIter.next();
0870: if (tempKeys.contains(curField.getName())) {
0871: selectFields.add(curField);
0872: tempKeys.remove(curField.getName());
0873: }
0874: }
0875:
0876: if (tempKeys.size() > 0) {
0877: throw new GenericModelException(
0878: "In selectListIteratorByCondition invalid field names specified: "
0879: + tempKeys.toString());
0880: }
0881: } else {
0882: selectFields = modelEntity.getFieldsCopy();
0883: }
0884:
0885: StringBuffer sqlBuffer = new StringBuffer("SELECT ");
0886:
0887: if (findOptions.getDistinct()) {
0888: sqlBuffer.append("DISTINCT ");
0889: }
0890:
0891: if (selectFields.size() > 0) {
0892: sqlBuffer.append(modelEntity.colNameString(selectFields,
0893: ", ", "", datasourceInfo.aliasViews));
0894: } else {
0895: sqlBuffer.append("*");
0896: }
0897:
0898: // FROM clause and when necessary the JOIN or LEFT JOIN clause(s) as well
0899: sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity,
0900: datasourceInfo));
0901:
0902: // WHERE clause
0903: StringBuffer whereString = new StringBuffer();
0904: String entityCondWhereString = "";
0905: List whereEntityConditionParams = FastList.newInstance();
0906: if (whereEntityCondition != null) {
0907: entityCondWhereString = whereEntityCondition
0908: .makeWhereString(modelEntity,
0909: whereEntityConditionParams,
0910: this .datasourceInfo);
0911: }
0912:
0913: String viewClause = SqlJdbcUtil.makeViewWhereClause(
0914: modelEntity, datasourceInfo.joinStyle);
0915:
0916: if (viewClause.length() > 0) {
0917: if (entityCondWhereString.length() > 0) {
0918: whereString.append("(");
0919: whereString.append(entityCondWhereString);
0920: whereString.append(") AND ");
0921: }
0922:
0923: whereString.append(viewClause);
0924: } else {
0925: whereString.append(entityCondWhereString);
0926: }
0927:
0928: if (whereString.length() > 0) {
0929: sqlBuffer.append(" WHERE ");
0930: sqlBuffer.append(whereString.toString());
0931: }
0932:
0933: // GROUP BY clause for view-entity
0934: if (modelEntity instanceof ModelViewEntity) {
0935: ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
0936: String groupByString = modelViewEntity.colNameString(
0937: modelViewEntity.getGroupBysCopy(), ", ", "", false);
0938:
0939: if (UtilValidate.isNotEmpty(groupByString)) {
0940: sqlBuffer.append(" GROUP BY ");
0941: sqlBuffer.append(groupByString);
0942: }
0943: }
0944:
0945: // HAVING clause
0946: String entityCondHavingString = "";
0947: List havingEntityConditionParams = FastList.newInstance();
0948:
0949: if (havingEntityCondition != null) {
0950: entityCondHavingString = havingEntityCondition
0951: .makeWhereString(modelEntity,
0952: havingEntityConditionParams,
0953: this .datasourceInfo);
0954: }
0955: if (entityCondHavingString.length() > 0) {
0956: sqlBuffer.append(" HAVING ");
0957: sqlBuffer.append(entityCondHavingString);
0958: }
0959:
0960: // ORDER BY clause
0961: sqlBuffer.append(SqlJdbcUtil.makeOrderByClause(modelEntity,
0962: orderBy, datasourceInfo));
0963: String sql = sqlBuffer.toString();
0964:
0965: SQLProcessor sqlP = new SQLProcessor(helperName);
0966: sqlP.prepareStatement(sql, findOptions
0967: .getSpecifyTypeAndConcur(), findOptions
0968: .getResultSetType(), findOptions
0969: .getResultSetConcurrency(), findOptions.getFetchSize(),
0970: findOptions.getMaxRows());
0971:
0972: if (verboseOn) {
0973: // put this inside an if statement so that we don't have to generate the string when not used...
0974: Debug.logVerbose("Setting the whereEntityConditionParams: "
0975: + whereEntityConditionParams, module);
0976: }
0977: // set all of the values from the Where EntityCondition
0978: Iterator whereEntityConditionParamsIter = whereEntityConditionParams
0979: .iterator();
0980: while (whereEntityConditionParamsIter.hasNext()) {
0981: EntityConditionParam whereEntityConditionParam = (EntityConditionParam) whereEntityConditionParamsIter
0982: .next();
0983:
0984: SqlJdbcUtil.setValue(sqlP, whereEntityConditionParam
0985: .getModelField(), modelEntity.getEntityName(),
0986: whereEntityConditionParam.getFieldValue(),
0987: modelFieldTypeReader);
0988: }
0989: if (verboseOn) {
0990: // put this inside an if statement so that we don't have to generate the string when not used...
0991: Debug.logVerbose(
0992: "Setting the havingEntityConditionParams: "
0993: + havingEntityConditionParams, module);
0994: }
0995: // set all of the values from the Having EntityCondition
0996: Iterator havingEntityConditionParamsIter = havingEntityConditionParams
0997: .iterator();
0998: while (havingEntityConditionParamsIter.hasNext()) {
0999: EntityConditionParam havingEntityConditionParam = (EntityConditionParam) havingEntityConditionParamsIter
1000: .next();
1001:
1002: SqlJdbcUtil.setValue(sqlP, havingEntityConditionParam
1003: .getModelField(), modelEntity.getEntityName(),
1004: havingEntityConditionParam.getFieldValue(),
1005: modelFieldTypeReader);
1006: }
1007:
1008: long queryStartTime = 0;
1009: if (Debug.timingOn()) {
1010: queryStartTime = System.currentTimeMillis();
1011: }
1012: sqlP.executeQuery();
1013: if (Debug.timingOn()) {
1014: long queryEndTime = System.currentTimeMillis();
1015: long queryTotalTime = queryEndTime - queryStartTime;
1016: if (queryTotalTime > 150) {
1017: Debug.logTiming("Ran query in " + queryTotalTime
1018: + " milli-seconds: " + sql, module);
1019: }
1020: }
1021: return new EntityListIterator(sqlP, modelEntity, selectFields,
1022: modelFieldTypeReader);
1023: }
1024:
1025: public List selectByMultiRelation(GenericValue value,
1026: ModelRelation modelRelationOne, ModelEntity modelEntityOne,
1027: ModelRelation modelRelationTwo, ModelEntity modelEntityTwo,
1028: List orderBy) throws GenericEntityException {
1029: SQLProcessor sqlP = new SQLProcessor(helperName);
1030:
1031: // get the tables names
1032: String atable = modelEntityOne.getTableName(datasourceInfo);
1033: String ttable = modelEntityTwo.getTableName(datasourceInfo);
1034:
1035: // get the column name string to select
1036: StringBuffer selsb = new StringBuffer();
1037: List collist = FastList.newInstance();
1038: List fldlist = FastList.newInstance();
1039:
1040: for (Iterator iterator = modelEntityTwo.getFieldsIterator(); iterator
1041: .hasNext();) {
1042: ModelField mf = (ModelField) iterator.next();
1043:
1044: collist.add(mf.getColName());
1045: fldlist.add(mf.getName());
1046: selsb.append(ttable + "." + mf.getColName());
1047: if (iterator.hasNext()) {
1048: selsb.append(", ");
1049: } else {
1050: selsb.append(" ");
1051: }
1052: }
1053:
1054: // construct assoc->target relation string
1055: int kmsize = modelRelationTwo.getKeyMapsSize();
1056: StringBuffer wheresb = new StringBuffer();
1057:
1058: for (int i = 0; i < kmsize; i++) {
1059: ModelKeyMap mkm = modelRelationTwo.getKeyMap(i);
1060: String lfname = mkm.getFieldName();
1061: String rfname = mkm.getRelFieldName();
1062:
1063: if (wheresb.length() > 0) {
1064: wheresb.append(" AND ");
1065: }
1066: wheresb.append(atable + "."
1067: + modelEntityOne.getField(lfname).getColName()
1068: + " = " + ttable + "."
1069: + modelEntityTwo.getField(rfname).getColName());
1070: }
1071:
1072: // construct the source entity qualifier
1073: // get the fields from relation description
1074: kmsize = modelRelationOne.getKeyMapsSize();
1075: Map bindMap = FastMap.newInstance();
1076:
1077: for (int i = 0; i < kmsize; i++) {
1078: // get the equivalent column names in the relation
1079: ModelKeyMap mkm = modelRelationOne.getKeyMap(i);
1080: String sfldname = mkm.getFieldName();
1081: String lfldname = mkm.getRelFieldName();
1082: ModelField amf = modelEntityOne.getField(lfldname);
1083: String lcolname = amf.getColName();
1084: Object rvalue = value.get(sfldname);
1085:
1086: bindMap.put(amf, rvalue);
1087: // construct one condition
1088: if (wheresb.length() > 0) {
1089: wheresb.append(" AND ");
1090: }
1091: wheresb.append(atable + "." + lcolname + " = ? ");
1092: }
1093:
1094: // construct a join sql query
1095: StringBuffer sqlsb = new StringBuffer();
1096:
1097: sqlsb.append("SELECT ");
1098: sqlsb.append(selsb.toString());
1099: sqlsb.append(" FROM ");
1100: sqlsb.append(atable + ", " + ttable);
1101: sqlsb.append(" WHERE ");
1102: sqlsb.append(wheresb.toString());
1103: sqlsb.append(SqlJdbcUtil.makeOrderByClause(modelEntityTwo,
1104: orderBy, true, datasourceInfo));
1105:
1106: // now execute the query
1107: List retlist = FastList.newInstance();
1108: GenericDelegator gd = value.getDelegator();
1109:
1110: try {
1111: sqlP.prepareStatement(sqlsb.toString());
1112: Set entrySet = bindMap.entrySet();
1113:
1114: for (Iterator iterator = entrySet.iterator(); iterator
1115: .hasNext();) {
1116: Map.Entry entry = (Map.Entry) iterator.next();
1117: ModelField mf = (ModelField) entry.getKey();
1118: Object curvalue = entry.getValue();
1119:
1120: SqlJdbcUtil.setValue(sqlP, mf, modelEntityOne
1121: .getEntityName(), curvalue,
1122: modelFieldTypeReader);
1123: }
1124: sqlP.executeQuery();
1125: //int collsize = collist.size();
1126:
1127: while (sqlP.next()) {
1128: GenericValue gv = gd.makeValue(modelEntityTwo
1129: .getEntityName(), Collections.EMPTY_MAP);
1130:
1131: // loop thru all columns for in one row
1132: int idx = 1;
1133: Iterator fldIter = fldlist.iterator();
1134: while (fldIter.hasNext()) {
1135: String fldname = (String) fldIter.next();
1136: ModelField mf = modelEntityTwo.getField(fldname);
1137: SqlJdbcUtil.getValue(sqlP.getResultSet(), idx, mf,
1138: gv, modelFieldTypeReader);
1139: idx++;
1140: }
1141: retlist.add(gv);
1142: }
1143: } finally {
1144: sqlP.close();
1145: }
1146:
1147: return retlist;
1148: }
1149:
1150: public long selectCountByCondition(ModelEntity modelEntity,
1151: EntityCondition whereEntityCondition,
1152: EntityCondition havingEntityCondition,
1153: EntityFindOptions findOptions)
1154: throws GenericEntityException {
1155: if (modelEntity == null) {
1156: return 0;
1157: }
1158:
1159: // if no find options passed, use default
1160: if (findOptions == null) {
1161: findOptions = new EntityFindOptions();
1162: }
1163: boolean verboseOn = Debug.verboseOn();
1164:
1165: if (verboseOn) {
1166: // put this inside an if statement so that we don't have to generate the string when not used...
1167: Debug.logVerbose(
1168: "Doing selectListIteratorByCondition with whereEntityCondition: "
1169: + whereEntityCondition, module);
1170: }
1171:
1172: StringBuffer sqlBuffer = new StringBuffer("SELECT ");
1173:
1174: if (findOptions.getDistinct()) {
1175: sqlBuffer.append("DISTINCT ");
1176: }
1177:
1178: sqlBuffer.append("COUNT(*) ");
1179:
1180: // FROM clause and when necessary the JOIN or LEFT JOIN clause(s) as well
1181: sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity,
1182: datasourceInfo));
1183:
1184: // WHERE clause
1185: StringBuffer whereString = new StringBuffer();
1186: String entityCondWhereString = "";
1187: List whereEntityConditionParams = FastList.newInstance();
1188: if (whereEntityCondition != null) {
1189: entityCondWhereString = whereEntityCondition
1190: .makeWhereString(modelEntity,
1191: whereEntityConditionParams,
1192: this .datasourceInfo);
1193: }
1194:
1195: String viewClause = SqlJdbcUtil.makeViewWhereClause(
1196: modelEntity, datasourceInfo.joinStyle);
1197:
1198: if (viewClause.length() > 0) {
1199: if (entityCondWhereString.length() > 0) {
1200: whereString.append("(");
1201: whereString.append(entityCondWhereString);
1202: whereString.append(") AND ");
1203: }
1204:
1205: whereString.append(viewClause);
1206: } else {
1207: whereString.append(entityCondWhereString);
1208: }
1209:
1210: if (whereString.length() > 0) {
1211: sqlBuffer.append(" WHERE ");
1212: sqlBuffer.append(whereString.toString());
1213: }
1214:
1215: // GROUP BY clause for view-entity
1216: if (modelEntity instanceof ModelViewEntity) {
1217: ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
1218: String groupByString = modelViewEntity.colNameString(
1219: modelViewEntity.getGroupBysCopy(), ", ", "", false);
1220:
1221: if (UtilValidate.isNotEmpty(groupByString)) {
1222: sqlBuffer.append(" GROUP BY ");
1223: sqlBuffer.append(groupByString);
1224: }
1225: }
1226:
1227: // HAVING clause
1228: String entityCondHavingString = "";
1229: List havingEntityConditionParams = FastList.newInstance();
1230: if (havingEntityCondition != null) {
1231: entityCondHavingString = havingEntityCondition
1232: .makeWhereString(modelEntity,
1233: havingEntityConditionParams,
1234: this .datasourceInfo);
1235: }
1236: if (entityCondHavingString.length() > 0) {
1237: sqlBuffer.append(" HAVING ");
1238: sqlBuffer.append(entityCondHavingString);
1239: }
1240:
1241: String sql = sqlBuffer.toString();
1242:
1243: SQLProcessor sqlP = new SQLProcessor(helperName);
1244: sqlP.prepareStatement(sql, findOptions
1245: .getSpecifyTypeAndConcur(), findOptions
1246: .getResultSetType(), findOptions
1247: .getResultSetConcurrency(), findOptions.getFetchSize(),
1248: findOptions.getMaxRows());
1249: if (verboseOn) {
1250: // put this inside an if statement so that we don't have to generate the string when not used...
1251: Debug.logVerbose("Setting the whereEntityConditionParams: "
1252: + whereEntityConditionParams, module);
1253: }
1254: // set all of the values from the Where EntityCondition
1255: Iterator whereEntityConditionParamsIter = whereEntityConditionParams
1256: .iterator();
1257: while (whereEntityConditionParamsIter.hasNext()) {
1258: EntityConditionParam whereEntityConditionParam = (EntityConditionParam) whereEntityConditionParamsIter
1259: .next();
1260: SqlJdbcUtil.setValue(sqlP, whereEntityConditionParam
1261: .getModelField(), modelEntity.getEntityName(),
1262: whereEntityConditionParam.getFieldValue(),
1263: modelFieldTypeReader);
1264: }
1265: if (verboseOn) {
1266: // put this inside an if statement so that we don't have to generate the string when not used...
1267: Debug.logVerbose(
1268: "Setting the havingEntityConditionParams: "
1269: + havingEntityConditionParams, module);
1270: }
1271: // set all of the values from the Having EntityCondition
1272: Iterator havingEntityConditionParamsIter = havingEntityConditionParams
1273: .iterator();
1274: while (havingEntityConditionParamsIter.hasNext()) {
1275: EntityConditionParam havingEntityConditionParam = (EntityConditionParam) havingEntityConditionParamsIter
1276: .next();
1277: SqlJdbcUtil.setValue(sqlP, havingEntityConditionParam
1278: .getModelField(), modelEntity.getEntityName(),
1279: havingEntityConditionParam.getFieldValue(),
1280: modelFieldTypeReader);
1281: }
1282:
1283: try {
1284: sqlP.executeQuery();
1285: long count = 0;
1286: ResultSet resultSet = sqlP.getResultSet();
1287: if (resultSet.next()) {
1288: count = resultSet.getLong(1);
1289: }
1290: return count;
1291: } catch (SQLException e) {
1292: throw new GenericDataSourceException(
1293: "Error getting count value", e);
1294: } finally {
1295: sqlP.close();
1296: }
1297: }
1298:
1299: /* ====================================================================== */
1300:
1301: /* ====================================================================== */
1302:
1303: public int delete(GenericEntity entity)
1304: throws GenericEntityException {
1305: SQLProcessor sqlP = new SQLProcessor(helperName);
1306:
1307: try {
1308: return delete(entity, sqlP);
1309: } catch (GenericDataSourceException e) {
1310: sqlP.rollback();
1311: throw new GenericDataSourceException(
1312: "Exception while deleting the following entity: "
1313: + entity.toString(), e);
1314: } finally {
1315: sqlP.close();
1316: }
1317: }
1318:
1319: public int delete(GenericEntity entity, SQLProcessor sqlP)
1320: throws GenericEntityException {
1321: ModelEntity modelEntity = entity.getModelEntity();
1322: if (modelEntity == null) {
1323: throw new GenericModelException(
1324: "Could not find ModelEntity record for entityName: "
1325: + entity.getEntityName());
1326: }
1327: if (modelEntity instanceof ModelViewEntity) {
1328: throw new org.ofbiz.entity.GenericNotImplementedException(
1329: "Operation delete not supported yet for view entities");
1330: }
1331:
1332: String sql = "DELETE FROM "
1333: + modelEntity.getTableName(datasourceInfo)
1334: + " WHERE "
1335: + SqlJdbcUtil.makeWhereStringFromFields(modelEntity
1336: .getPksCopy(), entity, "AND");
1337:
1338: int retVal;
1339:
1340: try {
1341: sqlP.prepareStatement(sql);
1342: SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity,
1343: modelFieldTypeReader);
1344: retVal = sqlP.executeUpdate();
1345: entity.removedFromDatasource();
1346: } finally {
1347: sqlP.close();
1348: }
1349: return retVal;
1350: }
1351:
1352: public int deleteByCondition(ModelEntity modelEntity,
1353: EntityCondition condition) throws GenericEntityException {
1354: SQLProcessor sqlP = new SQLProcessor(helperName);
1355:
1356: try {
1357: return deleteByCondition(modelEntity, condition, sqlP);
1358: } catch (GenericDataSourceException e) {
1359: sqlP.rollback();
1360: throw new GenericDataSourceException(
1361: "Generic Entity Exception occured in deleteByCondition",
1362: e);
1363: } finally {
1364: sqlP.close();
1365: }
1366: }
1367:
1368: public int deleteByCondition(ModelEntity modelEntity,
1369: EntityCondition condition, SQLProcessor sqlP)
1370: throws GenericEntityException {
1371: if (modelEntity == null || condition == null)
1372: return 0;
1373: if (modelEntity instanceof ModelViewEntity) {
1374: throw new org.ofbiz.entity.GenericNotImplementedException(
1375: "Operation deleteByCondition not supported yet for view entities");
1376: }
1377:
1378: String sql = "DELETE FROM "
1379: + modelEntity.getTableName(this .datasourceInfo);
1380:
1381: sql += " WHERE "
1382: + condition.makeWhereString(modelEntity, null,
1383: this .datasourceInfo);
1384:
1385: try {
1386: sqlP.prepareStatement(sql);
1387:
1388: return sqlP.executeUpdate();
1389: } finally {
1390: sqlP.close();
1391: }
1392: }
1393:
1394: /* ====================================================================== */
1395:
1396: public void checkDb(Map modelEntities, List messages,
1397: boolean addMissing) {
1398: DatabaseUtil dbUtil = new DatabaseUtil(this .helperName);
1399: dbUtil.checkDb(modelEntities, messages, addMissing);
1400: }
1401:
1402: /** Creates a list of ModelEntity objects based on meta data from the database */
1403: public List induceModelFromDb(Collection messages) {
1404: DatabaseUtil dbUtil = new DatabaseUtil(this.helperName);
1405: return dbUtil.induceModelFromDb(messages);
1406: }
1407: }
|