Search in sources :

Example 16 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class FindServices method createCondition.

/**
 * createCondition, comparing the normalizedFields with the list of keys, .
 *
 * This is use to the generic method that expects entity data affixed with special suffixes
 * to indicate their purpose in formulating an SQL query statement.
 * @param modelEntity the model entity object
 * @param normalizedFields list of field the user have populated
 * @return a arrayList usable to create an entityCondition
 */
public static List<EntityCondition> createCondition(ModelEntity modelEntity, Map<String, Map<String, Map<String, Object>>> normalizedFields, Map<String, Object> queryStringMap, Map<String, List<Object[]>> origValueMap, Delegator delegator, Map<String, ?> context) {
    Map<String, Map<String, Object>> subMap = null;
    Map<String, Object> subMap2 = null;
    // If it is a "value" field, it will be the value to be used in the query.
    Object fieldValue = null;
    // If it is an "op" field, it will be "equals", "greaterThan", etc.
    EntityCondition cond = null;
    List<EntityCondition> tmpList = new LinkedList<>();
    String opString = null;
    boolean ignoreCase = false;
    List<ModelField> fields = modelEntity.getFieldsUnmodifiable();
    for (ModelField modelField : fields) {
        String fieldName = modelField.getName();
        subMap = normalizedFields.get(fieldName);
        if (subMap == null) {
            continue;
        }
        subMap2 = subMap.get("fld0");
        fieldValue = subMap2.get("value");
        opString = (String) subMap2.get("op");
        // null fieldValue is OK if operator is "empty"
        if (fieldValue == null && !"empty".equals(opString)) {
            continue;
        }
        ignoreCase = "Y".equals(subMap2.get("ic"));
        cond = createSingleCondition(modelField, opString, fieldValue, ignoreCase, delegator, context);
        tmpList.add(cond);
        subMap2 = subMap.get("fld1");
        if (subMap2 == null) {
            continue;
        }
        fieldValue = subMap2.get("value");
        opString = (String) subMap2.get("op");
        if (fieldValue == null && !"empty".equals(opString)) {
            continue;
        }
        ignoreCase = "Y".equals(subMap2.get("ic"));
        cond = createSingleCondition(modelField, opString, fieldValue, ignoreCase, delegator, context);
        tmpList.add(cond);
        // add to queryStringMap
        List<Object[]> origList = origValueMap.get(fieldName);
        if (UtilValidate.isNotEmpty(origList)) {
            for (Object[] arr : origList) {
                queryStringMap.put((String) arr[0], arr[1]);
            }
        }
    }
    return tmpList;
}
Also used : EntityCondition(org.apache.ofbiz.entity.condition.EntityCondition) LinkedList(java.util.LinkedList) ModelField(org.apache.ofbiz.entity.model.ModelField) UtilGenerics.checkMap(org.apache.ofbiz.base.util.UtilGenerics.checkMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 17 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class DatabaseUtil method makeFkIndexClause.

public String makeFkIndexClause(ModelEntity entity, ModelRelation modelRelation, int constraintNameClipLength) {
    StringBuilder mainCols = new StringBuilder();
    for (ModelKeyMap keyMap : modelRelation.getKeyMaps()) {
        ModelField mainField = entity.getField(keyMap.getFieldName());
        if (mainField == null) {
            Debug.logError("Bad key-map in entity [" + entity.getEntityName() + "] relation to [" + modelRelation.getTitle() + modelRelation.getRelEntityName() + "] for field [" + keyMap.getFieldName() + "]", module);
            return null;
        }
        if (mainCols.length() > 0) {
            mainCols.append(", ");
        }
        mainCols.append(mainField.getColName());
    }
    StringBuilder indexSqlBuf = new StringBuilder("CREATE INDEX ");
    String relConstraintName = makeFkConstraintName(modelRelation, constraintNameClipLength);
    indexSqlBuf.append(relConstraintName);
    indexSqlBuf.append(" ON ");
    indexSqlBuf.append(entity.getTableName(datasourceInfo));
    indexSqlBuf.append(" (");
    indexSqlBuf.append(mainCols.toString());
    indexSqlBuf.append(")");
    return indexSqlBuf.toString();
}
Also used : ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap) ModelField(org.apache.ofbiz.entity.model.ModelField)

Example 18 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class DatabaseUtil method repairColumnSizeChanges.

public void repairColumnSizeChanges(Map<String, ModelEntity> modelEntities, List<String> fieldsWrongSize, List<String> messages) {
    if (modelEntities == null || UtilValidate.isEmpty(fieldsWrongSize)) {
        messages.add("No fields to repair");
        return;
    }
    if (messages == null)
        messages = new ArrayList<String>();
    for (String fieldInfo : fieldsWrongSize) {
        String entityName = fieldInfo.substring(0, fieldInfo.indexOf('.'));
        String fieldName = fieldInfo.substring(fieldInfo.indexOf('.') + 1);
        ModelEntity modelEntity = modelEntities.get(entityName);
        ModelField modelField = modelEntity.getField(fieldName);
        repairColumnSize(modelEntity, modelField, messages);
    }
}
Also used : ModelField(org.apache.ofbiz.entity.model.ModelField) ArrayList(java.util.ArrayList) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 19 with ModelField

use of org.apache.ofbiz.entity.model.ModelField 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");
}
Also used : TreeSet(java.util.TreeSet) ResultSet(java.sql.ResultSet) Set(java.util.Set) SQLException(java.sql.SQLException) HashMap(java.util.HashMap) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) ArrayList(java.util.ArrayList) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation) ModelField(org.apache.ofbiz.entity.model.ModelField) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelIndex(org.apache.ofbiz.entity.model.ModelIndex) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity) LinkedList(java.util.LinkedList) ModelFieldType(org.apache.ofbiz.entity.model.ModelFieldType) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) HashMap(java.util.HashMap) Map(java.util.Map) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap)

