use of CCDD.CcddTableTypeHandler.TypeDefinition in project CCDD by nasa.
the class CcddScriptHandler method getScriptAssociationData.
/**
********************************************************************************************
* Retrieve the script associations stored in the database and from these build the array for
* display and selection of the script associations
*
* @param allowSelectDisabled
* true if disabled associations can be selected; false if not. In the script
* manager disabled associations are selectable so that these can be deleted if
* desired. Scripts that are selected and disabled are ignored when executing
* scripts
*
* @param parent
* GUI component calling this method
*
* @return Object array containing the script associations
********************************************************************************************
*/
private Object[][] getScriptAssociationData(boolean allowSelectDisabled, Component parent) {
List<Object[]> associationsData = new ArrayList<Object[]>();
// Read the stored script associations from the database
List<String[]> committedAssociations = dbTable.retrieveInformationTable(InternalTable.ASSOCIATIONS, parent);
// Get the list of table names and their associated table type
ArrayListMultiple protoNamesAndTableTypes = new ArrayListMultiple();
protoNamesAndTableTypes.addAll(dbTable.queryTableAndTypeList(parent));
// Load the group information from the database
CcddGroupHandler groupHandler = new CcddGroupHandler(ccddMain, null, parent);
// Create a list to contain the variables (dataType.variableName) that have been verified
// to exist. This reduces the number of database transactions in the event the same
// variable is used in multiple associations
List<String> verifiedVars = new ArrayList<String>();
// Step through each script association
for (String[] assn : committedAssociations) {
AvailabilityType availableStatus = AvailabilityType.AVAILABLE;
int numVerifications = 0;
StringBuilder verifications = new StringBuilder("");
try {
// Get the list of association table paths
List<String> tablePaths = getAssociationTablePaths(assn[AssociationsColumn.MEMBERS.ordinal()].toString(), groupHandler, parent);
// Check if at least one table is assigned to this script association
if (!tablePaths.isEmpty()) {
// Step through each table referenced in this association
for (String tablePath : tablePaths) {
String parentTable = "";
// Step through each data type and variable name pair
for (String variable : tablePath.split(",")) {
// Split the variable reference into the data type and variable name
String[] typeAndVar = variable.split(Pattern.quote("."));
// Check if the variable hasn't already been verified to exist
if (!verifiedVars.contains(variable)) {
// Locate the table's prototype in the list
int index = protoNamesAndTableTypes.indexOf(typeAndVar[0]);
// Check if the prototype table doesn't exist
if (index == -1) {
throw new CCDDException();
}
// root table, so there is no variable name)
if (typeAndVar.length == 2) {
// Get the table's type definition
TypeDefinition typeDefn = ccddMain.getTableTypeHandler().getTypeDefinition(protoNamesAndTableTypes.get(index)[2]);
// Check if the table doesn't represent a structure
if (!typeDefn.isStructure()) {
throw new CCDDException();
}
// Get the name of the column that represents the variable name
String varColumn = typeDefn.getDbColumnNameByInputType(InputDataType.VARIABLE);
// Add the command to verify the existence of the variable in
// the parent table to the overall verification command for
// this association
verifications.append("SELECT " + varColumn + " FROM " + parentTable + " WHERE " + varColumn + " = '" + typeAndVar[1] + "' UNION ALL ");
numVerifications++;
// Add the variable to the list of those verified to exist
verifiedVars.add(variable);
}
}
// Store the data type, which is the parent for the next variable (if
// any)
parentTable = typeAndVar[0];
}
}
// Check if there are any variables to verify
if (numVerifications != 0) {
// Complete the verification command
verifications = CcddUtilities.removeTrailer(verifications, "UNION ALL ").append(";");
// Query the tables for the variables to be checked
List<String[]> result = dbTable.queryDatabase(verifications.toString(), parent);
// were found
if (result == null || result.size() != numVerifications) {
throw new CCDDException();
}
}
}
} catch (CCDDException ce) {
// The script file or associated table doesn't exist; set the flag to indicate the
// association isn't available
availableStatus = AvailabilityType.TABLE_MISSING;
}
// Add the association to the script associations list
associationsData.add(new Object[] { assn[AssociationsColumn.NAME.ordinal()], assn[AssociationsColumn.DESCRIPTION.ordinal()], assn[AssociationsColumn.SCRIPT_FILE.ordinal()], CcddUtilities.highlightDataType(assn[AssociationsColumn.MEMBERS.ordinal()]), availableStatus });
}
return associationsData.toArray(new Object[0][0]);
}
use of CCDD.CcddTableTypeHandler.TypeDefinition in project CCDD by nasa.
the class CcddSearchHandler method removeArrayMemberReferences.
/**
********************************************************************************************
* Remove data type or macro search references where the match occurs in an array size column
* of an array member (the reference in the array's definition is all that's needed)
*
* @param matches
* list containing the search results for the data type or macro reference
*
* @param tbleTypeHndlr
* reference to the table type handler
********************************************************************************************
*/
protected static void removeArrayMemberReferences(List<String> matches, CcddTableTypeHandler tbleTypeHndlr) {
// Step through each match (in reverse since an entry in the list may need to be removed)
for (int index = matches.size() - 1; index >= 0; index--) {
// Separate the match components
String[] tblColDescAndCntxt = matches.get(index).split(TABLE_DESCRIPTION_SEPARATOR, 4);
// Separate the user-viewable table name and table type
String[] tableAndType = tblColDescAndCntxt[SearchResultsQueryColumn.COMMENT.ordinal()].split(",", 2);
// Get the table's type definition
TypeDefinition typeDefn = tbleTypeHndlr.getTypeDefinition(tableAndType[1]);
// Check if the reference is in an array size column
if (typeDefn.getDbColumnNameByInputType(InputDataType.ARRAY_INDEX).equals(tblColDescAndCntxt[SearchResultsQueryColumn.COLUMN.ordinal()])) {
// Separate the location into the individual columns. Commas between double quotes
// are ignored so that an erroneous column separation doesn't occur
String[] columns = CcddUtilities.splitAndRemoveQuotes(tblColDescAndCntxt[SearchResultsQueryColumn.CONTEXT.ordinal()]);
// Get the index of the variable name column
int varNameIndex = typeDefn.getColumnIndexByInputType(InputDataType.VARIABLE);
// Check if the variable name is an array member
if (varNameIndex != -1 && ArrayVariable.isArrayMember(columns[varNameIndex])) {
// Remove the match
matches.remove(index);
}
}
}
}
use of CCDD.CcddTableTypeHandler.TypeDefinition in project CCDD by nasa.
the class CcddDbControlHandler method createStructureColumnFunctions.
/**
********************************************************************************************
* Create the reusable database functions for obtaining structure table members and
* structure-defining column values
*
* @return true if an error occurs creating the structure functions
********************************************************************************************
*/
protected boolean createStructureColumnFunctions() {
boolean errorFlag = false;
// Check if connected to a project database
if (isDatabaseConnected()) {
try {
// Structure-defining column names, as used by the database
String dbVariableName = null;
String dbDataType = null;
String dbArraySize = null;
String dbBitLength = null;
String dbRate = null;
String dbEnumeration = null;
String compareColumns = "";
// Use the default structure column names for certain default columns
dbVariableName = DefaultColumn.VARIABLE_NAME.getDbName();
dbDataType = DefaultColumn.DATA_TYPE.getDbName();
dbArraySize = DefaultColumn.ARRAY_SIZE.getDbName();
dbBitLength = DefaultColumn.BIT_LENGTH.getDbName();
// Create a string containing the partial command for determining if the columns
// that are necessary to define a structure table are present in a table
String defStructCols = "(column_name = '" + dbVariableName + "' OR " + "column_name = '" + dbDataType + "' OR " + "column_name = '" + dbArraySize + "' OR " + "column_name = '" + dbBitLength + "' OR ";
List<String> rateAndEnums = new ArrayList<String>();
// Step through each table type definition
for (TypeDefinition typeDefn : ccddMain.getTableTypeHandler().getTypeDefinitions()) {
// Check if the type represents a structure
if (typeDefn.isStructure()) {
// Get this type's first rate and enumeration column names
dbRate = typeDefn.getDbColumnNameByInputType(InputDataType.RATE);
dbEnumeration = typeDefn.getDbColumnNameByInputType(InputDataType.ENUMERATION);
// Create the portion of the command comparing the column name to the first
// rate and enumeration column names
String rateAndEnum = "column_name = '" + dbRate + "' OR " + "column_name = '" + dbEnumeration + "') OR ";
// exist in the comparison
if (!rateAndEnums.contains(rateAndEnum)) {
// Add the rate and enumeration name pair so that it won't be added
// again
rateAndEnums.add(rateAndEnum);
// Create a string containing the partial command for determining if
// the columns that are necessary to define a structure table are
// present in a table
compareColumns += defStructCols + "column_name = '" + dbRate + "' OR " + "column_name = '" + dbEnumeration + "') OR ";
}
}
}
// Check if no structure table type exists
if (compareColumns.isEmpty()) {
// Get the default rate and enumeration column names
dbRate = DefaultColumn.RATE.getDbName();
dbEnumeration = DefaultColumn.ENUMERATION.getDbName();
// Create a string containing the partial command for determining if the
// columns that are necessary to define a structure table are present in a
// table
compareColumns = defStructCols + "column_name = '" + dbRate + "' OR " + "column_name = '" + dbEnumeration + "')";
} else // At least one structure table type exists
{
compareColumns = CcddUtilities.removeTrailer(compareColumns, " OR ");
}
// alphabetically by name or numerically by row index
for (String[] functionParm : functionParameters) {
// Create function to get the table name, data type, variable name, bit length,
// sample rate, and enumeration for all structure tables that contain at least
// one row, sorted by table name or index, and then by variable name. For
// arrays, only the members are retrieved; the array definitions are ignored
dbCommand.executeDbCommand(deleteFunction("get_table_members_by_" + functionParm[0]) + "CREATE FUNCTION get_table_members_by_" + functionParm[0] + "() RETURNS TABLE(tbl_name text, data_type " + "text, variable_name text, bit_length text, " + "rate text, enumeration text) AS $$ BEGIN " + "DECLARE row record; BEGIN DROP TABLE IF EXISTS " + TEMP_TABLES + "; CREATE TEMP TABLE " + TEMP_TABLES + " AS SELECT t.tablename AS real_name FROM " + "pg_tables AS t WHERE t.schemaname = 'public' " + "AND substr(t.tablename, 1, 2) != '" + INTERNAL_TABLE_PREFIX + "' ORDER BY real_name ASC; FOR row IN SELECT * FROM " + TEMP_TABLES + " LOOP IF EXISTS (SELECT * FROM " + "(SELECT COUNT(*) FROM information_schema.columns " + "WHERE table_name = row.real_name AND (" + compareColumns + ")) AS alias1 WHERE count = '" + DefaultColumn.getTypeRequiredColumnCount(TYPE_STRUCTURE) + "') THEN RETURN QUERY EXECUTE E'SELECT ''' || " + "row.real_name || '''::text, * FROM get_def_columns_by_" + functionParm[0] + "(''' || row.real_name || ''')'; END IF; " + "END LOOP; END; END; $$ LANGUAGE plpgsql; " + buildOwnerCommand(DatabaseObject.FUNCTION, "get_table_members_by_" + functionParm[0] + "()"), ccddMain.getMainFrame());
}
String rateCol = "";
String rateJoin = "";
// Check if any rate columns are defined
if (ccddMain.getRateParameterHandler().getNumRateColumns() != 0) {
// Step through each data stream
for (RateInformation rateInfo : ccddMain.getRateParameterHandler().getRateInformation()) {
// Get the rate column name (in its database form)
String rateColName = DefaultColumn.convertVisibleToDatabase(rateInfo.getRateName(), InputDataType.RATE, true);
// Add detection for the rate column. If the column doesn't exist in the
// table then a blank is returned for that column's rate value
rateCol += "CASE WHEN " + rateColName + "_exists THEN " + rateColName + "::text ELSE ''''::text END || '','' || ";
rateJoin += " CROSS JOIN (SELECT EXISTS (SELECT 1 FROM " + "pg_catalog.pg_attribute WHERE attrelid = ''' " + "|| name || '''::regclass AND attname = ''" + rateColName + "'' " + "AND NOT attisdropped AND attnum > 0) AS " + rateColName + "_exists) " + rateColName;
}
// Remove the trailing separator text
rateCol = CcddUtilities.removeTrailer(rateCol, " || '','' || ");
} else // No rate columns exist
{
// Return a blank for the rate column value
rateCol = "''''::text";
}
String enumCol = "";
String enumJoin = "";
// Get the unique structure enumeration column names
List<String> enumColumns = ccddMain.getTableTypeHandler().getStructEnumColNames(true);
// Check if any enumeration columns are defined
if (enumColumns.size() != 0) {
// Build the enumeration separator (triple backslashes) portion of the command
String enumSep = " || E''' || E'\\\\\\\\\\\\\\\\\\\\\\\\' || ''' || ";
// Step through each enumeration column name (in its database form)
for (String enumColName : enumColumns) {
// Add detection for the enumeration column. If the column doesn't exist in
// the table then a blank is returned for that column's enumeration value
enumCol += "CASE WHEN " + enumColName + "_exists THEN " + enumColName + "::text ELSE ''''::text END" + enumSep;
enumJoin += " CROSS JOIN (SELECT EXISTS (SELECT 1 FROM " + "pg_catalog.pg_attribute WHERE attrelid = ''' " + "|| name || '''::regclass AND attname = ''" + enumColName + "'' " + "AND NOT attisdropped AND attnum > 0) AS " + enumColName + "_exists) " + enumColName;
}
// Remove the trailing separator text
enumCol = CcddUtilities.removeTrailer(enumCol, enumSep);
} else // No enumeration columns exist
{
// Return a blank for the enumeration column value
enumCol += "''''::text";
}
// alphabetically by name or numerically by row index
for (String[] functionParm : functionParameters) {
// Create function to get the data type and variable name column data for the
// specified table, sorted by variable name. For arrays, only the members are
// retrieved; the array definitions are ignored
dbCommand.executeDbCommand(deleteFunction("get_def_columns_by_" + functionParm[0]) + "CREATE FUNCTION get_def_columns_by_" + functionParm[0] + "(name text) RETURNS TABLE(data_type " + "text, variable_name text, bit_length text, " + "rate text, enumeration text) AS $$ " + "BEGIN RETURN QUERY EXECUTE 'SELECT " + dbDataType + ", " + dbVariableName + ", " + dbBitLength + ", " + rateCol + ", " + enumCol + " FROM ' || name || '" + rateJoin + enumJoin + " WHERE " + dbArraySize + " = E'''' OR (array_size ~ E''^" + MACRO_IDENTIFIER + "'' AND (SELECT EXISTS (SELECT " + MacrosColumn.VALUE.getColumnName() + " FROM " + InternalTable.MACROS.getTableName() + " WHERE " + MacrosColumn.MACRO_NAME.getColumnName() + " = replace('''' || array_size || '''', ''" + MACRO_IDENTIFIER + "'', '''') AND " + MacrosColumn.VALUE.getColumnName() + " = ''''))) OR " + dbVariableName + " ~ E''^.+]'' ORDER BY " + functionParm[1] + " ASC'; END $$ LANGUAGE plpgsql; " + buildOwnerCommand(DatabaseObject.FUNCTION, "get_def_columns_by_" + functionParm[0] + "(name text)"), ccddMain.getMainFrame());
}
// Database function to search for all tables containing a data type column, and
// replace a target value with a new value
dbCommand.executeDbCommand(deleteFunction("update_data_type_names") + "CREATE FUNCTION update_data_type_names(oldType text, " + "newType text) RETURNS VOID AS $$ BEGIN DECLARE row " + "record; BEGIN DROP TABLE IF EXISTS " + TEMP_TABLES + "; CREATE TEMP TABLE " + TEMP_TABLES + " AS SELECT t.tablename AS real_name " + "FROM pg_tables AS t WHERE t.schemaname = 'public' " + "AND substr(t.tablename, 1, " + INTERNAL_TABLE_PREFIX.length() + ") != '" + INTERNAL_TABLE_PREFIX + "'; FOR row IN SELECT * FROM " + TEMP_TABLES + " LOOP IF EXISTS (SELECT 1 FROM " + "information_schema.columns WHERE table_name = " + "row.real_name AND column_name = '" + dbDataType + "') THEN EXECUTE E'UPDATE ' || row.real_name || E' SET " + dbDataType + " = ''' || newType || E''' WHERE " + dbDataType + " = ''' || oldType || E''''; END IF; " + "END LOOP; END; END; $$ LANGUAGE plpgsql; " + buildOwnerCommand(DatabaseObject.FUNCTION, "update_data_type_names(oldType text," + " newType text)"), ccddMain.getMainFrame());
// Inform the user that the database function creation succeeded
eventLog.logEvent(SUCCESS_MSG, "Database structure functions created");
} catch (SQLException se) {
// Inform the user that creating the database functions failed
eventLog.logFailEvent(ccddMain.getMainFrame(), "Cannot create structure functions in project database '" + activeDatabase + "' as user '" + activeUser + "'; cause '" + se.getMessage() + "'", "<html><b>Cannot create structure functions in project database '</b>" + activeDatabase + "<b>'");
errorFlag = true;
}
}
return errorFlag;
}
use of CCDD.CcddTableTypeHandler.TypeDefinition in project CCDD by nasa.
the class CcddDbTableCommandHandler method modifyTableType.
/**
********************************************************************************************
* Add, rename, or delete table type column names in the table definitions table and update the
* existing tables of the specified type
*
* @param typeName
* table type name to modify
*
* @param fieldInformation
* data field information list
*
* @param overwriteFields
* true if the content of existing fields should be overwritten by the default
* values; false to not overwrite existing values
*
* @param additions
* list of new columns to add to the tables. Each list item is an array containing:
* [0] column name (user), [1] column input type
*
* @param modifications
* list of name changes of existing columns in the tables. Each list item is an
* array containing: [0] original column name (user), [1] new column name (user),
* [2] column input type
*
* @param deletions
* list of columns to remove from the tables. Each list item is an array containing:
* [0] column name (user), [1] column input type
*
* @param columnOrderChange
* true if the table type's column order changed
*
* @param originalDefn
* reference to the table type definition prior to making any changes; null if this
* is a new table type
*
* @param editorDialog
* reference to the table type editor dialog
*
* @param editor
* reference to the table type editor where the change(s) occurred
********************************************************************************************
*/
protected void modifyTableType(String typeName, List<FieldInformation> fieldInformation, boolean overwriteFields, List<String[]> additions, List<String[]> modifications, List<String[]> deletions, boolean columnOrderChange, TypeDefinition originalDefn, CcddTableTypeEditorDialog editorDialog, CcddTableTypeEditorHandler editor) {
try {
boolean errorFlag = false;
String[] tableNames = null;
String names = "";
// Get the type definition based on the table type name
TypeDefinition typeDefn = tableTypeHandler.getTypeDefinition(typeName);
// Set the flags that indicates if the table type definition represents a structure
// prior to and after making the updates
boolean wasStructure = originalDefn != null ? originalDefn.isStructure() : false;
boolean isStructure = typeDefn.isStructure();
// Create the command to update the table definitions table
StringBuilder command = new StringBuilder(storeTableTypesInfoTableCommand());
// Check if this isn't a new table type
if (originalDefn != null) {
// Get an array containing all of the prototype tables of the specified type
String[] protoTableNames = queryTablesOfTypeList(typeName, editorDialog);
String columnOrder = "";
// Check if the column order changed or if any columns were added or deleted
if (columnOrderChange || !additions.isEmpty() || !deletions.isEmpty()) {
// Step through each column in the table type
for (int index = 0; index < typeDefn.getColumnNamesDatabase().length; index++) {
// Add the column index and a separator
columnOrder += index + ":";
}
// Remove the trailing separator
columnOrder = CcddUtilities.removeTrailer(columnOrder, ":");
}
// Create a list to store the names of all tables of the specified type
List<String> tableNamesList = new ArrayList<String>();
// Build a table tree with all prototype and instance tables
CcddTableTreeHandler tableTree = new CcddTableTreeHandler(ccddMain, TableTreeType.TABLES, editorDialog);
// Step through each prototype table of the specified type
for (String protoName : protoTableNames) {
// Create a list of table path arrays for instances of this prototype table
// name
tableNamesList.addAll(tableTree.getTableTreePathList(protoName));
// Get the database form of the table name
String dbTable = protoName.toLowerCase();
// Step through each addition
for (String[] add : additions) {
// Get the input data type, and the column name in database form
InputDataType inputDataType = InputDataType.getInputTypeByName(add[1]);
String dbName = DefaultColumn.convertVisibleToDatabase(add[0], inputDataType, isStructure);
// Append the add command
command.append("ALTER TABLE " + dbTable + " ADD COLUMN " + dbName + " text DEFAULT ''; ");
}
// Step through each modification
for (String[] mod : modifications) {
// Get the old and new column names in database form
String oldDbName = DefaultColumn.convertVisibleToDatabase(mod[0], InputDataType.getInputTypeByName(mod[2]), isStructure);
String newDbName = DefaultColumn.convertVisibleToDatabase(mod[1], InputDataType.getInputTypeByName(mod[3]), isStructure);
// Check if the database form of the name changed
if (!oldDbName.equals(newDbName)) {
// Append the modify command
command.append("ALTER TABLE " + dbTable + " RENAME COLUMN " + oldDbName + " TO " + newDbName + "; ");
}
}
// Step through each deletion
for (String[] del : deletions) {
// Get the input data type, and the column name in database form
InputDataType inputDataType = InputDataType.getInputTypeByName(del[1]);
String dbName = DefaultColumn.convertVisibleToDatabase(del[0], inputDataType, isStructure);
// Append the delete command
command.append("ALTER TABLE " + dbTable + " DROP COLUMN " + dbName + "; ");
}
// Check if the column order changed
if (columnOrder.length() != 0) {
// Replace the column order for all tables matching this table name. This
// resets the column order for all users
command.append("UPDATE " + InternalTable.ORDERS.getTableName() + " SET " + OrdersColumn.COLUMN_ORDER.getColumnName() + " = '" + columnOrder + "' WHERE " + OrdersColumn.TABLE_PATH.getColumnName() + " ~ E'^" + protoName + "(,|$)'; ");
}
}
// exist
if ((!modifications.isEmpty() || !deletions.isEmpty()) && protoTableNames.length != 0) {
// ////////////////////////////////////////////////////////////////////////////
// Build the sub-command required to detect references to tables of the
// affected type in the custom values, links, and telemetry scheduler tables
// ////////////////////////////////////////////////////////////////////////////
StringBuilder valuesCmd = new StringBuilder("");
StringBuilder linksCmd = new StringBuilder("");
StringBuilder tlmSchCmd = new StringBuilder("");
// Step through each prototype table of the specified type
for (String protoName : protoTableNames) {
// Build the table name comparison command for the custom values table
valuesCmd.append(ValuesColumn.TABLE_PATH.getColumnName() + " ~ E'[^,]+," + protoName + "\\.[^,]+,[^,]+$' OR ");
}
// Remove the trailing 'OR' and prepend an 'AND' to complete the custom values
// command
valuesCmd = CcddUtilities.removeTrailer(valuesCmd, " OR ");
valuesCmd.insert(0, " AND (");
valuesCmd.append(")");
// Check if the table type represents a structure
if (isStructure && wasStructure) {
// Step through each prototype table of the specified type
for (String protoName : protoTableNames) {
// Build the table name comparison command for the links and telemetry
// scheduler tables
linksCmd.append(LinksColumn.MEMBER.getColumnName() + " ~ E'(?:" + protoName + ",|[^,]+," + protoName + "\\.[^,]+,[^,]+$)' OR ");
tlmSchCmd.append(TlmSchedulerColumn.MEMBER.getColumnName() + " ~ E'(?:" + tlmSchSeparator + protoName + ",|[^,]+," + protoName + "\\.[^,]+,[^,]+$)' OR ");
}
// Remove the trailing 'OR' and prepend an 'AND' to complete the links and
// telemetry scheduler table commands
linksCmd = CcddUtilities.removeTrailer(linksCmd, " OR ");
linksCmd.insert(0, " AND (");
linksCmd.append(")");
tlmSchCmd = CcddUtilities.removeTrailer(tlmSchCmd, " OR ");
tlmSchCmd.insert(0, " AND (");
tlmSchCmd.append(")");
}
// doing so
if (!isStructure && wasStructure) {
boolean hasSharedRate = false;
// Step through each rate column in the table type definition
for (int column : originalDefn.getColumnIndicesByInputType(InputDataType.RATE)) {
// Get the rate column name (as seen by the user)
String rateName = originalDefn.getColumnNamesUser()[column];
// Check if this is the only table type using this rate column name
if (rateHandler.getRateInformationByRateName(rateName).getNumSharedTableTypes() == 1) {
// Delete all entries in the links and telemetry scheduler tables
// that reference this rate name
command.append(deleteAllLinkAndTlmRateRefs(rateName));
} else // The rate is shared with another table type
{
// Set the flag indicating the table type has a shared rate
hasSharedRate = true;
}
}
// the specific table references in these internal tables
if (hasSharedRate) {
// Remove all references to tables of the changed type in the links and
// telemetry scheduler tables
command.append(deleteLinkAndTlmRateRef(".+", linksCmd, tlmSchCmd));
}
}
// Step through each modification
for (String[] mod : modifications) {
// Check if the column name changed
if (!mod[0].equals(mod[1])) {
// Append the modify command for the custom values table
command.append("UPDATE " + InternalTable.VALUES.getTableName() + " SET " + ValuesColumn.COLUMN_NAME.getColumnName() + " = '" + mod[1] + "' WHERE " + ValuesColumn.COLUMN_NAME.getColumnName() + " = '" + mod[0] + "'" + valuesCmd + "; ");
}
// was a rate
if (isStructure && wasStructure && mod[2].equals(InputDataType.RATE.getInputName())) {
// column
if (!mod[3].equals(InputDataType.RATE.getInputName())) {
// Check if the rate name is used by another structure table type
if (rateHandler.getRateInformationByRateName(mod[0]).getNumSharedTableTypes() > 1) {
// Remove all references to tables of the changed type in the
// links and telemetry scheduler tables
command.append(deleteLinkAndTlmRateRef(mod[0], linksCmd, tlmSchCmd));
} else // The rate name is unique to this table type
{
// Remove all references to the original rate column name in
// the links and telemetry scheduler tables
command.append(deleteAllLinkAndTlmRateRefs(mod[0]));
}
} else // Check if the rate column name changed
if (!mod[0].equals(mod[1])) {
// table type
if (rateHandler.getRateInformationByRateName(mod[0]).getNumSharedTableTypes() > 1) {
// Remove all references to tables of the changed type in the
// links and telemetry scheduler tables
command.append(deleteLinkAndTlmRateRef(mod[0], linksCmd, tlmSchCmd));
} else // type (i.e., the rate name is unique to this table type)
if (rateHandler.getRateInformationByRateName(mod[1]) == null) {
// Append the modify command for the links and telemetry
// scheduler table
command.append("UPDATE " + InternalTable.LINKS.getTableName() + " SET " + LinksColumn.RATE_NAME.getColumnName() + " = '" + mod[1] + "' WHERE " + LinksColumn.RATE_NAME.getColumnName() + " = '" + mod[0] + "'; UPDATE " + InternalTable.TLM_SCHEDULER.getTableName() + " SET " + TlmSchedulerColumn.RATE_NAME.getColumnName() + " = '" + mod[1] + "' WHERE " + TlmSchedulerColumn.RATE_NAME.getColumnName() + " = '" + mod[0] + "'; ");
} else // The new rate name is already in use
{
// Remove all references to the original rate column name in
// the links and telemetry scheduler tables
command.append(deleteAllLinkAndTlmRateRefs(mod[0]));
}
}
}
}
// Step through each deletion
for (String[] del : deletions) {
// Append the delete command for the custom values table
command.append("DELETE FROM " + InternalTable.VALUES.getTableName() + " WHERE " + ValuesColumn.COLUMN_NAME.getColumnName() + " = '" + del[0] + "'" + valuesCmd + "; ");
// deleted
if (isStructure && wasStructure && del[1].equals(InputDataType.RATE.getInputName())) {
// Check if the rate name is used by another structure table type
if (rateHandler.getRateInformationByRateName(del[0]).getNumSharedTableTypes() > 1) {
// Remove all references to tables of the changed type in the links
// and telemetry scheduler tables
command.append(deleteLinkAndTlmRateRef(del[0], linksCmd, tlmSchCmd));
} else // The rate name is unique to this table type
{
// Remove all references to the original rate column name in the
// links and telemetry/scheduler tables
command.append(deleteAllLinkAndTlmRateRefs(del[0]));
}
}
}
}
// Create a field handler to store the data field information
CcddFieldHandler fieldHandler = new CcddFieldHandler(ccddMain, null, editorDialog);
// Step through each table of the specified type
for (String tableName : tableNamesList) {
// Set the flag to indicate if the table is a root structure
boolean isRootStruct = isStructure && rootStructures.contains(tableName);
// Get the existing data fields for this table
fieldHandler.buildFieldInformation(tableName);
// Get the number of separator and line break fields
int numSep = fieldHandler.getFieldTypeCount(InputDataType.SEPARATOR);
int numBrk = fieldHandler.getFieldTypeCount(InputDataType.BREAK);
int sepCount = 0;
int brkCount = 0;
boolean isChanges = false;
// Step through the default data fields for this table type
for (FieldInformation fieldInfo : fieldInformation) {
// Check if this is a separator
if (fieldInfo.getInputType().equals(InputDataType.SEPARATOR)) {
// Increment the separator counter
sepCount++;
} else // Check if this is a line break
if (fieldInfo.getInputType().equals(InputDataType.BREAK)) {
// Increment the line break counter
brkCount++;
}
// Check if the data field meets the criteria of a new field for this table
if ((// The table doesn't have this data field
(fieldHandler.getFieldInformationByName(tableName, fieldInfo.getFieldName()) == null)) && // this table
(!tableName.contains(".") || fieldHandler.isFieldApplicable(tableName, fieldInfo.getApplicabilityType().getApplicabilityName(), isRootStruct)) || // separator in the type editor exceeds the number already in the table
(fieldInfo.getInputType().equals(InputDataType.SEPARATOR) && sepCount > numSep) || (fieldInfo.getInputType().equals(InputDataType.BREAK) && brkCount > numBrk)) {
// Add the data field to the table and set the flag indicating a change
// has been made
fieldHandler.addField(tableName, fieldInfo.getFieldName(), fieldInfo.getDescription(), fieldInfo.getSize(), fieldInfo.getInputType().getInputName(), fieldInfo.isRequired(), fieldInfo.getApplicabilityType().getApplicabilityName(), fieldInfo.getValue());
isChanges = true;
} else // overwritten, and if the field value(s) changed
if (overwriteFields && fieldHandler.updateField(new FieldInformation(tableName, fieldInfo.getFieldName(), fieldInfo.getDescription(), fieldInfo.getSize(), fieldInfo.getInputType().getInputName(), fieldInfo.isRequired(), fieldInfo.getApplicabilityType().getApplicabilityName(), fieldInfo.getValue()))) {
// Set the flag indicating a change has been made
isChanges = true;
}
}
// Check if any fields were added
if (isChanges) {
// Create the command to modify the table's data field entries
command.append(modifyFieldsCommand(tableName, fieldHandler.getFieldInformation()));
}
}
// Convert the list of modified tables names to an array
tableNames = tableNamesList.toArray(new String[0]);
// Check if any table of this type exists
if (tableNames.length != 0) {
// Convert the array of tables names into a single string and shorten it if too
// long
names = " and table(s) '</b>" + getShortenedTableNames(tableNames) + "<b>'";
}
// Build the command to update the data fields table and the telemetry scheduler
// table comment (rate parameters)
command.append(modifyFieldsCommand(CcddFieldHandler.getFieldTypeName(typeName), fieldInformation));
}
try {
// Execute the command to change the table type and any table's of this type
dbCommand.executeDbCommand(command.toString(), editorDialog);
// Check if the type changed from being a structure to not being a structure
if (!isStructure && wasStructure) {
// Update the list of root structure tables
rootStructures = getRootStructures(editorDialog);
}
// Log that updating the table type succeeded
eventLog.logEvent(SUCCESS_MSG, "Table type '" + typeName + "'" + CcddUtilities.removeHTMLTags(names) + " updated");
} catch (SQLException se) {
// Inform the user that updating the tables failed
eventLog.logFailEvent(editorDialog, "Cannot update table type '" + typeName + "'" + CcddUtilities.removeHTMLTags(names) + "; cause '" + se.getMessage() + "'", "<html><b>Cannot update table type '</b>" + typeName + "<b>'" + names);
errorFlag = true;
}
// structure
if (!errorFlag && (isStructure || wasStructure)) {
// Step through each column addition
for (String[] add : additions) {
// Check if the column is a rate column
if (add[1].equals(InputDataType.RATE.getInputName())) {
// Add the rate column to the rate information
rateHandler.addRateInformation(add[0]);
}
}
// Step through each column modification
for (String[] mod : modifications) {
// Check if the column changed from a rate column to not being a rate column
if (mod[2].equals(InputDataType.RATE.getInputName()) && !mod[3].equals(InputDataType.RATE.getInputName())) {
// Delete the rate column from the rate information
rateHandler.deleteRateInformation(mod[2]);
} else // Check if the column changed from not being a rate column to a rate column
if (!mod[2].equals(InputDataType.RATE.getInputName()) && mod[3].equals(InputDataType.RATE.getInputName())) {
// Add the rate column to the rate information
rateHandler.addRateInformation(mod[3]);
} else // changed)
if (mod[3].equals(InputDataType.RATE.getInputName())) {
// Rename (or add if the rate column is shared with another table type) the
// rate column in the rate information
rateHandler.renameRateInformation(mod[0], mod[1]);
}
}
// Step through each column deletion
for (String[] del : deletions) {
// Check if the column is a rate column
if (del[1].equals(InputDataType.RATE.getInputName())) {
// Delete the rate column from the rate information
rateHandler.deleteRateInformation(del[0]);
}
}
// Update the rate column information and store it in the project database
rateHandler.setRateInformation();
storeRateParameters(editorDialog);
// Update the database functions that collect structure table members and
// structure-defining column data
dbControl.createStructureColumnFunctions();
}
// Perform the type modification clean-up steps
editorDialog.doTypeModificationComplete(errorFlag, editor, tableNames);
} catch (Exception e) {
// Display a dialog providing details on the unanticipated error
CcddUtilities.displayException(e, editorDialog);
}
}
use of CCDD.CcddTableTypeHandler.TypeDefinition in project CCDD by nasa.
the class CcddFileIOHandler method createTablesFromDefinitions.
/**
********************************************************************************************
* Create one or more data tables from the supplied table definitions
*
* @param tableDefinitions
* list of table definitions for the table(s) to create
*
* @param replaceExisting
* true to replace a table that already exists in the database
*
* @param parent
* GUI component calling this method
*
* @throws CCDDException
* If the table path name is invalid or the table cannot be created from the table
* definition
********************************************************************************************
*/
private void createTablesFromDefinitions(List<TableDefinition> tableDefinitions, boolean replaceExisting, final Component parent) throws CCDDException {
cancelImport = false;
boolean prototypesOnly = true;
List<String> skippedTables = new ArrayList<String>();
// Get the list of all tables, including the paths for child structure tables
CcddTableTreeHandler tableTree = new CcddTableTreeHandler(ccddMain, TableTreeType.TABLES, parent);
List<String> allTables = tableTree.getTableTreePathList(null);
// tables
for (int loop = 1; loop <= 2 && !cancelImport; loop++) {
// Step through each table definition
for (TableDefinition tableDefn : tableDefinitions) {
// Check if the table path/name format is valid
if (!tableDefn.getName().matches(InputDataType.VARIABLE.getInputMatch() + "(?:$|(?:," + InputDataType.VARIABLE.getInputMatch() + "\\." + InputDataType.VARIABLE.getInputMatch() + ")+)")) {
// Inform the user the table path/name isn't in the correct format
throw new CCDDException("Invalid table path/name '</b>" + tableDefn.getName() + "<b>' format");
}
// Check if the table import was canceled by the user
if (cancelImport) {
// Add the table to the list of those skipped
skippedTables.add(tableDefn.getName());
continue;
}
// or if this is a child table and this is the second pass
if (!tableDefn.getData().isEmpty() && (!tableDefn.getName().contains(",") != !prototypesOnly)) {
// Get the table type definition for this table
TypeDefinition typeDefn = tableTypeHandler.getTypeDefinition(tableDefn.getTypeName());
// Get the number of table columns
int numColumns = typeDefn.getColumnCountVisible();
// Create the table information for the new table
TableInformation tableInfo = new TableInformation(tableDefn.getTypeName(), tableDefn.getName(), new String[0][0], tableTypeHandler.getDefaultColumnOrder(tableDefn.getTypeName()), tableDefn.getDescription(), !tableDefn.getName().contains("."), tableDefn.getDataFields().toArray(new String[0][0]));
// Check if the new table is not a prototype
if (!tableInfo.isPrototype()) {
// Break the path into the individual structure variable references
String[] ancestors = tableInfo.getTablePath().split(",");
// table
for (int index = ancestors.length - 1; index >= 0 && !cancelImport; index--) {
// Split the ancestor into the data type (i.e., structure name) and
// variable name
String[] typeAndVar = ancestors[index].split("\\.");
// Check if the ancestor prototype table doesn't exist
if (!dbTable.isTableExists(typeAndVar[0].toLowerCase(), ccddMain.getMainFrame())) {
// Create the table information for the new prototype table
TableInformation ancestorInfo = new TableInformation(tableDefn.getTypeName(), typeAndVar[0], new String[0][0], tableTypeHandler.getDefaultColumnOrder(tableDefn.getTypeName()), "", true, tableDefn.getDataFields().toArray(new String[0][0]));
// Check if this is the child table and not one of its ancestors
if (index == ancestors.length - 1) {
// Create a list to store a copy of the cell data
List<String> protoData = new ArrayList<String>(tableDefn.getData());
// Step through each row of the cell data
for (int cellIndex = 0; cellIndex < tableDefn.getData().size(); cellIndex += numColumns) {
// Step through each column in the row
for (int colIndex = 0; colIndex < numColumns; colIndex++) {
// type
if (!DefaultColumn.isTypeRequiredColumn((typeDefn.isStructure() ? TYPE_STRUCTURE : (typeDefn.isCommand() ? TYPE_COMMAND : TYPE_OTHER)), typeDefn.getInputTypesVisible()[colIndex])) {
// Replace the non-required column value with a
// blank. The child's non-required values are
// therefore not inherited from the prototype
protoData.set(cellIndex + colIndex, "");
}
}
}
// the protected column data
if (!createImportedTable(ancestorInfo, protoData, numColumns, replaceExisting, "Cannot create prototype '" + ancestorInfo.getPrototypeName() + "' of child table", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(ancestorInfo.getTablePath());
}
} else // This is an ancestor of the child table
{
// Split the ancestor into the data type (i.e., structure name)
// and variable name
typeAndVar = ancestors[index + 1].split("\\.|$", -1);
// Add the variable reference to the new table
String[] rowData = new String[typeDefn.getColumnCountVisible()];
Arrays.fill(rowData, "");
rowData[typeDefn.getVisibleColumnIndexByUserName(typeDefn.getColumnNameByInputType(InputDataType.VARIABLE))] = typeAndVar[1];
rowData[typeDefn.getVisibleColumnIndexByUserName(typeDefn.getColumnNameByInputType(InputDataType.PRIM_AND_STRUCT))] = typeAndVar[0];
// the protected column data
if (!createImportedTable(ancestorInfo, Arrays.asList(rowData), numColumns, replaceExisting, "Cannot create prototype '" + ancestorInfo.getPrototypeName() + "' of child table's ancestor", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(ancestorInfo.getTablePath());
}
}
}
}
// Load the table's prototype data from the database and copy the
// prototype's data to the table
TableInformation protoInfo = dbTable.loadTableData(tableInfo.getPrototypeName(), false, false, false, ccddMain.getMainFrame());
tableInfo.setData(protoInfo.getData());
}
// Create a table from the imported information
if (!createImportedTable(tableInfo, tableDefn.getData(), numColumns, replaceExisting, "Cannot create prototype '" + tableInfo.getPrototypeName() + "'", allTables, parent)) {
// Add the skipped table to the list
skippedTables.add(tableInfo.getTablePath());
}
}
}
prototypesOnly = false;
}
// Check if any tables were skipped
if (!skippedTables.isEmpty()) {
// Inform the user that one or more tables were not imported
new CcddDialogHandler().showMessageDialog(parent, "<html><b>Table(s) not imported<br>'</b>" + dbTable.getShortenedTableNames(skippedTables.toArray(new String[0])) + "<b>';<br>table already exists", "Import Warning", JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
}
// Store the table types
dbTable.storeInformationTable(InternalTable.TABLE_TYPES, null, null, parent);
// Store the data types
dbTable.storeInformationTable(InternalTable.DATA_TYPES, CcddUtilities.removeArrayListColumn(dataTypeHandler.getDataTypeData(), DataTypesColumn.OID.ordinal()), null, parent);
// Check if any macros are defined
if (!macroHandler.getMacroData().isEmpty()) {
// Store the macros in the database
dbTable.storeInformationTable(InternalTable.MACROS, CcddUtilities.removeArrayListColumn(macroHandler.getMacroData(), MacrosColumn.OID.ordinal()), null, parent);
}
// Check if any reserved message IDs are defined
if (!rsvMsgIDHandler.getReservedMsgIDData().isEmpty()) {
// Store the reserved message IDs in the database
dbTable.storeInformationTable(InternalTable.RESERVED_MSG_IDS, CcddUtilities.removeArrayListColumn(rsvMsgIDHandler.getReservedMsgIDData(), ReservedMsgIDsColumn.OID.ordinal()), null, parent);
}
}
Aggregations