Search in sources :

Example 11 with BackgroundCommand

use of CCDD.CcddBackgroundCommand.BackgroundCommand in project CCDD by nasa.

the class CcddDbControlHandler method renameDatabaseInBackground.

/**
 ********************************************************************************************
 * Rename a project and/or add/update the database description. This command is executed in a
 * separate thread since it can take a noticeable amount time to complete, and by using a
 * separate thread the GUI is allowed to continue to update. The GUI menu commands, however,
 * are disabled until the database command completes execution
 *
 * @param oldProject
 *            current name of the project
 *
 * @param newProject
 *            new name of the project
 *
 * @param description
 *            database description
 ********************************************************************************************
 */
protected void renameDatabaseInBackground(final String oldProject, final String newProject, final String description) {
    // Execute the command in the background
    CcddBackgroundCommand.executeInBackground(ccddMain, new BackgroundCommand() {

        /**
         ************************************************************************************
         * Rename database command
         ************************************************************************************
         */
        @Override
        protected void execute() {
            String currentDatabase = activeDatabase;
            // Convert the project names to their database equivalents
            String oldDatabase = convertProjectNameToDatabase(oldProject);
            String newDatabase = convertProjectNameToDatabase(newProject);
            try {
                // project name and/or description changed
                if (oldDatabase.equals(newDatabase)) {
                    // Update the database's description
                    dbCommand.executeDbUpdate(buildDatabaseCommentCommand(newProject, false, description), ccddMain.getMainFrame());
                } else // (required in order to make changes to the current database)
                if (!oldDatabase.equals(currentDatabase) || !openDatabase(DEFAULT_DATABASE)) {
                    // Rename the database to the new name and update the description
                    dbCommand.executeDbUpdate("ALTER DATABASE " + oldDatabase + " RENAME TO " + newDatabase + "; " + buildDatabaseCommentCommand(newProject, false, description), ccddMain.getMainFrame());
                    // Check if the currently open database is the one being renamed
                    if (oldDatabase.equals(currentDatabase)) {
                        // Close the default database and reopen the target
                        openDatabase(newProject, false);
                    }
                    // Log that the renaming the database succeeded
                    eventLog.logEvent(SUCCESS_MSG, "Project database '" + oldProject + "' renamed to '" + newProject + "'");
                }
            } catch (SQLException se) {
                // Inform the user that the database cannot be renamed
                eventLog.logFailEvent(ccddMain.getMainFrame(), "Cannot rename project database '" + getServerAndDatabase(oldDatabase) + "'; cause '" + se.getMessage() + "'", "<html><b>Cannot rename project '</b>" + oldProject + "<b>'");
                // renamed
                if (oldProject.equals(currentDatabase)) {
                    // Close the default database and reopen the target
                    openDatabase(currentDatabase, false);
                }
            }
        }
    });
}
Also used : SQLException(java.sql.SQLException) BackgroundCommand(CCDD.CcddBackgroundCommand.BackgroundCommand)

Example 12 with BackgroundCommand

use of CCDD.CcddBackgroundCommand.BackgroundCommand in project CCDD by nasa.

the class CcddDbTableCommandHandler method modifyTablePerDataTypeOrMacroChanges.

/**
 ********************************************************************************************
 * Modify all tables affected by changes to the user-defined data type names, or macro names
 * and/or macro values. This command is executed in a separate thread since it can take a
 * noticeable amount time to complete, and by using a separate thread the GUI is allowed to
 * continue to update. The GUI menu commands, however, are disabled until the database command
 * completes execution
 *
 * @param modifications
 *            list of data type (macro) definition modifications
 *
 * @param updates
 *            list of string arrays reflecting the content of the data types (macros) after
 *            being changed in the data type (macro) editor
 *
 * @param dialog
 *            reference to the data type or macro editor dialog
 ********************************************************************************************
 */
