|
Author: hansbak
Date: Wed Dec 26 04:19:34 2012 New Revision: 1425813 URL: http://svn.apache.org/viewvc?rev=1425813&view=rev Log: Nice contribution from Nicolas, now be able to modify and delete database records using the framework import function: https://issues.apache.org/jira/browse/OFBIZ-4949 Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java?rev=1425813&r1=1425812&r2=1425813&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java Wed Dec 26 04:19:34 2012 @@ -694,6 +694,20 @@ public class ModelEntity extends ModelIn return nameList; } + /** + * @return field names list, managed by entity-engine + */ + public List<String> getAutomaticFieldNames() { + List<String> nameList = FastList.newInstance(); + if (! this.noAutoStamp) { + nameList.add(STAMP_FIELD); + nameList.add(STAMP_TX_FIELD); + nameList.add(CREATE_STAMP_FIELD); + nameList.add(CREATE_STAMP_TX_FIELD); + } + return nameList; + } + public int getRelationsSize() { return this.relations.size(); } Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java?rev=1425813&r1=1425812&r2=1425813&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java Wed Dec 26 04:19:34 2012 @@ -40,12 +40,15 @@ import javolution.xml.sax.XMLReaderImpl; import org.ofbiz.base.location.FlexibleLocation; import org.ofbiz.base.util.Base64; import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; import org.ofbiz.base.util.template.FreeMarkerWorker; import org.ofbiz.entity.Delegator; import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.GenericEntityNotFoundException; import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.datasource.GenericHelper; import org.ofbiz.entity.eca.EntityEcaHandler; import org.ofbiz.entity.model.ModelEntity; import org.ofbiz.entity.model.ModelField; @@ -78,6 +81,11 @@ public class EntitySaxReader implements protected CharSequence currentFieldName = null; protected CharSequence currentFieldValue = null; protected long numberRead = 0; + protected long numberCreated = 0; + protected long numberUpdated = 0; + protected long numberReplaced = 0; + protected long numberDeleted = 0; + protected long numberSkipped = 0; protected int valuesPerWrite = 100; protected int valuesPerMessage = 1000; @@ -88,9 +96,13 @@ public class EntitySaxReader implements protected boolean checkDataOnly = false; protected boolean doCacheClear = true; protected boolean disableEeca = false; + protected enum Action {CREATE, CREATE_UPDATE, CREATE_REPLACE, DELETE}; + protected List<String> actionTags = UtilMisc.toList("create", "create-update", "create-replace", "delete"); + protected Action currentAction = Action.CREATE_UPDATE; protected List<Object> messageList = null; protected List<GenericValue> valuesToWrite = new ArrayList<GenericValue>(valuesPerWrite); + protected List<GenericValue> valuesToDelete = new ArrayList<GenericValue>(valuesPerWrite); protected boolean isParseForTemplate = false; protected CharSequence templatePath = null; @@ -202,6 +214,14 @@ public class EntitySaxReader implements } } + public void setAction(Action action) { + this.currentAction = action; + } + + public Action getAction() { + return this.currentAction; + } + public long parse(String content) throws SAXException, java.io.IOException { if (content == null) { Debug.logWarning("content was null, doing nothing", module); @@ -272,10 +292,14 @@ public class EntitySaxReader implements try { parser.parse(is); // make sure all of the values to write got written... - if (valuesToWrite.size() > 0) { + if (! valuesToWrite.isEmpty()) { writeValues(valuesToWrite); valuesToWrite.clear(); } + if (! valuesToDelete.isEmpty()) { + delegator.removeAll(valuesToDelete); + valuesToDelete.clear(); + } TransactionUtil.commit(beganTransaction); } catch (Exception e) { String errMsg = "An error occurred saving the data, rolling back transaction (" + beganTransaction + ")"; @@ -287,6 +311,11 @@ public class EntitySaxReader implements throw new SAXException("A transaction error occurred reading data", e); } Debug.logImportant("Finished " + numberRead + " values from " + docDescription, module); + if (Debug.verboseOn()) { + Debug.logVerbose(" Detail created : " + numberCreated + ", skipped : " + numberSkipped + + ", updated : " + numberUpdated + ", replaced : " + numberReplaced + + ", deleted : " + numberDeleted, module); + } return numberRead; } @@ -384,6 +413,12 @@ public class EntitySaxReader implements return; } + //Test if end action tag, set action to default + if (actionTags.contains(fullNameString)) { + setAction(Action.CREATE_UPDATE); + return; + } + if (currentValue != null) { if (currentFieldName != null) { if (UtilValidate.isNotEmpty(currentFieldValue)) { @@ -419,22 +454,58 @@ public class EntitySaxReader implements } try { - if (this.useTryInsertMethod && !this.checkDataOnly) { - // this technique is faster for data sets where most, if not all, values do not already exist in the database - try { - currentValue.create(); - } catch (GenericEntityException e1) { - // create failed, try a store, if that fails too we have a real error and the catch outside of this should handle it - currentValue.store(); + boolean exist = true; + boolean skip = false; + //if verbose on, check if entity exist on database for count each action + //It's necessay to check also for specific action CREATE and DELETE to ensure it's ok + if (Action.CREATE == currentAction || Action.DELETE == currentAction || Debug.verboseOn()) { + GenericHelper helper = delegator.getEntityHelper(currentValue.getEntityName()); + if (currentValue.containsPrimaryKey()) { + try { + helper.findByPrimaryKey(currentValue.getPrimaryKey()); + } catch (GenericEntityNotFoundException e) {exist = false;} } - } else { - valuesToWrite.add(currentValue); - if (valuesToWrite.size() >= valuesPerWrite) { - writeValues(valuesToWrite); - valuesToWrite.clear(); + if (Action.CREATE == currentAction && exist) { skip = true; } + else if (Action.DELETE == currentAction && ! exist) { skip = true; } + } + if (! skip) { + if (this.useTryInsertMethod && !this.checkDataOnly) { + if (Action.CREATE == currentAction) { currentValue.create(); } + else if (Action.DELETE == currentAction) { + try { + currentValue.remove(); + } catch (GenericEntityException e1) { + String errMsg = "Error deleting value"; + Debug.logError(e1, errMsg, module); + throw new SAXException(errMsg, e1); + } + } else { + // this technique is faster for data sets where most, if not all, values do not already exist in the database + try { + currentValue.create(); + } catch (GenericEntityException e1) { + // create failed, try a store, if that fails too we have a real error and the catch outside of this should handle it + currentValue.store(); + } + } + } else { + if (Action.DELETE == currentAction) { + valuesToDelete.add(currentValue); + if (valuesToDelete.size() >= valuesPerWrite) { + delegator.removeAll(valuesToDelete, doCacheClear); + valuesToDelete.clear(); + } + } else { + valuesToWrite.add(currentValue); + if (valuesToWrite.size() >= valuesPerWrite) { + writeValues(valuesToWrite); + valuesToWrite.clear(); + } + } } } numberRead++; + if (Debug.verboseOn()) countValue(skip, exist); if ((numberRead % valuesPerMessage) == 0) { Debug.logImportant("Another " + valuesPerMessage + " values imported: now up to " + numberRead, module); } @@ -448,6 +519,15 @@ public class EntitySaxReader implements } } + //Use for detail the loading entities + protected void countValue(boolean skip, boolean exist) { + if (skip) numberSkipped++; + else if (Action.DELETE == currentAction) numberDeleted++; + else if (Action.CREATE == currentAction || ! exist) numberCreated++; + else if (Action.CREATE_REPLACE == currentAction) numberReplaced++; + else numberUpdated++; + } + public void endPrefixMapping(CharArray prefix) throws org.xml.sax.SAXException {} public void ignorableWhitespace(char[] values, int offset, int count) throws org.xml.sax.SAXException { @@ -526,6 +606,15 @@ public class EntitySaxReader implements return; } + //Test if action change + if (actionTags.contains(fullNameString)) { + if ("create".equals(fullNameString)) setAction(Action.CREATE); + if ("create-update".equals(fullNameString)) setAction(Action.CREATE_UPDATE); + if ("create-replace".equals(fullNameString)) setAction(Action.CREATE_REPLACE); + if ("delete".equals(fullNameString)) setAction(Action.DELETE); + return; + } + if (currentValue != null) { // we have a nested value/CDATA element currentFieldName = fullName; @@ -554,6 +643,13 @@ public class EntitySaxReader implements if (currentValue != null) { int length = attributes.getLength(); + List<String> absentFields = null; + if (Action.CREATE_REPLACE == currentAction) { + //get all non pk fields + ModelEntity currentEntity = currentValue.getModelEntity(); + absentFields = currentEntity.getNoPkFieldNames(); + absentFields.removeAll(currentEntity.getAutomaticFieldNames()); + } for (int i = 0; i < length; i++) { CharSequence name = attributes.getLocalName(i); @@ -567,6 +663,7 @@ public class EntitySaxReader implements if (UtilValidate.isNotEmpty(value)) { if (currentValue.getModelEntity().isField(name.toString())) { currentValue.setString(name.toString(), value.toString()); + if (Action.CREATE_REPLACE == currentAction && absentFields != null) absentFields.remove(name); } else { Debug.logWarning("Ignoring invalid field name [" + name + "] found for the entity: " + currentValue.getEntityName() + " with value=" + value, module); } @@ -575,6 +672,11 @@ public class EntitySaxReader implements Debug.logWarning(e, "Could not set field " + entityName + "." + name + " to the value " + value, module); } } + if (Action.CREATE_REPLACE == currentAction && absentFields != null) { + for (String fieldName : absentFields) { + currentValue.set(fieldName, null); + } + } } } } Modified: ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml?rev=1425813&r1=1425812&r2=1425813&view=diff ============================================================================== --- ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml (original) +++ ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml Wed Dec 26 04:19:34 2012 @@ -61,6 +61,20 @@ under the License. <Example exampleId="EX08" exampleName="Example 8" exampleTypeId="MADE_UP" statusId="EXST_IN_DESIGN"/> <Example exampleId="EX09" exampleName="Example 9" exampleTypeId="MADE_UP" statusId="EXST_IN_DESIGN"/> <Example exampleId="EX10" exampleName="Example 10" exampleTypeId="MADE_UP" statusId="EXST_IN_DESIGN"/> - <Example exampleId="EX11" exampleName="Example 11" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> - <Example exampleId="EX12" exampleName="Example 12" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> + <Example exampleId="EX11" exampleName="Example 11" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN" description="mMy inspired example 11 description"/> + <Example exampleId="EX12" exampleName="Example 12" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN" description="mMy inspired example 12 description"/> + <create> + <Example exampleId="EX13" exampleName="Example 13" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> + <Example exampleId="EX14" exampleName="Example 14" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> + </create> + <create-replace> + <Example exampleId="EX12" exampleName="Example 12 after replace" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> + </create-replace> + <create-update> + <Example exampleId="EX12" exampleName="Example 11 after update" exampleTypeId="INSPIRED" statusId="EXST_IN_DESIGN"/> + </create-update> + <delete> + <Example exampleId="EX09"/> + </delete> + <Example exampleId="EX10" exampleName="Example 10 after update"/> </entity-engine-xml> |
| Free forum by Nabble | Edit this page |
