use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.
the class UpgradeServices method generateMySqlFileWithAlterTableForTimestamps.
/**
* Generate sql file for data migration from mySql.5 and earlier version to mySql.6 to later version
* mySql added support in 5.6 to support microseconds for datetime field.
* https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
* <ul>
* <li>Service will take [groupName] as in param,</li>
* <li>iterate all the entity and check for datetime and time field</li>
* <li>it will generate alter table sql statement to update the field data type</li>
* <li>datetime will be altered with DATETIME(3)</li>
* <li>time will be altered with TIME(3)</li>
* <li>sql fiel will be created at following location</li>
* <li>${ofbiz.home}/runtime/tempfiles/[groupName].sql</li>
* </ul>
* @param dctx
* @param context
* @return Map with the success result of the service,
*/
public static Map<String, Object> generateMySqlFileWithAlterTableForTimestamps(DispatchContext dctx, Map<String, Object> context) {
Delegator delegator = dctx.getDelegator();
Security security = dctx.getSecurity();
Locale locale = (Locale) context.get("locale");
// check permission
GenericValue userLogin = (GenericValue) context.get("userLogin");
if (!security.hasPermission("ENTITY_MAINT", userLogin)) {
Debug.logError(UtilProperties.getMessage(resource, "EntityExtServicePermissionNotGranted", locale), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "EntityExtServicePermissionNotGranted", locale));
}
String groupName = (String) context.get("groupName");
Map<String, ModelEntity> modelEntities;
try (PrintWriter dataWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(System.getProperty("ofbiz.home") + "/runtime/tempfiles/" + groupName + ".sql")), "UTF-8")))) {
modelEntities = delegator.getModelEntityMapByGroup(groupName);
/* TODO:
1) fetch the meta data of the "date-time" field using the JDBC connection and JDBC meta data;
2) compare it to date-time and only generate the alter statement if they differs;
*/
dataWriter.println("SET FOREIGN_KEY_CHECKS=0;");
for (ModelEntity modelEntity : modelEntities.values()) {
List<ModelField> fields = modelEntity.getFieldsUnmodifiable();
for (ModelField field : fields) {
if (modelEntity.getPlainTableName() != null) {
if ("date-time".equals(field.getType())) {
dataWriter.println("ALTER TABLE " + modelEntity.getPlainTableName() + " MODIFY " + field.getColName() + " DATETIME(3);");
}
if ("time".equals(field.getType())) {
dataWriter.println("ALTER TABLE " + modelEntity.getPlainTableName() + " MODIFY " + field.getColName() + " TIME(3);");
}
}
}
}
dataWriter.println("SET FOREIGN_KEY_CHECKS=1;");
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting list of entities in group: " + e.toString(), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "EntityExtErrorGettingListOfEntityInGroup", UtilMisc.toMap("errorString", e.toString()), locale));
} catch (FileNotFoundException | UnsupportedEncodingException e) {
Debug.logError(e, e.getMessage(), module);
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.
the class SqlJdbcUtil method makeViewWhereClause.
public static String makeViewWhereClause(ModelEntity modelEntity, String joinStyle) throws GenericEntityException {
if (modelEntity instanceof ModelViewEntity) {
StringBuilder whereString = new StringBuilder();
ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
if ("ansi".equals(joinStyle) || "ansi-no-parenthesis".equals(joinStyle)) {
// nothing to do here, all done in the JOIN clauses
} else if ("theta-oracle".equals(joinStyle) || "theta-mssql".equals(joinStyle)) {
boolean isOracleStyle = "theta-oracle".equals(joinStyle);
boolean isMssqlStyle = "theta-mssql".equals(joinStyle);
for (int i = 0; i < modelViewEntity.getViewLinksSize(); i++) {
ModelViewEntity.ModelViewLink viewLink = modelViewEntity.getViewLink(i);
ModelEntity linkEntity = modelViewEntity.getMemberModelEntity(viewLink.getEntityAlias());
ModelEntity relLinkEntity = modelViewEntity.getMemberModelEntity(viewLink.getRelEntityAlias());
if (linkEntity == null) {
throw new GenericEntityException("Link entity not found with alias: " + viewLink.getEntityAlias() + " for entity: " + modelViewEntity.getEntityName());
}
if (relLinkEntity == null) {
throw new GenericEntityException("Rel-Link entity not found with alias: " + viewLink.getRelEntityAlias() + " for entity: " + modelViewEntity.getEntityName());
}
for (int j = 0; j < viewLink.getKeyMapsSize(); j++) {
ModelKeyMap keyMap = viewLink.getKeyMap(j);
ModelField linkField = linkEntity.getField(keyMap.getFieldName());
ModelField relLinkField = relLinkEntity.getField(keyMap.getRelFieldName());
if (whereString.length() > 0) {
whereString.append(" AND ");
}
whereString.append(viewLink.getEntityAlias());
whereString.append(".");
whereString.append(linkField.getColName());
// if (isOracleStyle && linkMemberEntity.getOptional()) whereString.append(" (+) ");
if (isMssqlStyle && viewLink.isRelOptional())
whereString.append("*");
whereString.append("=");
// if (isMssqlStyle && linkMemberEntity.getOptional()) whereString.append("*");
if (isOracleStyle && viewLink.isRelOptional())
whereString.append(" (+) ");
whereString.append(viewLink.getRelEntityAlias());
whereString.append(".");
whereString.append(relLinkField.getColName());
}
}
} else {
throw new GenericModelException("The join-style " + joinStyle + " is not supported");
}
if (whereString.length() > 0) {
return "(" + whereString.toString() + ")";
}
}
return "";
}
use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.
the class SqlJdbcUtil method makeWhereStringFromFields.
/**
* Makes a WHERE clause String with "<col name>=?" if not null or "<col name> IS null" if null, all AND separated
*/
public static StringBuilder makeWhereStringFromFields(StringBuilder sb, List<ModelField> modelFields, Map<String, Object> fields, String operator, List<EntityConditionParam> entityConditionParams) {
if (modelFields.size() < 1) {
return sb;
}
Iterator<ModelField> iter = modelFields.iterator();
while (iter.hasNext()) {
Object item = iter.next();
Object name = null;
ModelField modelField = null;
if (item instanceof ModelField) {
modelField = (ModelField) item;
sb.append(modelField.getColValue());
name = modelField.getName();
} else {
sb.append(item);
name = item;
}
Object fieldValue = fields.get(name);
if (fieldValue != null && fieldValue != GenericEntity.NULL_FIELD) {
sb.append('=');
addValue(sb, modelField, fieldValue, entityConditionParams);
} else {
sb.append(" IS NULL");
}
if (iter.hasNext()) {
sb.append(' ');
sb.append(operator);
sb.append(' ');
}
}
return sb;
}
use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.
the class EntityAutoEngine method runSync.
/**
* @see org.apache.ofbiz.service.engine.GenericEngine#runSync(java.lang.String, org.apache.ofbiz.service.ModelService, java.util.Map)
*/
@Override
public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> parameters) throws GenericServiceException {
// static java service methods should be: public Map<String, Object> methodName(DispatchContext dctx, Map<String, Object> context)
DispatchContext dctx = dispatcher.getLocalContext(localName);
Locale locale = (Locale) parameters.get("locale");
Map<String, Object> result = ServiceUtil.returnSuccess();
// check the package and method names
if (modelService.invoke == null || !availableInvokeActionNames.contains(modelService.invoke)) {
throw new GenericServiceException("In Service [" + modelService.name + "] the invoke value must be create, update, or delete for entity-auto engine");
}
if (UtilValidate.isEmpty(modelService.defaultEntityName)) {
throw new GenericServiceException("In Service [" + modelService.name + "] you must specify a default-entity-name for entity-auto engine");
}
ModelEntity modelEntity = dctx.getDelegator().getModelEntity(modelService.defaultEntityName);
if (modelEntity == null) {
throw new GenericServiceException("In Service [" + modelService.name + "] the specified default-entity-name [" + modelService.defaultEntityName + "] is not valid");
}
try {
boolean allPksInOnly = true;
List<String> pkFieldNameOutOnly = null;
/* Check for each pk if it's :
* 1. part IN
* 2. or part IN and OUT, but without value but present on parameters map
* Help the engine to determinate the operation to realize for a create call or validate that
* any pk is present for update/delete call.
*/
for (ModelField pkField : modelEntity.getPkFieldsUnmodifiable()) {
ModelParam pkParam = modelService.getParam(pkField.getName());
boolean pkValueInParameters = pkParam.isIn() && UtilValidate.isNotEmpty(parameters.get(pkParam.getFieldName()));
if (pkParam.isOut() && !pkValueInParameters) {
if (pkFieldNameOutOnly == null) {
pkFieldNameOutOnly = new LinkedList<>();
allPksInOnly = false;
}
pkFieldNameOutOnly.add(pkField.getName());
}
}
switch(modelService.invoke) {
case "create":
result = invokeCreate(dctx, parameters, modelService, modelEntity, allPksInOnly, pkFieldNameOutOnly);
break;
case "update":
result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
break;
case "delete":
result = invokeDelete(dctx, parameters, modelService, modelEntity, allPksInOnly);
break;
case "expire":
result = invokeExpire(dctx, parameters, modelService, modelEntity, allPksInOnly);
if (ServiceUtil.isSuccess(result)) {
result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
}
break;
default:
break;
}
GenericValue crudValue = (GenericValue) result.get("crudValue");
if (crudValue != null) {
result.remove("crudValue");
result.putAll(modelService.makeValid(crudValue, ModelService.OUT_PARAM));
}
} catch (GeneralException e) {
Debug.logError(e, "Error doing entity-auto operation for entity [" + modelEntity.getEntityName() + "] in service [" + modelService.name + "]: " + e.toString(), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceEntityAutoOperation", UtilMisc.toMap("entityName", modelEntity.getEntityName(), "serviceName", modelService.name, "errorString", e.toString()), locale));
}
result.put(ModelService.SUCCESS_MESSAGE, ServiceUtil.makeSuccessMessage(result, "", "", "", ""));
return result;
}
use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.
the class EntityAutoEngine method invokeUpdate.
private static Map<String, Object> invokeUpdate(DispatchContext dctx, Map<String, Object> parameters, ModelService modelService, ModelEntity modelEntity, boolean allPksInOnly) throws GeneralException {
Locale locale = (Locale) parameters.get("locale");
Map<String, Object> localContext = new HashMap<>();
localContext.put("parameters", parameters);
Map<String, Object> result = ServiceUtil.returnSuccess();
// check to make sure that all primary key fields are defined as IN attributes
if (!allPksInOnly) {
throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the update invoke option not all pk fields have the mode IN");
}
GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
if (lookedUpValue == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueNotFound", locale));
}
// localContext.put("lookedUpValue", lookedUpValue);
// populate the oldStatusId out if there is a service parameter for it, and before we do the set non-pk fields
/*
<auto-attributes include="pk" mode="IN" optional="false"/>
<attribute name="oldStatusId" type="String" mode="OUT" optional="false"/>
*
<field-to-result field-name="lookedUpValue.statusId" result-name="oldStatusId"/>
*/
ModelParam statusIdParam = modelService.getParam("statusId");
ModelField statusIdField = modelEntity.getField("statusId");
ModelParam oldStatusIdParam = modelService.getParam("oldStatusId");
if (statusIdParam != null && statusIdParam.isIn() && oldStatusIdParam != null && oldStatusIdParam.isOut() && statusIdField != null) {
result.put("oldStatusId", lookedUpValue.get("statusId"));
}
// do the StatusValidChange check
/*
<if-compare-field field="lookedUpValue.statusId" operator="not-equals" to-field="parameters.statusId">
<!-- if the record exists there should be a statusId, but just in case make it so it won't blow up -->
<if-not-empty field="lookedUpValue.statusId">
<!-- if statusId change is not in the StatusValidChange list, complain... -->
<entity-one entity-name="StatusValidChange" value-name="statusValidChange" auto-field-map="false">
<field-map field-name="statusId" env-name="lookedUpValue.statusId"/>
<field-map field-name="statusIdTo" env-name="parameters.statusId"/>
</entity-one>
<if-empty field="statusValidChange">
<!-- no valid change record found? return an error... -->
<add-error><fail-property resource="CommonUiLabels" property="CommonErrorNoStatusValidChange"/></add-error>
<check-errors/>
</if-empty>
</if-not-empty>
</if-compare-field>
*/
String parameterStatusId = (String) parameters.get("statusId");
if (statusIdParam != null && statusIdParam.isIn() && UtilValidate.isNotEmpty(parameterStatusId) && statusIdField != null) {
String lookedUpStatusId = (String) lookedUpValue.get("statusId");
if (UtilValidate.isNotEmpty(lookedUpStatusId) && !parameterStatusId.equals(lookedUpStatusId)) {
// there was an old status, and in this call we are trying to change it, so do the StatusValidChange check
GenericValue statusValidChange = dctx.getDelegator().findOne("StatusValidChange", true, "statusId", lookedUpStatusId, "statusIdTo", parameterStatusId);
if (statusValidChange == null) {
// uh-oh, no valid change...
return ServiceUtil.returnError(UtilProperties.getMessage("CommonUiLabels", "CommonErrorNoStatusValidChange", localContext, locale));
}
}
}
// NOTE: nothing here to maintain the status history, that should be done with a custom service called by SECA rule
lookedUpValue.setNonPKFields(parameters, true);
if (modelEntity.getField("lastModifiedDate") != null || modelEntity.getField("changedDate") != null) {
if (modelEntity.getField("lastModifiedDate") != null) {
lookedUpValue.set("lastModifiedDate", UtilDateTime.nowTimestamp());
} else {
lookedUpValue.set("changedDate", UtilDateTime.nowTimestamp());
}
if (modelEntity.getField("lastModifiedByUserLogin") != null || modelEntity.getField("changedByUserLogin") != null) {
GenericValue userLogin = (GenericValue) parameters.get("userLogin");
if (userLogin != null) {
if (modelEntity.getField("lastModifiedByUserLogin") != null) {
lookedUpValue.set("lastModifiedByUserLogin", userLogin.get("userLoginId"));
} else {
lookedUpValue.set("changedByUserLogin", userLogin.get("userLoginId"));
}
}
}
}
if (modelEntity.getField("changeByUserLoginId") != null) {
if (modelEntity.getEntityName().endsWith("Status")) {
// Oh update on EntityStatus concept detected ... not possible, return invalid request
throw new GenericServiceException("You call a updating operation on entity that track the activity, sorry I can't do that, please amazing developer check your service definition ;)");
}
GenericValue userLogin = (GenericValue) parameters.get("userLogin");
if (userLogin != null) {
lookedUpValue.set("changeByUserLoginId", userLogin.get("userLoginId"));
} else {
throw new GenericServiceException("You call a updating operation on entity that track the activity, sorry I can't do that, please amazing developer check your service definition ;)");
}
}
lookedUpValue.store();
result.put("crudValue", lookedUpValue);
result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage("ServiceUiLabels", "EntityUpdatedSuccessfully", UtilMisc.toMap("entityName", modelEntity.getEntityName()), locale));
return result;
}
Aggregations