use of org.apache.ofbiz.entity.model.ModelFieldType in project ofbiz-framework by apache.
the class GenericEntity method set.
/**
* Sets the named field to the passed value. If value is null, it is only
* set if the setIfNull parameter is true. This is useful because an update
* will only set values that are included in the HashMap and will store null
* values in the HashMap to the datastore. If a value is not in the HashMap,
* it will be left unmodified in the datastore.
* @param name The field name to set
* @param value The value to set
* @param setIfNull Specifies whether or not to set the value if it is null
*/
public Object set(String name, Object value, boolean setIfNull) {
assertIsMutable();
ModelField modelField = getModelEntity().getField(name);
if (modelField == null) {
throw new IllegalArgumentException("[GenericEntity.set] \"" + name + "\" is not a field of " + entityName + ", must be one of: " + getModelEntity().fieldNameString());
}
if (value != null || setIfNull) {
ModelFieldType type = null;
try {
type = getDelegator().getEntityFieldType(getModelEntity(), modelField.getType());
} catch (IllegalStateException | GenericEntityException e) {
Debug.logWarning(e, module);
}
if (type == null) {
throw new IllegalArgumentException("Type " + modelField.getType() + " not found for entity [" + this.getEntityName() + "]; probably because there is no datasource (helper) setup for the entity group that this entity is in: [" + this.getDelegator().getEntityGroupName(this.getEntityName()) + "]");
}
if (value instanceof Boolean) {
// if this is a Boolean check to see if we should convert from an indicator or just leave as is
try {
int fieldType = SqlJdbcUtil.getType(type.getJavaType());
if (fieldType != 10) {
value = ((Boolean) value).booleanValue() ? "Y" : "N";
}
} catch (GenericNotImplementedException e) {
throw new IllegalArgumentException(e.getMessage());
}
} else if (value != null && !(value instanceof NULL)) {
// make sure the type matches the field Java type
if (value instanceof TimeDuration) {
try {
value = ObjectType.simpleTypeConvert(value, type.getJavaType(), null, null);
} catch (GeneralException e) {
Debug.logError(e, module);
}
} else if ((value instanceof String) && "byte[]".equals(type.getJavaType())) {
value = ((String) value).getBytes(UtilIO.getUtf8());
}
if (!ObjectType.instanceOf(value, type.getJavaType())) {
if (!("java.sql.Blob".equals(type.getJavaType()) && (value instanceof byte[] || ObjectType.instanceOf(value, ByteBuffer.class)))) {
String errMsg = "In entity field [" + this.getEntityName() + "." + name + "] set the value passed in [" + value.getClass().getName() + "] is not compatible with the Java type of the field [" + type.getJavaType() + "]";
// eventually we should do this, but for now we'll do a "soft" failure: throw new IllegalArgumentException(errMsg);
Debug.logWarning(new Exception("Location of database type warning"), "=-=-=-=-=-=-=-=-= Database type warning GenericEntity.set =-=-=-=-=-=-=-=-= " + errMsg, module);
}
}
}
Object old = fields.put(name, value);
generateHashCode = true;
this.setChanged();
this.notifyObservers(name);
return old;
}
return fields.get(name);
}
use of org.apache.ofbiz.entity.model.ModelFieldType in project ofbiz-framework by apache.
the class ModelServiceReader method createAutoAttrDef.
private void createAutoAttrDef(Element autoElement, ModelService service) {
// get the entity name; first from the auto-attributes then from the service def
String entityName = UtilXml.checkEmpty(autoElement.getAttribute("entity-name"));
if (UtilValidate.isEmpty(entityName)) {
entityName = service.defaultEntityName;
if (UtilValidate.isEmpty(entityName)) {
Debug.logWarning("Auto-Attribute does not specify an entity-name; not default-entity on service definition", module);
}
}
// get the include type 'pk|nonpk|all'
String includeType = UtilXml.checkEmpty(autoElement.getAttribute("include"));
boolean includePk = "pk".equals(includeType) || "all".equals(includeType);
boolean includeNonPk = "nonpk".equals(includeType) || "all".equals(includeType);
if (delegator == null) {
Debug.logWarning("Cannot use auto-attribute fields with a null delegator", module);
}
if (delegator != null && entityName != null) {
Map<String, ModelParam> modelParamMap = new LinkedHashMap<>();
try {
ModelEntity entity = delegator.getModelEntity(entityName);
if (entity == null) {
throw new GeneralException("Could not find entity with name [" + entityName + "]");
}
Iterator<ModelField> fieldsIter = entity.getFieldsIterator();
while (fieldsIter.hasNext()) {
ModelField field = fieldsIter.next();
if ((!field.getIsAutoCreatedInternal()) && ((field.getIsPk() && includePk) || (!field.getIsPk() && includeNonPk))) {
ModelFieldType fieldType = delegator.getEntityFieldType(entity, field.getType());
if (fieldType == null) {
throw new GeneralException("Null field type from delegator for entity [" + entityName + "]");
}
ModelParam param = new ModelParam();
param.entityName = entityName;
param.fieldName = field.getName();
param.name = field.getName();
param.type = fieldType.getJavaType();
// this is a special case where we use something different in the service layer than we do in the entity/data layer
if ("java.sql.Blob".equals(param.type)) {
param.type = "java.nio.ByteBuffer";
}
param.mode = UtilXml.checkEmpty(autoElement.getAttribute("mode")).intern();
// default to true
param.optional = "true".equalsIgnoreCase(autoElement.getAttribute("optional"));
// default to false
param.formDisplay = !"false".equalsIgnoreCase(autoElement.getAttribute("form-display"));
// default to none
param.allowHtml = UtilXml.checkEmpty(autoElement.getAttribute("allow-html"), "none").intern();
modelParamMap.put(field.getName(), param);
}
}
// get the excludes list; and remove those from the map
List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
if (excludes != null) {
for (Element exclude : excludes) {
modelParamMap.remove(UtilXml.checkEmpty(exclude.getAttribute("field-name")));
}
}
// now add in all the remaining params
for (ModelParam thisParam : modelParamMap.values()) {
service.addParam(thisParam);
}
} catch (GenericEntityException e) {
Debug.logError(e, "Problem loading auto-attributes [" + entityName + "] for " + service.name, module);
} catch (GeneralException e) {
Debug.logError(e, "Cannot load auto-attributes : " + e.getMessage() + " for " + service.name, module);
}
}
}
use of org.apache.ofbiz.entity.model.ModelFieldType in project ofbiz-framework by apache.
the class WebToolsServices method getEntityRefData.
/**
* Get entity reference data. Returns the number of entities in
* <code>numberOfEntities</code> and a List of Maps -
* <code>packagesList</code>.
* Each Map contains:<br>
* <ul><li><code>packageName</code> - the entity package name</li>
* <li><code>entitiesList</code> - a list of Maps:
* <ul>
* <li><code>entityName</code></li>
* <li><code>helperName</code></li>
* <li><code>groupName</code></li>
* <li><code>plainTableName</code></li>
* <li><code>title</code></li>
* <li><code>description</code></li>
* <!-- <li><code>location</code></li> -->
* <li><code>javaNameList</code> - list of Maps:
* <ul>
* <li><code>isPk</code></li>
* <li><code>name</code></li>
* <li><code>colName</code></li>
* <li><code>description</code></li>
* <li><code>type</code></li>
* <li><code>javaType</code></li>
* <li><code>sqlType</code></li>
* </ul>
* </li>
* <li><code>relationsList</code> - list of Maps:
* <ul>
* <li><code>title</code></li>
* <!-- <li><code>description</code></li> -->
* <li><code>relEntity</code></li>
* <li><code>fkName</code></li>
* <li><code>type</code></li>
* <li><code>length</code></li>
* <li><code>keysList</code> - list of Maps:
* <ul>
* <li><code>row</code></li>
* <li><code>fieldName</code></li>
* <li><code>relFieldName</code></li>
* </ul>
* </li>
* </ul>
* </li>
* <li><code>indexList</code> - list of Maps:
* <ul>
* <li><code>name</code></li>
* <!-- <li><code>description</code></li> -->
* <li><code>fieldNameList</code> - list of Strings</li>
* </ul>
* </li>
* </ul>
* </li></ul>
*/
public static Map<String, Object> getEntityRefData(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Map<String, Object> resultMap = ServiceUtil.returnSuccess();
ModelReader reader = delegator.getModelReader();
Map<String, TreeSet<String>> entitiesByPackage = new HashMap<String, TreeSet<String>>();
Set<String> packageNames = new TreeSet<String>();
Set<String> tableNames = new TreeSet<String>();
// put the entityNames TreeSets in a HashMap by packageName
try {
Collection<String> ec = reader.getEntityNames();
resultMap.put("numberOfEntities", ec.size());
for (String eName : ec) {
ModelEntity ent = reader.getModelEntity(eName);
// make sure the table name is in the list of all table names, if not null
if (UtilValidate.isNotEmpty(ent.getPlainTableName())) {
tableNames.add(ent.getPlainTableName());
}
TreeSet<String> entities = entitiesByPackage.get(ent.getPackageName());
if (entities == null) {
entities = new TreeSet<String>();
entitiesByPackage.put(ent.getPackageName(), entities);
packageNames.add(ent.getPackageName());
}
entities.add(eName);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "EntityImportErrorRetrievingEntityNames", locale) + e.getMessage());
}
String search = (String) context.get("search");
List<Map<String, Object>> packagesList = new LinkedList<Map<String, Object>>();
try {
for (String pName : packageNames) {
Map<String, Object> packageMap = new HashMap<String, Object>();
TreeSet<String> entities = entitiesByPackage.get(pName);
List<Map<String, Object>> entitiesList = new LinkedList<Map<String, Object>>();
for (String entityName : entities) {
Map<String, Object> entityMap = new HashMap<String, Object>();
String helperName = delegator.getEntityHelperName(entityName);
String groupName = delegator.getEntityGroupName(entityName);
if (search == null || entityName.toLowerCase().indexOf(search.toLowerCase()) != -1) {
ModelEntity entity = reader.getModelEntity(entityName);
ResourceBundle bundle = null;
if (UtilValidate.isNotEmpty(entity.getDefaultResourceName())) {
try {
bundle = UtilResourceBundle.getBundle(entity.getDefaultResourceName(), locale, loader);
} catch (Exception exception) {
Debug.logInfo(exception.getMessage(), module);
}
}
String entityDescription = null;
if (bundle != null) {
try {
entityDescription = bundle.getString("EntityDescription." + entity.getEntityName());
} catch (Exception exception) {
}
}
if (UtilValidate.isEmpty(entityDescription)) {
entityDescription = entity.getDescription();
}
// fields list
List<Map<String, Object>> javaNameList = new LinkedList<Map<String, Object>>();
for (Iterator<ModelField> f = entity.getFieldsIterator(); f.hasNext(); ) {
Map<String, Object> javaNameMap = new HashMap<String, Object>();
ModelField field = f.next();
ModelFieldType type = delegator.getEntityFieldType(entity, field.getType());
javaNameMap.put("isPk", field.getIsPk());
javaNameMap.put("name", field.getName());
javaNameMap.put("colName", field.getColName());
String fieldDescription = null;
if (bundle != null) {
try {
fieldDescription = bundle.getString("FieldDescription." + entity.getEntityName() + "." + field.getName());
} catch (Exception exception) {
}
}
if (UtilValidate.isEmpty(fieldDescription)) {
fieldDescription = field.getDescription();
}
if (UtilValidate.isEmpty(fieldDescription) && bundle != null) {
try {
fieldDescription = bundle.getString("FieldDescription." + field.getName());
} catch (Exception exception) {
}
}
if (UtilValidate.isEmpty(fieldDescription)) {
fieldDescription = ModelUtil.javaNameToDbName(field.getName()).toLowerCase();
fieldDescription = ModelUtil.upperFirstChar(fieldDescription.replace('_', ' '));
}
javaNameMap.put("description", fieldDescription);
javaNameMap.put("type", (field.getType()) != null ? field.getType() : null);
javaNameMap.put("javaType", (field.getType() != null && type != null) ? type.getJavaType() : "Undefined");
javaNameMap.put("sqlType", (type != null && type.getSqlType() != null) ? type.getSqlType() : "Undefined");
javaNameMap.put("encrypted", field.getEncryptMethod().isEncrypted());
javaNameMap.put("encryptMethod", field.getEncryptMethod());
javaNameList.add(javaNameMap);
}
// relations list
List<Map<String, Object>> relationsList = new LinkedList<Map<String, Object>>();
for (int r = 0; r < entity.getRelationsSize(); r++) {
Map<String, Object> relationMap = new HashMap<String, Object>();
ModelRelation relation = entity.getRelation(r);
List<Map<String, Object>> keysList = new LinkedList<Map<String, Object>>();
int row = 1;
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
Map<String, Object> keysMap = new HashMap<String, Object>();
String fieldName = null;
String relFieldName = null;
if (keyMap.getFieldName().equals(keyMap.getRelFieldName())) {
fieldName = keyMap.getFieldName();
relFieldName = "aa";
} else {
fieldName = keyMap.getFieldName();
relFieldName = keyMap.getRelFieldName();
}
keysMap.put("row", row++);
keysMap.put("fieldName", fieldName);
keysMap.put("relFieldName", relFieldName);
keysList.add(keysMap);
}
relationMap.put("title", relation.getTitle());
relationMap.put("description", relation.getDescription());
relationMap.put("relEntity", relation.getRelEntityName());
relationMap.put("fkName", relation.getFkName());
relationMap.put("type", relation.getType());
relationMap.put("length", relation.getType().length());
relationMap.put("keysList", keysList);
relationsList.add(relationMap);
}
// index list
List<Map<String, Object>> indexList = new LinkedList<Map<String, Object>>();
for (int r = 0; r < entity.getIndexesSize(); r++) {
List<String> fieldNameList = new LinkedList<String>();
ModelIndex index = entity.getIndex(r);
for (Iterator<ModelIndex.Field> fieldIterator = index.getFields().iterator(); fieldIterator.hasNext(); ) {
fieldNameList.add(fieldIterator.next().getFieldName());
}
Map<String, Object> indexMap = new HashMap<String, Object>();
indexMap.put("name", index.getName());
indexMap.put("description", index.getDescription());
indexMap.put("fieldNameList", fieldNameList);
indexList.add(indexMap);
}
entityMap.put("entityName", entityName);
entityMap.put("helperName", helperName);
entityMap.put("groupName", groupName);
entityMap.put("plainTableName", entity.getPlainTableName());
entityMap.put("title", entity.getTitle());
entityMap.put("description", entityDescription);
String entityLocation = entity.getLocation();
entityLocation = entityLocation.replaceFirst(System.getProperty("ofbiz.home") + "/", "");
entityMap.put("location", entityLocation);
entityMap.put("javaNameList", javaNameList);
entityMap.put("relationsList", relationsList);
entityMap.put("indexList", indexList);
entitiesList.add(entityMap);
}
}
packageMap.put("packageName", pName);
packageMap.put("entitiesList", entitiesList);
packagesList.add(packageMap);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "EntityImportErrorRetrievingEntityNames", locale) + e.getMessage());
}
resultMap.put("packagesList", packagesList);
return resultMap;
}
use of org.apache.ofbiz.entity.model.ModelFieldType in project ofbiz-framework by apache.
the class DatabaseUtil method addColumn.
public String addColumn(ModelEntity entity, ModelField field) {
if (entity == null || field == null)
return "ModelEntity or ModelField where null, cannot add column";
if (entity instanceof ModelViewEntity) {
return "ERROR: Cannot add column for a view entity";
}
ModelFieldType type = modelFieldTypeReader.getModelFieldType(field.getType());
if (type == null) {
return "Field type [" + type + "] not found for field [" + field.getName() + "] of entity [" + entity.getEntityName() + "], not adding column.";
}
StringBuilder sqlBuf = new StringBuilder("ALTER TABLE ");
sqlBuf.append(entity.getTableName(datasourceInfo));
sqlBuf.append(" ADD ");
sqlBuf.append(field.getColName());
sqlBuf.append(" ");
sqlBuf.append(type.getSqlType());
if ("String".equals(type.getJavaType()) || "java.lang.String".equals(type.getJavaType())) {
// if there is a characterSet, add the CHARACTER SET arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCharacterSet())) {
sqlBuf.append(" CHARACTER SET ");
sqlBuf.append(this.datasourceInfo.getCharacterSet());
}
// if there is a collate, add the COLLATE arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCollate())) {
sqlBuf.append(" COLLATE ");
sqlBuf.append(this.datasourceInfo.getCollate());
}
}
String sql = sqlBuf.toString();
if (Debug.infoOn())
Debug.logInfo("[addColumn] sql=" + sql, module);
try (Connection connection = getConnection();
Statement stmt = connection.createStatement()) {
stmt.executeUpdate(sql);
} catch (SQLException e) {
// if that failed try the alternate syntax real quick
StringBuilder sql2Buf = new StringBuilder("ALTER TABLE ");
sql2Buf.append(entity.getTableName(datasourceInfo));
sql2Buf.append(" ADD COLUMN ");
sql2Buf.append(field.getColName());
sql2Buf.append(" ");
sql2Buf.append(type.getSqlType());
if ("String".equals(type.getJavaType()) || "java.lang.String".equals(type.getJavaType())) {
// if there is a characterSet, add the CHARACTER SET arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCharacterSet())) {
sql2Buf.append(" CHARACTER SET ");
sql2Buf.append(this.datasourceInfo.getCharacterSet());
}
// if there is a collate, add the COLLATE arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCollate())) {
sql2Buf.append(" COLLATE ");
sql2Buf.append(this.datasourceInfo.getCollate());
}
}
String sql2 = sql2Buf.toString();
if (Debug.infoOn())
Debug.logInfo("[addColumn] sql failed, trying sql2=" + sql2, module);
try (Connection connection = getConnection();
Statement stmt = connection.createStatement()) {
stmt.executeUpdate(sql2);
} catch (SQLException e2) {
// if this also fails report original error, not this error...
return "SQL Exception while executing the following:\n" + sql + "\nError was: " + e2.toString();
} catch (GenericEntityException e2) {
String errMsg = "Unable to establish a connection with the database for helperName [" + this.helperInfo.getHelperFullName() + "]... Error was: " + e2.toString();
Debug.logError(e2, errMsg, module);
return errMsg;
}
} catch (GenericEntityException e) {
String errMsg = "Unable to establish a connection with the database for helperName [" + this.helperInfo.getHelperFullName() + "]... Error was: " + e.toString();
Debug.logError(e, errMsg, module);
return errMsg;
}
return null;
}
use of org.apache.ofbiz.entity.model.ModelFieldType in project ofbiz-framework by apache.
the class DatabaseUtil method checkDb.
public void checkDb(Map<String, ModelEntity> modelEntities, List<String> colWrongSize, List<String> messages, boolean checkPks, boolean checkFks, boolean checkFkIdx, boolean addMissing) {
if (isLegacy) {
throw new RuntimeException("Cannot run checkDb on a legacy database connection; configure a database helper (entityengine.xml)");
}
ExecutorService executor = Executors.newFixedThreadPool(datasourceInfo.getMaxWorkerPoolSize());
UtilTimer timer = new UtilTimer();
timer.timerString("Start - Before Get Database Meta Data");
// get ALL tables from this database
TreeSet<String> tableNames = this.getTableNames(messages);
TreeSet<String> fkTableNames = tableNames == null ? null : new TreeSet<String>(tableNames);
TreeSet<String> indexTableNames = tableNames == null ? null : new TreeSet<String>(tableNames);
if (tableNames == null) {
String message = "Could not get table name information from the database, aborting.";
if (messages != null)
messages.add(message);
Debug.logError(message, module);
return;
}
timer.timerString("After Get All Table Names");
// get ALL column info, put into hashmap by table name
Map<String, Map<String, ColumnCheckInfo>> colInfo = getColumnInfo(tableNames, checkPks, messages, executor);
if (colInfo == null) {
String message = "Could not get column information from the database, aborting.";
if (messages != null)
messages.add(message);
Debug.logError(message, module);
return;
}
timer.timerString("After Get All Column Info");
// -make sure all entities have a corresponding table
// -list all tables that do not have a corresponding entity
// -display message if number of table columns does not match number of entity fields
// -list all columns that do not have a corresponding field
// -make sure each corresponding column is of the correct type
// -list all fields that do not have a corresponding column
timer.timerString("Before Individual Table/Column Check");
List<ModelEntity> modelEntityList = new ArrayList<ModelEntity>(modelEntities.values());
// sort using compareTo method on ModelEntity
Collections.sort(modelEntityList);
int curEnt = 0;
int totalEnt = modelEntityList.size();
List<ModelEntity> entitiesAdded = new LinkedList<ModelEntity>();
String schemaName;
try {
schemaName = getSchemaName(messages);
} catch (SQLException e) {
String message = "Could not get schema name the database, aborting.";
if (messages != null)
messages.add(message);
Debug.logError(message, module);
return;
}
List<Future<CreateTableCallable>> tableFutures = new LinkedList<Future<CreateTableCallable>>();
for (ModelEntity entity : modelEntityList) {
curEnt++;
// if this is a view entity, do not check it...
if (entity instanceof ModelViewEntity) {
String entMessage = "(" + timer.timeSinceLast() + "ms) NOT Checking #" + curEnt + "/" + totalEnt + " View Entity " + entity.getEntityName();
Debug.logVerbose(entMessage, module);
if (messages != null)
messages.add(entMessage);
continue;
// if never-check is set then don't check it either
} else if (entity.getNeverCheck()) {
String entMessage = "(" + timer.timeSinceLast() + "ms) NOT Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getEntityName();
Debug.logVerbose(entMessage, module);
if (messages != null)
messages.add(entMessage);
continue;
}
String plainTableName = entity.getPlainTableName();
String tableName;
if (UtilValidate.isNotEmpty(schemaName)) {
tableName = schemaName + "." + plainTableName;
} else {
tableName = plainTableName;
}
String entMessage = "(" + timer.timeSinceLast() + "ms) Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getEntityName() + " with table " + tableName;
Debug.logVerbose(entMessage, module);
if (messages != null)
messages.add(entMessage);
// -make sure all entities have a corresponding table
if (tableNames.contains(tableName)) {
tableNames.remove(tableName);
if (colInfo != null) {
Map<String, ModelField> fieldColNames = new HashMap<String, ModelField>();
Iterator<ModelField> fieldIter = entity.getFieldsIterator();
while (fieldIter.hasNext()) {
ModelField field = fieldIter.next();
fieldColNames.put(field.getColName(), field);
}
Map<String, ColumnCheckInfo> colMap = colInfo.get(tableName);
if (colMap != null) {
for (ColumnCheckInfo ccInfo : colMap.values()) {
// -list all columns that do not have a corresponding field
if (fieldColNames.containsKey(ccInfo.columnName)) {
ModelField field = null;
field = fieldColNames.remove(ccInfo.columnName);
ModelFieldType modelFieldType = modelFieldTypeReader.getModelFieldType(field.getType());
if (modelFieldType != null) {
// make sure each corresponding column is of the correct type
String fullTypeStr = modelFieldType.getSqlType();
String typeName;
int columnSize = -1;
int decimalDigits = -1;
int openParen = fullTypeStr.indexOf('(');
int closeParen = fullTypeStr.indexOf(')');
int comma = fullTypeStr.indexOf(',');
if (openParen > 0 && closeParen > 0 && closeParen > openParen) {
typeName = fullTypeStr.substring(0, openParen);
if (!("DATETIME".equals(typeName) || "TIME".equals(typeName))) {
// for DATETIME and TIME fields the number within the parenthesis doesn't represent the column size
if (comma > 0 && comma > openParen && comma < closeParen) {
String csStr = fullTypeStr.substring(openParen + 1, comma);
try {
columnSize = Integer.parseInt(csStr);
} catch (NumberFormatException e) {
Debug.logError(e, module);
}
String ddStr = fullTypeStr.substring(comma + 1, closeParen);
try {
decimalDigits = Integer.parseInt(ddStr);
} catch (NumberFormatException e) {
Debug.logError(e, module);
}
} else if (openParen + 1 < closeParen) {
String csStr = fullTypeStr.substring(openParen + 1, closeParen);
try {
columnSize = Integer.parseInt(csStr);
} catch (NumberFormatException e) {
Debug.logError(e, module);
}
}
}
} else {
typeName = fullTypeStr;
}
// override the default typeName with the sqlTypeAlias if it is specified
if (UtilValidate.isNotEmpty(modelFieldType.getSqlTypeAlias())) {
typeName = modelFieldType.getSqlTypeAlias();
}
// NOTE: this may need a toUpperCase in some cases, keep an eye on it, okay just compare with ignore case
if (!ccInfo.typeName.equalsIgnoreCase(typeName)) {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] is of type [" + ccInfo.typeName + "] in the database, but is defined as type [" + typeName + "] in the entity definition.";
Debug.logError(message, module);
if (messages != null)
messages.add(message);
}
if (columnSize != -1 && ccInfo.columnSize != -1 && columnSize != ccInfo.columnSize && (columnSize * 3) != ccInfo.columnSize) {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a column size of [" + ccInfo.columnSize + "] in the database, but is defined to have a column size of [" + columnSize + "] in the entity definition.";
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
if (columnSize > ccInfo.columnSize && colWrongSize != null) {
// add item to list of wrong sized columns; only if the entity is larger
colWrongSize.add(entity.getEntityName() + "." + field.getName());
}
}
if (decimalDigits != -1 && decimalDigits != ccInfo.decimalDigits) {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a decimalDigits of [" + ccInfo.decimalDigits + "] in the database, but is defined to have a decimalDigits of [" + decimalDigits + "] in the entity definition.";
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
}
// do primary key matching check
if (checkPks && ccInfo.isPk && !field.getIsPk()) {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] IS a primary key in the database, but IS NOT a primary key in the entity definition. The primary key for this table needs to be re-created or modified so that this column is NOT part of the primary key.";
Debug.logError(message, module);
if (messages != null)
messages.add(message);
}
if (checkPks && !ccInfo.isPk && field.getIsPk()) {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] IS NOT a primary key in the database, but IS a primary key in the entity definition. The primary key for this table needs to be re-created or modified to add this column to the primary key. Note that data may need to be added first as a primary key column cannot have an null values.";
Debug.logError(message, module);
if (messages != null)
messages.add(message);
}
} else {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a field type name of [" + field.getType() + "] which is not found in the field type definitions";
Debug.logError(message, module);
if (messages != null)
messages.add(message);
}
} else {
String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] exists in the database but has no corresponding field" + ((checkPks && ccInfo.isPk) ? " (and it is a PRIMARY KEY COLUMN)" : "");
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
}
}
// -display message if number of table columns does not match number of entity fields
if (colMap.size() != entity.getFieldsSize()) {
String message = "Entity [" + entity.getEntityName() + "] has " + entity.getFieldsSize() + " fields but table [" + tableName + "] has " + colMap.size() + " columns.";
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
}
}
// -list all fields that do not have a corresponding column
for (ModelField field : fieldColNames.values()) {
String message = "Field [" + field.getName() + "] of entity [" + entity.getEntityName() + "] is missing its corresponding column [" + field.getColName() + "]" + (field.getIsPk() ? " (and it is a PRIMARY KEY FIELD)" : "");
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
if (addMissing) {
// add the column
String errMsg = addColumn(entity, field);
if (UtilValidate.isNotEmpty(errMsg)) {
message = "Could not add column [" + field.getColName() + "] to table [" + tableName + "]: " + errMsg;
Debug.logError(message, module);
if (messages != null)
messages.add(message);
} else {
message = "Added column [" + field.getColName() + "] to table [" + tableName + "]" + (field.getIsPk() ? " (NOTE: this is a PRIMARY KEY FIELD, but the primary key was not updated automatically (not considered a safe operation), be sure to fill in any needed data and re-create the primary key)" : "");
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
}
}
}
} else {
String message = "Entity [" + entity.getEntityName() + "] has no table in the database";
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
if (addMissing) {
// create the table
tableFutures.add(executor.submit(new CreateTableCallable(entity, modelEntities, tableName)));
}
}
}
for (CreateTableCallable tableCallable : ExecutionPool.getAllFutures(tableFutures)) {
tableCallable.updateData(messages, entitiesAdded);
}
timer.timerString("After Individual Table/Column Check");
// -list all tables that do not have a corresponding entity
for (String tableName : tableNames) {
String message = "Table named [" + tableName + "] exists in the database but has no corresponding entity";
Debug.logWarning(message, module);
if (messages != null)
messages.add(message);
}
// for each newly added table, add fk indices
if (datasourceInfo.getUseForeignKeyIndices()) {
int totalFkIndices = 0;
List<Future<AbstractCountingCallable>> fkIndicesFutures = new LinkedList<Future<AbstractCountingCallable>>();
for (ModelEntity curEntity : entitiesAdded) {
if (curEntity.getRelationsOneSize() > 0) {
fkIndicesFutures.add(executor.submit(new AbstractCountingCallable(curEntity, modelEntities) {
public AbstractCountingCallable call() throws Exception {
count = createForeignKeyIndices(entity, datasourceInfo.getConstraintNameClipLength(), messages);
return this;
}
}));
}
}
for (AbstractCountingCallable fkIndicesCallable : ExecutionPool.getAllFutures(fkIndicesFutures)) {
totalFkIndices += fkIndicesCallable.updateData(messages);
}
if (totalFkIndices > 0)
Debug.logImportant("==== TOTAL Foreign Key Indices Created: " + totalFkIndices, module);
}
// for each newly added table, add fks
if (datasourceInfo.getUseForeignKeys()) {
int totalFks = 0;
for (ModelEntity curEntity : entitiesAdded) {
totalFks += this.createForeignKeys(curEntity, modelEntities, datasourceInfo.getConstraintNameClipLength(), datasourceInfo.getFkStyle(), datasourceInfo.getUseFkInitiallyDeferred(), messages);
}
if (totalFks > 0)
Debug.logImportant("==== TOTAL Foreign Keys Created: " + totalFks, module);
}
// for each newly added table, add declared indexes
if (datasourceInfo.getUseIndices()) {
int totalDis = 0;
List<Future<AbstractCountingCallable>> disFutures = new LinkedList<Future<AbstractCountingCallable>>();
for (ModelEntity curEntity : entitiesAdded) {
if (curEntity.getIndexesSize() > 0) {
disFutures.add(executor.submit(new AbstractCountingCallable(curEntity, modelEntities) {
public AbstractCountingCallable call() throws Exception {
count = createDeclaredIndices(entity, messages);
return this;
}
}));
}
}
for (AbstractCountingCallable disCallable : ExecutionPool.getAllFutures(disFutures)) {
totalDis += disCallable.updateData(messages);
}
if (totalDis > 0)
Debug.logImportant("==== TOTAL Declared Indices Created: " + totalDis, module);
}
// make sure each one-relation has an FK
if (checkFks) {
// if (!justColumns && datasourceInfo.getUseForeignKeys() && datasourceInfo.checkForeignKeysOnStart) {
// NOTE: This ISN'T working for Postgres or MySQL, who knows about others, may be from JDBC driver bugs...
int numFksCreated = 0;
// TODO: check each key-map to make sure it exists in the FK, if any differences warn and then remove FK and recreate it
// get ALL column info, put into hashmap by table name
Map<String, Map<String, ReferenceCheckInfo>> refTableInfoMap = this.getReferenceInfo(fkTableNames, messages);
if (refTableInfoMap == null) {
// uh oh, something happened while getting info...
if (Debug.verboseOn())
Debug.logVerbose("Ref Table Info Map is null", module);
} else {
for (ModelEntity entity : modelEntityList) {
String entityName = entity.getEntityName();
// if this is a view entity, do not check it...
if (entity instanceof ModelViewEntity) {
String entMessage = "NOT Checking View Entity " + entity.getEntityName();
Debug.logVerbose(entMessage, module);
if (messages != null) {
messages.add(entMessage);
}
continue;
}
// get existing FK map for this table
Map<String, ReferenceCheckInfo> rcInfoMap = refTableInfoMap.get(entity.getTableName(datasourceInfo));
// Debug.logVerbose("Got ref info for table " + entity.getTableName(datasourceInfo) + ": " + rcInfoMap, module);
// go through each relation to see if an FK already exists
Iterator<ModelRelation> relations = entity.getRelationsIterator();
boolean createdConstraints = false;
while (relations.hasNext()) {
ModelRelation modelRelation = relations.next();
if (!"one".equals(modelRelation.getType())) {
continue;
}
ModelEntity relModelEntity = modelEntities.get(modelRelation.getRelEntityName());
if (relModelEntity == null) {
Debug.logError("No such relation: " + entity.getEntityName() + " -> " + modelRelation.getRelEntityName(), module);
continue;
}
String relConstraintName = makeFkConstraintName(modelRelation, datasourceInfo.getConstraintNameClipLength());
ReferenceCheckInfo rcInfo = null;
if (rcInfoMap != null) {
rcInfo = rcInfoMap.get(relConstraintName);
}
if (rcInfo != null) {
rcInfoMap.remove(relConstraintName);
} else {
// if not, create one
String noFkMessage = "No Foreign Key Constraint [" + relConstraintName + "] found for entity [" + entityName + "]";
if (messages != null)
messages.add(noFkMessage);
if (Debug.infoOn())
Debug.logInfo(noFkMessage, module);
if (addMissing) {
String errMsg = createForeignKey(entity, modelRelation, relModelEntity, datasourceInfo.getConstraintNameClipLength(), datasourceInfo.getFkStyle(), datasourceInfo.getUseFkInitiallyDeferred());
if (UtilValidate.isNotEmpty(errMsg)) {
String message = "Could not create foreign key " + relConstraintName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
Debug.logError(message, module);
if (messages != null)
messages.add(message);
} else {
String message = "Created foreign key " + relConstraintName + " for entity [" + entity.getEntityName() + "]";
Debug.logVerbose(message, module);
if (messages != null)
messages.add(message);
createdConstraints = true;
numFksCreated++;
}
}
}
}
if (createdConstraints) {
String message = "Created foreign key(s) for entity [" + entity.getEntityName() + "]";
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
// show foreign key references that exist but are unknown
if (rcInfoMap != null) {
for (String rcKeyLeft : rcInfoMap.keySet()) {
String message = "Unknown Foreign Key Constraint " + rcKeyLeft + " found in table " + entity.getTableName(datasourceInfo);
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
}
}
}
if (Debug.infoOn())
Debug.logInfo("Created " + numFksCreated + " fk refs", module);
}
// make sure each one-relation has an index
if (checkFkIdx || datasourceInfo.getCheckIndicesOnStart()) {
// if (!justColumns && datasourceInfo.getUseForeignKeyIndices() && datasourceInfo.checkFkIndicesOnStart) {
int numIndicesCreated = 0;
// TODO: check each key-map to make sure it exists in the index, if any differences warn and then remove the index and recreate it
// get ALL column info, put into hashmap by table name
boolean[] needsUpperCase = new boolean[1];
Map<String, Set<String>> tableIndexListMap = this.getIndexInfo(indexTableNames, messages, needsUpperCase);
if (tableIndexListMap == null) {
// uh oh, something happened while getting info...
if (Debug.verboseOn())
Debug.logVerbose("Ref Table Info Map is null", module);
} else {
for (ModelEntity entity : modelEntityList) {
String entityName = entity.getEntityName();
// if this is a view entity, do not check it...
if (entity instanceof ModelViewEntity) {
String entMessage = "NOT Checking View Entity " + entity.getEntityName();
Debug.logVerbose(entMessage, module);
if (messages != null)
messages.add(entMessage);
continue;
}
// get existing index list for this table
Set<String> tableIndexList = tableIndexListMap.get(entity.getTableName(datasourceInfo));
if (tableIndexList == null) {
// evidently no indexes in the database for this table, do the create all
if (checkFkIdx) {
this.createForeignKeyIndices(entity, datasourceInfo.getConstraintNameClipLength(), messages);
}
if (datasourceInfo.getCheckIndicesOnStart()) {
this.createDeclaredIndices(entity, messages);
}
continue;
}
// go through each relation to see if an FK already exists
boolean createdConstraints = false;
Iterator<ModelRelation> relations = entity.getRelationsIterator();
while (relations.hasNext()) {
ModelRelation modelRelation = relations.next();
if (!"one".equals(modelRelation.getType())) {
continue;
}
String relConstraintName = makeFkConstraintName(modelRelation, datasourceInfo.getConstraintNameClipLength());
if (tableIndexList.contains(relConstraintName)) {
tableIndexList.remove(relConstraintName);
} else {
if (checkFkIdx) {
// if not, create one
String noIdxMessage = "No Index [" + relConstraintName + "] found for entity [" + entityName + "]";
if (messages != null)
messages.add(noIdxMessage);
if (Debug.infoOn())
Debug.logInfo(noIdxMessage, module);
if (addMissing) {
String errMsg = createForeignKeyIndex(entity, modelRelation, datasourceInfo.getConstraintNameClipLength());
if (UtilValidate.isNotEmpty(errMsg)) {
String message = "Could not create foreign key index " + relConstraintName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
Debug.logError(message, module);
if (messages != null)
messages.add(message);
} else {
String message = "Created foreign key index " + relConstraintName + " for entity [" + entity.getEntityName() + "]";
Debug.logVerbose(message, module);
if (messages != null)
messages.add(message);
createdConstraints = true;
numIndicesCreated++;
}
}
}
}
}
if (createdConstraints) {
String message = "Created foreign key index/indices for entity [" + entity.getEntityName() + "]";
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
// go through each indice to see if an indice already exists
boolean createdIndexes = false;
Iterator<ModelIndex> indexes = entity.getIndexesIterator();
while (indexes.hasNext()) {
ModelIndex modelIndex = indexes.next();
String relIndexName = makeIndexName(modelIndex, datasourceInfo.getConstraintNameClipLength());
String checkIndexName = needsUpperCase[0] ? relIndexName.toUpperCase() : relIndexName;
if (tableIndexList.contains(checkIndexName)) {
tableIndexList.remove(checkIndexName);
} else {
if (datasourceInfo.getCheckIndicesOnStart()) {
// if not, create one
String noIdxMessage = "No Index [" + relIndexName + "] found for entity [" + entityName + "]";
if (messages != null)
messages.add(noIdxMessage);
if (Debug.infoOn())
Debug.logInfo(noIdxMessage, module);
if (addMissing) {
String errMsg = createDeclaredIndex(entity, modelIndex);
if (UtilValidate.isNotEmpty(errMsg)) {
String message = "Could not create index " + relIndexName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
Debug.logError(message, module);
if (messages != null)
messages.add(message);
} else {
String message = "Created index " + relIndexName + " for entity [" + entity.getEntityName() + "]";
Debug.logVerbose(message, module);
if (messages != null)
messages.add(message);
createdIndexes = true;
numIndicesCreated++;
}
}
}
}
}
if (createdIndexes) {
String message = "Created declared index/indices for entity [" + entity.getEntityName() + "]";
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
// show index key references that exist but are unknown
if (tableIndexList != null) {
for (String indexLeft : tableIndexList) {
String message = "Unknown Index " + indexLeft + " found in table " + entity.getTableName(datasourceInfo);
Debug.logImportant(message, module);
if (messages != null)
messages.add(message);
}
}
}
}
if (numIndicesCreated > 0 && Debug.infoOn())
Debug.logInfo("Created " + numIndicesCreated + " indices", module);
}
executor.shutdown();
timer.timerString("Finished Checking Entity Database");
}
Aggregations