Search in sources :

Example 6 with ModelRelation

use of org.apache.ofbiz.entity.model.ModelRelation 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;
}
Also used : Locale(java.util.Locale) HashMap(java.util.HashMap) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation) ModelField(org.apache.ofbiz.entity.model.ModelField) ModelReader(org.apache.ofbiz.entity.model.ModelReader) ModelField(org.apache.ofbiz.entity.model.ModelField) TreeSet(java.util.TreeSet) ModelIndex(org.apache.ofbiz.entity.model.ModelIndex) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity) LinkedList(java.util.LinkedList) GenericServiceException(org.apache.ofbiz.service.GenericServiceException) FileNotFoundException(java.io.FileNotFoundException) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) SAXException(org.xml.sax.SAXException) GeneralException(org.apache.ofbiz.base.util.GeneralException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) GenericTransactionException(org.apache.ofbiz.entity.transaction.GenericTransactionException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) ModelFieldType(org.apache.ofbiz.entity.model.ModelFieldType) ResourceBundle(java.util.ResourceBundle) UtilResourceBundle(org.apache.ofbiz.base.util.UtilProperties.UtilResourceBundle) Map(java.util.Map) HashMap(java.util.HashMap) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap)

Example 7 with ModelRelation

use of org.apache.ofbiz.entity.model.ModelRelation 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 8 with ModelRelation

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

the class DatabaseUtil method deleteForeignKeyIndices.

public String deleteForeignKeyIndices(ModelEntity entity, int constraintNameClipLength) {
    if (entity == null) {
        return "ModelEntity was null and is required to delete foreign keys indices for a table";
    }
    if (entity instanceof ModelViewEntity) {
        return "ERROR: Cannot delete foreign keys indices for a view entity";
    }
    StringBuilder retMsgsBuffer = new StringBuilder();
    // go through the relationships to see if any foreign keys need to be added
    Iterator<ModelRelation> relationsIter = entity.getRelationsIterator();
    while (relationsIter.hasNext()) {
        ModelRelation modelRelation = relationsIter.next();
        if ("one".equals(modelRelation.getType())) {
            String retMsg = deleteForeignKeyIndex(entity, modelRelation, constraintNameClipLength);
            if (UtilValidate.isNotEmpty(retMsg)) {
                if (retMsgsBuffer.length() > 0) {
                    retMsgsBuffer.append("\n");
                }
                retMsgsBuffer.append(retMsg);
            }
        }
    }
    if (retMsgsBuffer.length() > 0) {
        return retMsgsBuffer.toString();
    } else {
        return null;
    }
}
Also used : ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation)

Example 9 with ModelRelation

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

the class DatabaseUtil method deleteForeignKeys.

public void deleteForeignKeys(ModelEntity entity, Map<String, ModelEntity> modelEntities, int constraintNameClipLength, List<String> messages) {
    if (entity == null) {
        String errMsg = "ModelEntity was null and is required to delete foreign keys for a table";
        if (messages != null)
            messages.add(errMsg);
        Debug.logError(errMsg, module);
        return;
    }
    if (entity instanceof ModelViewEntity) {
        // Debug.logError(errMsg, module);
        return;
    }
    String message = "Deleting foreign keys for entity [" + entity.getEntityName() + "]";
    Debug.logImportant(message, module);
    if (messages != null)
        messages.add(message);
    // go through the relationships to see if any foreign keys need to be added
    Iterator<ModelRelation> relationsIter = entity.getRelationsIterator();
    while (relationsIter.hasNext()) {
        ModelRelation modelRelation = relationsIter.next();
        if ("one".equals(modelRelation.getType())) {
            ModelEntity relModelEntity = modelEntities.get(modelRelation.getRelEntityName());
            if (relModelEntity == null) {
                String errMsg = "Error removing foreign key: ModelEntity was null for related entity name " + modelRelation.getRelEntityName();
                if (messages != null)
                    messages.add(errMsg);
                Debug.logError(errMsg, module);
                continue;
            }
            if (relModelEntity instanceof ModelViewEntity) {
                String errMsg = "Error removing foreign key: related entity is a view entity for related entity name " + modelRelation.getRelEntityName();
                if (messages != null)
                    messages.add(errMsg);
                Debug.logError(errMsg, module);
                continue;
            }
            String retMsg = deleteForeignKey(entity, modelRelation, relModelEntity, constraintNameClipLength);
            if (UtilValidate.isNotEmpty(retMsg)) {
                if (messages != null)
                    messages.add(retMsg);
                Debug.logError(retMsg, module);
            }
        }
    }
}
Also used : ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity)

Example 10 with ModelRelation

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

the class DatabaseUtil method createForeignKeyIndices.

public int createForeignKeyIndices(ModelEntity entity, int constraintNameClipLength, List<String> messages) {
    if (entity == null) {
        String message = "ModelEntity was null and is required to create foreign keys indices for a table";
        Debug.logError(message, module);
        if (messages != null)
            messages.add(message);
        return 0;
    }
    if (entity instanceof ModelViewEntity) {
        String message = "Cannot create foreign keys indices for a view entity";
        Debug.logWarning(message, module);
        if (messages != null)
            messages.add(message);
        return 0;
    }
    int fkisCreated = 0;
    // go through the relationships to see if any foreign keys need to be added
    Iterator<ModelRelation> relationsIter = entity.getRelationsIterator();
    while (relationsIter.hasNext()) {
        ModelRelation modelRelation = relationsIter.next();
        if ("one".equals(modelRelation.getType())) {
            String retMsg = createForeignKeyIndex(entity, modelRelation, constraintNameClipLength);
            if (UtilValidate.isNotEmpty(retMsg)) {
                String message = "Could not create foreign key indices for entity [" + entity.getEntityName() + "]: " + retMsg;
                Debug.logError(message, module);
                if (messages != null)
                    messages.add(message);
                continue;
            }
            fkisCreated++;
        }
    }
    if (fkisCreated > 0) {
        String message = "Created " + fkisCreated + " foreign key indices for entity [" + entity.getEntityName() + "]";
        Debug.logImportant(message, module);
        if (messages != null)
            messages.add(message);
    }
    return fkisCreated;
}
Also used : ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation)

Aggregations

ModelRelation (org.apache.ofbiz.entity.model.ModelRelation)14 ModelEntity (org.apache.ofbiz.entity.model.ModelEntity)10 HashMap (java.util.HashMap)7 ModelKeyMap (org.apache.ofbiz.entity.model.ModelKeyMap)7 ModelViewEntity (org.apache.ofbiz.entity.model.ModelViewEntity)6 UtilObject (org.apache.ofbiz.base.util.UtilObject)4 ModelField (org.apache.ofbiz.entity.model.ModelField)3 ModelFieldType (org.apache.ofbiz.entity.model.ModelFieldType)3 SQLException (java.sql.SQLException)2 LinkedList (java.util.LinkedList)2 Map (java.util.Map)2 TreeSet (java.util.TreeSet)2 GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)2 ModelIndex (org.apache.ofbiz.entity.model.ModelIndex)2 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 MalformedURLException (java.net.MalformedURLException)1 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1