You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ha...@apache.org on 2012/12/26 05:19:34 UTC
svn commit: r1425813 - in /ofbiz/trunk:
framework/entity/src/org/ofbiz/entity/model/ModelEntity.java
framework/entity/src/org/ofbiz/entity/util/EntitySaxReader.java
specialpurpose/example/data/ExampleDemoData.xml
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>