protected void modifyTablePerDataTypeOrMacroChanges(final List<TableModification> modifications, final List<String[]> updates, final CcddDialogHandler dialog) {
    final CcddDataTypeHandler newDataTypeHandler;
    final CcddMacroHandler newMacroHandler;
    final String changeName;
    // Set to true if the change is to a data type, and false if the change is to a macro
    final boolean isDataType = dialog instanceof CcddDataTypeEditorDialog;
    // Check if this is a data type change
    if (isDataType) {
        // Create new data type, macro, and variable size handlers using the updates from the
        // data type editor
        newDataTypeHandler = new CcddDataTypeHandler(updates);
        newMacroHandler = new CcddMacroHandler(ccddMain, ccddMain.getMacroHandler().getMacroData());
        changeName = "Data types";
    } else // This is a macro change
    {
        // Create new macro and variable size handlers using the updates from the macro editor
        newDataTypeHandler = dataTypeHandler;
        newMacroHandler = new CcddMacroHandler(ccddMain, updates);
        changeName = "Macros";
    }
    // Create a variable size handler accounting for the updates, then build the variable paths
    // and offsets lists
    final CcddVariableSizeAndConversionHandler newVariableHandler = new CcddVariableSizeAndConversionHandler(ccddMain, newDataTypeHandler, newMacroHandler);
    newMacroHandler.setHandlers(newVariableHandler);
    newVariableHandler.buildPathAndOffsetLists();
    /**
     ****************************************************************************************
     * Class for table information for those tables modified due to changes in a data type
     * (macro) definition
     ****************************************************************************************
     */
    class ModifiedTable {

        private final TableInformation tableInformation;

        private final CcddTableEditorHandler editor;

        /**
         ************************************************************************************
         * Class constructor for table information for those tables modified due to changes in
         * a data type (macro) definition
         *
         * @param tablePath
         *            table path (if applicable) and name
         ************************************************************************************
         */
        ModifiedTable(String tablePath) {
            // Load the table's information from the project database
            tableInformation = loadTableData(tablePath, false, true, false, dialog);
            // Create a table editor handler using the updated data types and/or macros, but
            // without displaying the editor itself
            editor = new CcddTableEditorHandler(ccddMain, tableInformation, newDataTypeHandler, newMacroHandler);
        }

        /**
         ************************************************************************************
         * Get the reference to the table information
         *
         * @return Reference to the table information
         ************************************************************************************
         */
        protected TableInformation getTableInformation() {
            return tableInformation;
        }

        /**
         ************************************************************************************
         * Get the reference to the table editor
         *
         * @return Reference to the table editor
         ************************************************************************************
         */
        protected CcddTableEditorHandler getEditor() {
            return editor;
        }
    }
    // Execute the command in the background
    CcddBackgroundCommand.executeInBackground(ccddMain, dialog, new BackgroundCommand() {

        boolean errorFlag = false;

        List<ModifiedTable> modifiedTables = new ArrayList<ModifiedTable>();

        /**
         ************************************************************************************
         * Modify data types (macros) command
         ************************************************************************************
         */
        @Override
        protected void execute() {
            TypeDefinition typeDefn = null;
            // Flag that indicates that only a data type (macro) name has been altered, or a
            // data type size where the new size is not larger than the old size. If this
            // remains true for all data type (macro) updates then the project database
            // internal table update process is streamlined, making it much faster in cases
            // where the internal tables reference a large number of variables and tables
            boolean nameChangeOnly = true;
            // Storage for the table's data. This is the table data as it exists in the project
            // database
            List<Object[]> tableData;
            // Step through each modification
            for (TableModification mod : modifications) {
                String oldName;
                String newName;
                String oldNameDelim = null;
                String newNameDelim = null;
                String[] references;
                // Check if this is a data type change
                if (isDataType) {
                    // Get the original and updated user-defined data type names
                    oldName = CcddDataTypeHandler.getDataTypeName(mod.getOriginalRowData()[DataTypesColumn.USER_NAME.ordinal()].toString(), mod.getOriginalRowData()[DataTypesColumn.C_NAME.ordinal()].toString());
                    newName = CcddDataTypeHandler.getDataTypeName(mod.getRowData()[DataTypesColumn.USER_NAME.ordinal()].toString(), mod.getRowData()[DataTypesColumn.C_NAME.ordinal()].toString());
                    // Get the references to the updated data type
                    references = dataTypeHandler.getDataTypeReferences(oldName, dialog);
                    // the initial pass)
                    if (nameChangeOnly) {
                        // Set to false if the size increased or the base type changed; keep
                        // equal to true if only the data type name has changed and the size is
                        // no larger
                        nameChangeOnly = Integer.valueOf(mod.getOriginalRowData()[DataTypesColumn.SIZE.ordinal()].toString()) >= Integer.valueOf(mod.getRowData()[DataTypesColumn.SIZE.ordinal()].toString()) && mod.getOriginalRowData()[DataTypesColumn.BASE_TYPE.ordinal()].toString().equals(mod.getRowData()[DataTypesColumn.BASE_TYPE.ordinal()].toString());
                    }
                } else // This is a macro change
                {
                    // Get the original and updated user-defined macro names
                    oldName = mod.getOriginalRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString();
                    newName = mod.getRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString();
                    // Get the original and updated macro names with the macro delimiters
                    oldNameDelim = CcddMacroHandler.getFullMacroName(mod.getOriginalRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString());
                    newNameDelim = CcddMacroHandler.getFullMacroName(mod.getRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString());
                    // Get the references to the updated macro
                    references = macroHandler.getMacroReferences(oldNameDelim, dialog);
                    // initial pass)
                    if (nameChangeOnly) {
                        // Set to false if the macro value changes; keep equal to true if only
                        // the macro name has changed
                        nameChangeOnly = macroHandler.getMacroExpansion(mod.getOriginalRowData()[MacrosColumn.VALUE.ordinal()].toString()).equals(newMacroHandler.getMacroExpansion(mod.getRowData()[MacrosColumn.VALUE.ordinal()].toString()));
                    }
                }
                // Step through each table/column containing the modification
                for (String ref : references) {
                    String tableName = null;
                    String changeColumn = null;
                    String matchColumn = null;
                    ModifiedTable modifiedTable = null;
                    // Split the reference into table name, column name, table type, and
                    // context
                    String[] tblColDescAndCntxt = ref.split(TABLE_DESCRIPTION_SEPARATOR, 4);
                    // Create a reference to the search result's database table name and row
                    // data to shorten comparisons below
                    String refTableName = tblColDescAndCntxt[SearchResultsQueryColumn.TABLE.ordinal()];
                    String[] refContext = CcddUtilities.splitAndRemoveQuotes(tblColDescAndCntxt[SearchResultsQueryColumn.CONTEXT.ordinal()]);
                    // Set to true if the referenced table is a prototype table and false if
                    // the reference is to the internal custom values table
                    boolean isPrototype = !refTableName.startsWith(INTERNAL_TABLE_PREFIX);
                    // Check if the referenced table is a prototype table
                    if (isPrototype) {
                        // Set the viewable table name (with capitalization intact) and get the
                        // column name containing the data type (macro) reference. Use the
                        // primary key as the matching column criteria
                        tableName = tblColDescAndCntxt[SearchResultsQueryColumn.COMMENT.ordinal()].split(",", 2)[0];
                        changeColumn = tblColDescAndCntxt[SearchResultsQueryColumn.COLUMN.ordinal()];
                        matchColumn = refContext[DefaultColumn.PRIMARY_KEY.ordinal()];
                    } else // change
                    if (!isDataType) {
                        // Get the table name from the variable path in the custom values table
                        // and get the column name containing the macro reference. Use the
                        // variable name as the matching column criteria
                        tableName = refContext[ValuesColumn.TABLE_PATH.ordinal()].replaceAll("(\"|\\s|,[^\\.]*\\.[^,]*$)", "");
                        changeColumn = refContext[ValuesColumn.COLUMN_NAME.ordinal()];
                        matchColumn = refContext[ValuesColumn.TABLE_PATH.ordinal()].replaceAll("(.*\\.|\")", "");
                    } else // This is a data type change and the reference is in the custom values
                    // table
                    {
                        // process
                        continue;
                    }
                    // Step through each table already loaded for modifications
                    for (ModifiedTable modTbl : modifiedTables) {
                        // Check if the table has already been loaded
                        if (modTbl.getTableInformation().getProtoVariableName().equals(tableName)) {
                            // Store the reference to the modified table and stop searching
                            modifiedTable = modTbl;
                            break;
                        }
                    }
                    // Check if the table isn't already loaded
                    if (modifiedTable == null) {
                        // Load the table and add it to the list
                        modifiedTable = new ModifiedTable(tableName);
                        modifiedTables.add(modifiedTable);
                        // Check if the table arrays aren't expanded
                        if (!modifiedTable.getEditor().isExpanded()) {
                            // Expand the table arrays
                            modifiedTable.getEditor().showHideArrayMembers();
                        }
                    }
                    // Get the reference to the table to shorten subsequent calls
                    CcddJTableHandler table = modifiedTable.getEditor().getTable();
                    // Use the table's type to get the index for the table column containing
                    // the data type (macro) reference
                    typeDefn = modifiedTable.getEditor().getTableTypeDefinition();
                    int changeColumnIndex = isPrototype ? typeDefn.getColumnIndexByDbName(changeColumn) : typeDefn.getColumnIndexByUserName(changeColumn);
                    String macroValue = null;
                    // Check is a change was made to a macro
                    if (!isDataType) {
                        // Get the original value of the macro
                        macroValue = macroHandler.getMacroValue(oldName);
                    }
                    // Set the flags that indicate if a name or value changed
                    boolean isNameChange = !oldName.equals(newName);
                    boolean isValueChange = (isDataType && (dataTypeHandler.getSizeInBytes(oldName) != newDataTypeHandler.getSizeInBytes(newName) || !dataTypeHandler.getBaseDataType(oldName).equals(newDataTypeHandler.getBaseDataType(newName)))) || (!isDataType && macroValue != null && !macroValue.equals(newMacroHandler.getMacroValue(newName)));
                    // base type, or macro value, changed
                    if (isNameChange || isValueChange) {
                        // Get the table's data (again if a name change occurred since changes
                        // were made)
                        tableData = table.getTableDataList(false);
                        // Step through each row
                        for (int row = 0; row < tableData.size(); row++) {
                            // column index for the variable name
                            if (isPrototype ? matchColumn.equals(tableData.get(row)[DefaultColumn.PRIMARY_KEY.ordinal()]) : matchColumn.equals(tableData.get(row)[typeDefn.getColumnIndexByInputType(InputDataType.VARIABLE)].toString())) {
                                // key and row index columns
                                for (int column = NUM_HIDDEN_COLUMNS; column < tableData.get(row).length; column++) {
                                    // macro
                                    if (column == changeColumnIndex) {
                                        // Check if the cell value is editable
                                        if (table.isCellEditable(table.convertRowIndexToView(row), table.convertColumnIndexToView(column))) {
                                            // Get the contents of the cell containing the data
                                            // type or macro reference
                                            String oldValue = tableData.get(row)[column].toString();
                                            String newValue = oldValue;
                                            // Check if the data type or macro name changed
                                            if (isNameChange) {
                                                // Check if this is a data type change
                                                if (isDataType) {
                                                    // the data type name
                                                    if (!oldValue.equals(oldName)) {
                                                        // sizeof() call for the data type
                                                        if (!CcddVariableSizeAndConversionHandler.hasSizeof(oldValue, oldName)) {
                                                            // type match is coincidental
                                                            continue;
                                                        }
                                                        // replacing each sizeof() instance
                                                        while (CcddVariableSizeAndConversionHandler.hasSizeof(newValue, oldName)) {
                                                            // Replace the data type in the
                                                            // sizeof() call with the new name
                                                            newValue = newValue.replaceFirst(CcddVariableSizeAndConversionHandler.getSizeofDataTypeMatch(oldName), "sizeof(" + newName + ")");
                                                        }
                                                    } else // The cell contains only the data type
                                                    // name
                                                    {
                                                        // Set the new cell value to the new
                                                        // data type name
                                                        newValue = newName;
                                                    }
                                                } else // This is a macro change
                                                {
                                                    // Replace all instances of the old macro
                                                    // name in the table cell with the new name
                                                    newValue = macroHandler.replaceMacroName(oldNameDelim, newNameDelim, oldValue);
                                                }
                                            }
                                            // size or base type
                                            if (isDataType && isValueChange) {
                                                // sizeof() call)
                                                if (!newValue.equals(newName) && !CcddVariableSizeAndConversionHandler.hasSizeof(newValue) && !CcddMacroHandler.hasMacro(newValue)) {
                                                    // match is coincidental
                                                    continue;
                                                }
                                            }
                                            // Store the change in the table data
                                            tableData.get(row)[column] = newValue;
                                            // Make the change to the cell, including any
                                            // updates to changes in array size
                                            table.validateCellContent(tableData, row, column, oldValue, newValue, false, true);
                                            // Load the updated array of data into the table
                                            table.loadDataArrayIntoTable(tableData.toArray(new Object[0][0]), false);
                                        }
                                        // located and processed
                                        break;
                                    }
                                }
                                // processed
                                break;
                            }
                        }
                    }
                }
            }
            try {
                // Enable creation of a save point in case an error occurs while modifying a
                // table. This prevents committing the changes to the database until after all
                // tables are modified
                dbCommand.setSavePointEnable(true);
                // simplified in order to speed it up
                if (nameChangeOnly) {
                    // references in the internal tables
                    for (TableModification mod : modifications) {
                        // Check if this is a data type change
                        if (isDataType) {
                            // Get the old and new data type name
                            String oldName = CcddDataTypeHandler.getDataTypeName(mod.getOriginalRowData()[DataTypesColumn.USER_NAME.ordinal()].toString(), mod.getOriginalRowData()[DataTypesColumn.C_NAME.ordinal()].toString());
                            String newName = CcddDataTypeHandler.getDataTypeName(mod.getRowData()[DataTypesColumn.USER_NAME.ordinal()].toString(), mod.getRowData()[DataTypesColumn.C_NAME.ordinal()].toString());
                            // Execute the command to update the internal tables that reference
                            // variable paths
                            dbCommand.executeDbUpdate("UPDATE " + InternalTable.LINKS.getTableName() + " SET " + LinksColumn.MEMBER.getColumnName() + " = regexp_replace(" + LinksColumn.MEMBER.getColumnName() + ", E'(.*,)" + oldName + "(\\..*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.TLM_SCHEDULER.getTableName() + " SET " + TlmSchedulerColumn.MEMBER.getColumnName() + " = regexp_replace(" + TlmSchedulerColumn.MEMBER.getColumnName() + ", E'(.*,)" + oldName + "(\\..*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.VALUES.getTableName() + " SET " + ValuesColumn.TABLE_PATH.getColumnName() + " = regexp_replace(" + ValuesColumn.TABLE_PATH.getColumnName() + ", E'(.*,)" + oldName + "(\\..*)'" + ", E'\\\\1" + newName + "\\\\2'); ", dialog);
                        } else // This is a macro change
                        {
                            // Get the original and updated user-defined macro names (with the
                            // delimiters)
                            String oldName = CcddMacroHandler.getFullMacroName(mod.getOriginalRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString());
                            String newName = CcddMacroHandler.getFullMacroName(mod.getRowData()[MacrosColumn.MACRO_NAME.ordinal()].toString());
                            // Execute the command to update the internal tables that reference
                            // variable and table paths
                            dbCommand.executeDbUpdate("UPDATE " + InternalTable.ASSOCIATIONS.getTableName() + " SET " + AssociationsColumn.MEMBERS.getColumnName() + " = regexp_replace(" + AssociationsColumn.MEMBERS.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.FIELDS.getTableName() + " SET " + FieldsColumn.OWNER_NAME.getColumnName() + " = regexp_replace(" + FieldsColumn.OWNER_NAME.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.GROUPS.getTableName() + " SET " + GroupsColumn.MEMBERS.getColumnName() + " = regexp_replace(" + GroupsColumn.MEMBERS.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.LINKS.getTableName() + " SET " + LinksColumn.MEMBER.getColumnName() + " = regexp_replace(" + LinksColumn.MEMBER.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.TLM_SCHEDULER.getTableName() + " SET " + TlmSchedulerColumn.MEMBER.getColumnName() + " = regexp_replace(" + TlmSchedulerColumn.MEMBER.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); UPDATE " + InternalTable.VALUES.getTableName() + " SET " + ValuesColumn.TABLE_PATH.getColumnName() + " = regexp_replace(" + ValuesColumn.TABLE_PATH.getColumnName() + ", E'(.*)" + oldName + "(.*)'" + ", E'\\\\1" + newName + "\\\\2'); ", dialog);
                        }
                    }
                }
                // Step through each modified table
                for (ModifiedTable modTbl : modifiedTables) {
                    // Build the additions, modifications, and deletions to the table
                    modTbl.getEditor().buildUpdates();
                    // table editors that contain the data type (macro) reference(s)
                    if (modifyTableData(modTbl.getTableInformation(), modTbl.getEditor().getAdditions(), modTbl.getEditor().getModifications(), modTbl.getEditor().getDeletions(), true, nameChangeOnly, false, false, false, newDataTypeHandler, dialog)) {
                        throw new SQLException("table modification error");
                    }
                }
                // Store the data type or macro table
                dbCommand.executeDbUpdate(storeNonTableTypesInfoTableCommand((isDataType ? InternalTable.DATA_TYPES : InternalTable.MACROS), CcddUtilities.removeArrayListColumn(updates, (isDataType ? DataTypesColumn.OID.ordinal() : MacrosColumn.OID.ordinal())), null, dialog), dialog);
                // Commit the change(s) to the database
                dbCommand.getConnection().commit();
                // Inform the user that the update succeeded
                eventLog.logEvent(SUCCESS_MSG, changeName + " and all affected tables updated");
            } catch (SQLException se) {
                try {
                    // Inform the user that updating the macros failed
                    eventLog.logFailEvent(dialog, "Cannot update " + changeName.toLowerCase() + "; cause '" + se.getMessage() + "'", "<html><b>Cannot update " + changeName.toLowerCase());
                    // Revert the changes to the tables that were successfully updated prior
                    // the current table
                    dbCommand.executeDbCommand("ROLLBACK TO SAVEPOINT " + DB_SAVE_POINT_NAME + ";", dialog);
                } catch (SQLException se2) {
                    // Inform the user that the reversion to the save point failed
                    eventLog.logFailEvent(dialog, "Cannot revert changes to table(s); cause '" + se.getMessage() + "'", "<html><b>Cannot revert changes to table(s)");
                }
                errorFlag = true;
            } catch (Exception e) {
                // Display a dialog providing details on the unanticipated error
                CcddUtilities.displayException(e, dialog);
            } finally {
                // Reset the flag for creating a save point
                dbCommand.setSavePointEnable(false);
            }
        }

        /**
         ************************************************************************************
         * Modify data types or macros command complete
         ************************************************************************************
         */
        @Override
        protected void complete() {
            // Rebuild the variable paths and offsets
            variableHandler.buildPathAndOffsetLists();
            // Check if this is a data type change
            if (isDataType) {
                ((CcddDataTypeEditorDialog) dialog).doDataTypeUpdatesComplete(errorFlag);
            } else // This is a macro change
            {
                ((CcddMacroEditorDialog) dialog).doMacroUpdatesComplete(errorFlag);
            }
        }
    });
}
Also used : SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) TableModification(CCDD.CcddClassesDataTable.TableModification) CCDDException(CCDD.CcddClassesDataTable.CCDDException) SQLException(java.sql.SQLException) TypeDefinition(CCDD.CcddTableTypeHandler.TypeDefinition) TableInformation(CCDD.CcddClassesDataTable.TableInformation) List(java.util.List) ArrayList(java.util.ArrayList) DatabaseObject(CCDD.CcddConstants.DatabaseObject) BackgroundCommand(CCDD.CcddBackgroundCommand.BackgroundCommand)

Example 13 with BackgroundCommand

use of CCDD.CcddBackgroundCommand.BackgroundCommand in project CCDD by nasa.

the class CcddDbTableCommandHandler method deleteTableType.

/**
 ********************************************************************************************
 * Delete a table type and all tables of the deleted type. This command is executed in a
 * separate thread since it can take a noticeable amount time to complete, and by using a
 * separate thread the GUI is allowed to continue to update. The GUI menu commands, however,
 * are disabled until the database command completes execution
 *
 * @param typeName
 *            type of table to delete
 *
 * @param isStructure
 *            true if the table type represents a structure
 *
 * @param typeDialog
 *            reference to the type manager dialog
 *
 * @param parent
 *            GUI component calling this method
 ********************************************************************************************
 */
protected void deleteTableType(final String typeName, final boolean isStructure, final CcddTableTypeManagerDialog typeDialog, final Component parent) {
    // Execute the command in the background
    CcddBackgroundCommand.executeInBackground(ccddMain, new BackgroundCommand() {

        boolean errorFlag = false;

        boolean isStructure = false;

        String[] tableNames = null;

        String names = "";

        /**
         ************************************************************************************
         * Table type deletion command
         ************************************************************************************
         */
        @Override
        protected void execute() {
            try {
                // Get the reference to the type definition
                TypeDefinition typeDefn = tableTypeHandler.getTypeDefinition(typeName);
                // Set the flag to indicate if the type represents a structure
                boolean isStructure = typeDefn.isStructure();
                // Delete the table type definition from the table type handler
                tableTypeHandler.getTypeDefinitions().remove(typeDefn);
                // Create the command to update the table definitions table
                String command = storeTableTypesInfoTableCommand();
                // Get an array containing tables of the specified type
                tableNames = queryTablesOfTypeList(typeName, ccddMain.getMainFrame());
                // Check if there are any associated tables to delete
                if (tableNames.length != 0) {
                    // Convert the array of tables names into a single string and shorten it if
                    // too long
                    names = getShortenedTableNames(tableNames);
                    // Check if the user confirms deleting the affected table(s)
                    if (new CcddDialogHandler().showMessageDialog(parent, "<html><b>Delete table(s) '</b>" + names + "<b>' of type '</b>" + typeName + "<b>'?<br><br><i>Warning: This action cannot be undone!", "Delete Table(s)", JOptionPane.QUESTION_MESSAGE, DialogOption.OK_CANCEL_OPTION) == OK_BUTTON) {
                        // Add the command to delete the tables and all their references in the
                        // internal tables
                        command += deleteTableCommand(tableNames, true) + " ";
                    } else // The user canceled the operation
                    {
                        // Set the error flag to restore the deleted type definition
                        errorFlag = true;
                    }
                }
                // Check if the user didn't cancel the operation
                if (!errorFlag) {
                    // Add the command to remove any default data fields for this table type
                    command += modifyFieldsCommand(CcddFieldHandler.getFieldTypeName(typeName), null);
                    // Step through the array of table names
                    for (String name : tableNames) {
                        // Remove the table's data fields
                        command += modifyFieldsCommand(name, null);
                    }
                    // Modify the (shortened) names string for logging messages
                    names = " and table(s) '</b>" + names + "<b>'";
                    // Delete the table(s)
                    dbCommand.executeDbUpdate(command, parent);
                    // Execute the command to reset the rate for links that no longer contain
                    // any variables
                    dbCommand.executeDbQuery("SELECT reset_link_rate();", parent);
                    // Check if the the deleted type represented a structure
                    if (isStructure) {
                        // Update the list of root structure tables
                        rootStructures = getRootStructures(parent);
                    }
                    // Log that table deletion succeeded
                    eventLog.logEvent(SUCCESS_MSG, "Table type '" + typeName + "'" + CcddUtilities.removeHTMLTags(names) + " deleted");
                }
            } catch (SQLException se) {
                // Inform the user that the table deletion failed
                eventLog.logFailEvent(parent, "Cannot delete table type '" + typeName + "'" + CcddUtilities.removeHTMLTags(names) + "; cause '" + se.getMessage() + "'", "<html><b>Cannot delete table type '" + typeName + "'</b>" + names + "<b>'");
                errorFlag = true;
            }
        }

        /**
         ************************************************************************************
         * Delete table type command complete
         ************************************************************************************
         */
        @Override
        protected void complete() {
            // Check if no error occurred when deleting the table type
            if (!errorFlag) {
                // Check if the deleted type represents a structure
                if (isStructure) {
                    // Update the database functions that collect structure table members and
                    // structure-defining column data
                    dbControl.createStructureColumnFunctions();
                }
                // Check if the number of rate columns changed due to the type deletion
                if (rateHandler.setRateInformation()) {
                    // Store the rate parameters in the project database
                    storeRateParameters(ccddMain.getMainFrame());
                }
            }
            // Perform any remaining steps, based on if deleting the type was successful
            typeDialog.doTypeOperationComplete(errorFlag, null, tableNames);
        }
    });
}
Also used : SQLException(java.sql.SQLException) BackgroundCommand(CCDD.CcddBackgroundCommand.BackgroundCommand) TypeDefinition(CCDD.CcddTableTypeHandler.TypeDefinition)

Example 14 with BackgroundCommand

use of CCDD.CcddBackgroundCommand.BackgroundCommand in project CCDD by nasa.

the class CcddDbTableCommandHandler method copyTable.

/**
 ********************************************************************************************
 * Make a copy of an existing table. Only prototype tables can be copied using this method
 * (instances are copied by adding a new instance and copying the values to it in the table
 * editor). This command is executed in a separate thread since it can take a noticeable amount
 * time to complete, and by using a separate thread the GUI is allowed to continue to update.
 * The GUI menu commands, however, are disabled until the database command completes execution
 *
 * @param tableName
 *            name of the table to copy
 *
 * @param newName
 *            name of the table copy
 *
 * @param newDescription
 *            new description for this table
 *
 * @param tableDialog
 *            reference to the table manager dialog
 ********************************************************************************************
 */
protected void copyTable(final String tableName, final String newName, final String newDescription, final CcddTableManagerDialog tableDialog) {
    // Execute the command in the background
    CcddBackgroundCommand.executeInBackground(ccddMain, new BackgroundCommand() {

        boolean errorFlag = false;

        /**
         ************************************************************************************
         * Copy table command
         ************************************************************************************
         */
        @Override
        protected void execute() {
            try {
                // Convert the table names to lower case. This is done automatically by
                // PostgreSQL, so this is done here to differentiate the table name from the
                // upper case database commands in the event log
                String dbTableName = tableName.toLowerCase();
                String dbNewName = newName.toLowerCase();
                // Get the existing table's comment, description, and column order so that
                // these can be used for the copy
                String[] comment = queryDataTableComment(dbTableName, tableDialog);
                String columnOrder = queryColumnOrder(tableName, comment[1], tableDialog);
                String sequenceName = dbNewName + "_" + DefaultColumn.PRIMARY_KEY.getDbName() + "_seq";
                // Create the command to copy the original table
                String command = "CREATE TABLE " + dbNewName + " (LIKE " + dbTableName + " INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES); ALTER TABLE " + dbNewName + " ALTER " + DefaultColumn.PRIMARY_KEY.getDbName() + " DROP DEFAULT; CREATE SEQUENCE " + sequenceName + "; INSERT INTO " + dbNewName + " SELECT * FROM " + dbTableName + "; ALTER SEQUENCE " + sequenceName + " OWNED BY " + dbNewName + "." + DefaultColumn.PRIMARY_KEY.getDbName() + "; SELECT setval('" + sequenceName + "', (SELECT max(" + DefaultColumn.PRIMARY_KEY.getDbName() + ") FROM " + dbTableName + "), true); ALTER TABLE " + dbNewName + " ALTER " + DefaultColumn.PRIMARY_KEY.getDbName() + " SET DEFAULT nextval('" + sequenceName + "'); " + dbControl.buildOwnerCommand(DatabaseObject.TABLE, dbNewName) + dbControl.buildOwnerCommand(DatabaseObject.SEQUENCE, sequenceName);
                // Update the table comment to reflect the name with case intact, and create
                // the commands to duplicate the original table's description and column order
                command += buildDataTableComment(newName, comment[TableCommentIndex.TYPE.ordinal()]) + buildTableDescription(newName, newDescription) + buildColumnOrder(newName, columnOrder);
                // Copy the table's data field entries for the new table
                command += copyDataFieldCommand(tableName, newName, tableDialog);
                // Execute the command to copy the table, including the table's original name
                // (before conversion to all lower case) that's stored as a comment
                dbCommand.executeDbCommand(command, tableDialog);
                // Update the list of root structure tables
                rootStructures = getRootStructures(tableDialog);
                // Log that renaming the table succeeded
                eventLog.logEvent(SUCCESS_MSG, "Table '" + tableName + "' copied to '" + newName + "'");
            } catch (SQLException se) {
                // Inform the user that copying the table failed
                eventLog.logFailEvent(tableDialog, "Cannot copy table '" + tableName + "'; cause '" + se.getMessage() + "'", "<html><b>Cannot copy table '</b>" + tableName + "<b>'");
                errorFlag = true;
            }
        }

        /**
         ********************************************************************************
         * Copy database table command complete
         ********************************************************************************
         */
        @Override
        protected void complete() {
            // Check if no error occurred copying the table
            if (!errorFlag) {
                tableDialog.doTableOperationComplete();
            }
        }
    });
}
Also used : SQLException(java.sql.SQLException) BackgroundCommand(CCDD.CcddBackgroundCommand.BackgroundCommand)

Example 15 with BackgroundCommand

use of CCDD.CcddBackgroundCommand.BackgroundCommand in project CCDD by nasa.

the class CcddDbTableCommandHandler method renameTable.

/**
 ********************************************************************************************
 * Change the name of a table. Only prototype tables can be renamed using this method
 * (instances are renamed by changing the variable name in the prototype). This command is
 * executed in a separate thread since it can take a noticeable amount time to complete, and by
 * using a separate thread the GUI is allowed to continue to update. The GUI menu commands,
 * however, are disabled until the database command completes execution
 *
 * @param tableName
 *            current name of the table
 *
 * @param newName
 *            new name for this table
 *
 * @param newDescription
 *            new description for this table
 *
 * @param tableDialog
 *            reference to the table manager dialog
 ********************************************************************************************
 */
protected void renameTable(final String tableName, final String newName, final String newDescription, final CcddTableManagerDialog tableDialog) {
    // Execute the command in the background
    CcddBackgroundCommand.executeInBackground(ccddMain, new BackgroundCommand() {

        boolean errorFlag = false;

        /**
         ************************************************************************************
         * Rename database table command
         ************************************************************************************
         */
        @Override
        protected void execute() {
            try {
                // Convert the table names to lower case. This is done automatically by
                // PostgreSQL, so this is done here to differentiate the table name from the
                // upper case database commands in the event log
                String dbTableName = tableName.toLowerCase();
                String dbNewName = newName.toLowerCase();
                // Get the table's comment so that it can be rebuilt with the new table name
                String[] comment = queryDataTableComment(dbTableName, tableDialog);
                String command = "";
                // Check that the old and new names differ in more than capitalization
                if (!dbTableName.equals(dbNewName)) {
                    // Create the command to change the table's name and all references to it
                    // in the custom values, links, and groups tables
                    command = "ALTER TABLE " + dbTableName + " RENAME TO " + dbNewName + "; " + buildTableDescription(newName, newDescription) + renameInfoTableCommand(InternalTable.VALUES, ValuesColumn.TABLE_PATH.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.LINKS, LinksColumn.MEMBER.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.TLM_SCHEDULER, TlmSchedulerColumn.MEMBER.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.GROUPS, GroupsColumn.MEMBERS.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.FIELDS, FieldsColumn.OWNER_NAME.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.ORDERS, OrdersColumn.TABLE_PATH.getColumnName(), tableName, newName) + renameInfoTableCommand(InternalTable.ASSOCIATIONS, AssociationsColumn.MEMBERS.getColumnName(), tableName, newName);
                }
                // Update the table comment to reflect the name with case intact
                command += buildDataTableComment(newName, comment[TableCommentIndex.TYPE.ordinal()]);
                // Search for all occurrences of the old table name in those tables containing
                // a data type column and replace the references with the new table name
                command += "SELECT update_data_type_names('" + tableName + "', '" + newName + "');";
                // Execute the command to change the table's name, including the table's
                // original name (before conversion to all lower case) that's stored as a
                // comment
                dbCommand.executeDbCommand(command, tableDialog);
                // Update the list of root structure tables
                rootStructures = getRootStructures(tableDialog);
                // Log that renaming the table succeeded
                eventLog.logEvent(SUCCESS_MSG, "Table '" + tableName + "' renamed to '" + newName + "'");
            } catch (SQLException se) {
                // Inform the user that renaming the table failed
                eventLog.logFailEvent(tableDialog, "Cannot rename table '" + tableName + "'; cause '" + se.getMessage() + "'", "<html><b>Cannot rename table '</b>" + tableName + "<b>'");
                errorFlag = true;
            }
        }

        /**
         ************************************************************************************
         * Rename database table command complete
         ************************************************************************************
         */
        @Override
        protected void complete() {
            // Check if no error occurred renaming the table
            if (!errorFlag) {
                tableDialog.doTableOperationComplete();
            }
        }
    });
}
Also used : SQLException(java.sql.SQLException) BackgroundCommand(CCDD.CcddBackgroundCommand.BackgroundCommand)

Aggregations

BackgroundCommand (CCDD.CcddBackgroundCommand.BackgroundCommand)26 JPanel (javax.swing.JPanel)16 GridBagConstraints (java.awt.GridBagConstraints)14 GridBagLayout (java.awt.GridBagLayout)14 Insets (java.awt.Insets)14 ActionEvent (java.awt.event.ActionEvent)13 ArrayList (java.util.ArrayList)11 ActionListener (java.awt.event.ActionListener)10 SQLException (java.sql.SQLException)10 JButton (javax.swing.JButton)9 JLabel (javax.swing.JLabel)8 ValidateCellActionListener (CCDD.CcddClassesComponent.ValidateCellActionListener)7 TypeDefinition (CCDD.CcddTableTypeHandler.TypeDefinition)4 List (java.util.List)4 BoxLayout (javax.swing.BoxLayout)4 JCheckBox (javax.swing.JCheckBox)4 DnDTabbedPane (CCDD.CcddClassesComponent.DnDTabbedPane)3 Border (javax.swing.border.Border)3 CustomSplitPane (CCDD.CcddClassesComponent.CustomSplitPane)2 CCDDException (CCDD.CcddClassesDataTable.CCDDException)2