Example 20 with ModelField

use of org.apache.ofbiz.entity.model.ModelField in project ofbiz-framework by apache.

the class DatabaseUtil method updateCharacterSetAndCollation.

/* ====================================================================== */
/* ====================================================================== */
public void updateCharacterSetAndCollation(ModelEntity entity, List<String> messages) {
    if (entity instanceof ModelViewEntity) {
        return;
    }
    if (UtilValidate.isEmpty(this.datasourceInfo.getCharacterSet()) && UtilValidate.isEmpty(this.datasourceInfo.getCollate())) {
        messages.add("Not setting character-set and collate for entity [" + entity.getEntityName() + "], options not specified in the datasource definition in the entityengine.xml file.");
        return;
    }
    try (Connection connection = getConnectionLogged(messages)) {
        if (connection == null) {
            return;
        }
        StringBuilder sqlTableBuf = new StringBuilder("ALTER TABLE ");
        sqlTableBuf.append(entity.getTableName(this.datasourceInfo));
        // if there is a characterSet, add the CHARACTER SET arg here
        if (UtilValidate.isNotEmpty(this.datasourceInfo.getCharacterSet())) {
            sqlTableBuf.append(" DEFAULT CHARACTER SET ");
            sqlTableBuf.append(this.datasourceInfo.getCharacterSet());
        }
        // if there is a collate, add the COLLATE arg here
        if (UtilValidate.isNotEmpty(this.datasourceInfo.getCollate())) {
            sqlTableBuf.append(" COLLATE ");
            sqlTableBuf.append(this.datasourceInfo.getCollate());
        }
        if (Debug.verboseOn())
            Debug.logVerbose("[updateCharacterSetAndCollation] character-set and collate sql=" + sqlTableBuf, module);
        try (Statement stmt = connection.createStatement()) {
            stmt.executeUpdate(sqlTableBuf.toString());
        } catch (SQLException e) {
            String errMsg = "SQL Exception while executing the following:\n" + sqlTableBuf + "\nError was: " + e.toString();
            messages.add(errMsg);
            Debug.logError(errMsg, module);
        }
        Iterator<ModelField> fieldIter = entity.getFieldsIterator();
        while (fieldIter.hasNext()) {
            ModelField field = fieldIter.next();
            ModelFieldType type = modelFieldTypeReader.getModelFieldType(field.getType());
            if (type == null) {
                messages.add("Field type [" + type + "] not found for field [" + field.getName() + "] of entity [" + entity.getEntityName() + "], not creating table.");
                continue;
            }
            if (!"String".equals(type.getJavaType()) && !"java.lang.String".equals(type.getJavaType())) {
                continue;
            }
            StringBuilder sqlBuf = new StringBuilder("ALTER TABLE ");
            sqlBuf.append(entity.getTableName(this.datasourceInfo));
            sqlBuf.append(" MODIFY COLUMN ");
            sqlBuf.append(field.getColName());
            sqlBuf.append(" ");
            sqlBuf.append(type.getSqlType());
            // 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());
            }
            if (field.getIsPk() || field.getIsNotNull()) {
                if (this.datasourceInfo.getAlwaysUseConstraintKeyword()) {
                    sqlBuf.append(" CONSTRAINT NOT NULL");
                } else {
                    sqlBuf.append(" NOT NULL");
                }
            }
            if (Debug.verboseOn())
                Debug.logVerbose("[updateCharacterSetAndCollation] character-set and collate sql=" + sqlBuf, module);
            try (Statement stmt = connection.createStatement()) {
                stmt.executeUpdate(sqlBuf.toString());
            } catch (SQLException e) {
                String errMsg = "SQL Exception while executing the following:\n" + sqlBuf + "\nError was: " + e.toString();
                messages.add(errMsg);
                Debug.logError(errMsg, module);
            }
        }
    } catch (SQLException e) {
        Debug.logError(e, module);
    }
}
Also used : ModelField(org.apache.ofbiz.entity.model.ModelField) SQLException(java.sql.SQLException) Statement(java.sql.Statement) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelFieldType(org.apache.ofbiz.entity.model.ModelFieldType) Connection(java.sql.Connection)

Aggregations

ModelField (org.apache.ofbiz.entity.model.ModelField)55 ModelEntity (org.apache.ofbiz.entity.model.ModelEntity)28 GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)16 LinkedList (java.util.LinkedList)14 ModelViewEntity (org.apache.ofbiz.entity.model.ModelViewEntity)13 HashMap (java.util.HashMap)10 GenericValue (org.apache.ofbiz.entity.GenericValue)10 ModelFieldType (org.apache.ofbiz.entity.model.ModelFieldType)10 ModelKeyMap (org.apache.ofbiz.entity.model.ModelKeyMap)10 Map (java.util.Map)8 SQLException (java.sql.SQLException)7 Locale (java.util.Locale)7 GenericModelException (org.apache.ofbiz.entity.GenericModelException)7 TreeSet (java.util.TreeSet)6 Delegator (org.apache.ofbiz.entity.Delegator)6 EntityCondition (org.apache.ofbiz.entity.condition.EntityCondition)6 GeneralException (org.apache.ofbiz.base.util.GeneralException)5 ModelParam (org.apache.ofbiz.service.ModelParam)5 SQLProcessor (org.apache.ofbiz.entity.jdbc.SQLProcessor)4 GenericServiceException (org.apache.ofbiz.service.GenericServiceException)4