This commit is contained in:
Julio Cesar Laura Avendaño
2019-07-26 10:01:39 -04:00
parent b2f81d7873
commit 3c9c63429e
8 changed files with 271 additions and 175 deletions

View File

@@ -393,19 +393,20 @@ class database extends database_base
} }
/** /**
* generate a sentence to add indexes or primary keys * Generate a sentence to add indexes or primary keys
* *
* @param string $table table name * @param string $table table name
* @param string $indexName index name * @param string $indexName index name
* @param array $keys array of keys * @param array $keys array of keys
* @param string $indexType the index type
*
* @return string sql sentence * @return string sql sentence
* @throws Exception * @throws Exception
*/ */
public function generateAddKeysSQL($table, $indexName, $keys) public function generateAddKeysSQL($table, $indexName, $keys, $indexType = 'INDEX')
{ {
try { try {
$indexType = 'INDEX';
if ($indexName === 'primaryKey' || $indexName === 'PRIMARY') { if ($indexName === 'primaryKey' || $indexName === 'PRIMARY') {
$indexType = 'PRIMARY'; $indexType = 'PRIMARY';
$indexName = 'KEY'; $indexName = 'KEY';
@@ -1037,10 +1038,11 @@ class database extends database_base
* @param string $tableName * @param string $tableName
* @param array $columns * @param array $columns
* @param array $indexes * @param array $indexes
* @param array $fulltextIndexes
* *
* @return string * @return string
*/ */
public function generateAddColumnsSql($tableName, $columns, $indexes = []) public function generateAddColumnsSql($tableName, $columns, $indexes = [], $fulltextIndexes = [])
{ {
$indexesAlreadyAdded = []; $indexesAlreadyAdded = [];
$sql = 'ALTER TABLE ' . $this->sQuoteCharacter . $tableName . $this->sQuoteCharacter . ' '; $sql = 'ALTER TABLE ' . $this->sQuoteCharacter . $tableName . $this->sQuoteCharacter . ' ';
@@ -1080,6 +1082,7 @@ class database extends database_base
} }
$sql .= ', '; $sql .= ', ';
} }
// Add the normal indexes if are not "primaryKeys" already added
foreach ($indexes as $indexName => $indexColumns) { foreach ($indexes as $indexName => $indexColumns) {
$indexType = 'INDEX'; $indexType = 'INDEX';
if ($indexName === 'primaryKey' || $indexName === 'PRIMARY') { if ($indexName === 'primaryKey' || $indexName === 'PRIMARY') {
@@ -1097,6 +1100,15 @@ class database extends database_base
$sql = substr($sql, 0, -2); $sql = substr($sql, 0, -2);
$sql .= '), '; $sql .= '), ';
} }
// Add the "fulltext" indexes always
foreach ($fulltextIndexes as $indexName => $indexColumns) {
$sql .= 'ADD FULLTEXT ' . $indexName . ' (';
foreach ($indexColumns as $column) {
$sql .= $this->sQuoteCharacter . $column . $this->sQuoteCharacter . ', ';
}
$sql = substr($sql, 0, -2);
$sql .= '), ';
}
$sql = rtrim($sql, ', '); $sql = rtrim($sql, ', ');
return $sql; return $sql;

View File

@@ -147,11 +147,13 @@ function run_upgrade($parameters, $args)
// The previous actions should be executed only the first time // The previous actions should be executed only the first time
$mainThread = false; $mainThread = false;
if ($numberOfWorkspaces === 1) {
// Displaying information of the unique workspace to upgrade
CLI::logging("UPGRADING DATABASE AND FILES OF WORKSPACE '{$workspace->name}' (1/1)\n");
}
} }
if ($numberOfWorkspaces === 1) { if ($numberOfWorkspaces === 1) {
// Displaying information of the current workspace to upgrade
CLI::logging("UPGRADING DATABASE AND FILES OF WORKSPACE '{$workspace->name}' ($countWorkspace/$numberOfWorkspaces)\n");
// Build parameters // Build parameters
$arrayOptTranslation = [ $arrayOptTranslation = [
'updateXml' => $updateXmlForms, 'updateXml' => $updateXmlForms,
@@ -165,6 +167,9 @@ function run_upgrade($parameters, $args)
$workspace->upgrade($workspace->name, SYS_LANG, $arrayOptTranslation, $optionMigrateHistoryData); $workspace->upgrade($workspace->name, SYS_LANG, $arrayOptTranslation, $optionMigrateHistoryData);
$workspace->close(); $workspace->close();
} else { } else {
// Displaying information of the current workspace to upgrade
CLI::logging("UPGRADING DATABASE AND FILES OF WORKSPACE '{$workspace->name}' ($countWorkspace/$numberOfWorkspaces)\n");
// Build arguments // Build arguments
$args = '--child'; $args = '--child';
$args .= $updateXmlForms ? '' : ' --no-xml'; $args .= $updateXmlForms ? '' : ' --no-xml';

View File

@@ -566,15 +566,14 @@ function run_database_import($args, $opts)
* Check if we need to execute an external program for each workspace * Check if we need to execute an external program for each workspace
* If we apply the command for all workspaces we will need to execute one by one by redefining the constants * If we apply the command for all workspaces we will need to execute one by one by redefining the constants
* @param string $args, workspaceName that we need to apply the database-upgrade * @param string $args, workspaceName that we need to apply the database-upgrade
* @param string $opts
* *
* @return void * @return void
*/ */
function run_database_upgrade($args, $opts) function run_database_upgrade($args)
{ {
//Check if the command is executed by a specific workspace //Check if the command is executed by a specific workspace
if (count($args) === 1) { if (count($args) === 1) {
database_upgrade('upgrade', $args); database_upgrade($args);
} else { } else {
$workspaces = get_workspaces_from_args($args); $workspaces = get_workspaces_from_args($args);
foreach ($workspaces as $workspace) { foreach ($workspaces as $workspace) {
@@ -583,11 +582,6 @@ function run_database_upgrade($args, $opts)
} }
} }
function run_database_check($args, $opts)
{
database_upgrade("check", $args);
}
function run_migrate_new_cases_lists($args, $opts) function run_migrate_new_cases_lists($args, $opts)
{ {
migrate_new_cases_lists("migrate", $args, $opts); migrate_new_cases_lists("migrate", $args, $opts);
@@ -605,44 +599,32 @@ function run_migrate_list_unassigned($args, $opts)
/** /**
* This function is executed only by one workspace * This function is executed only by one workspace
* @param string $command, the specific actions must be: upgrade|check
* @param array $args, workspaceName for to apply the database-upgrade * @param array $args, workspaceName for to apply the database-upgrade
* *
* @return void * @return void
*/ */
function database_upgrade($command, $args) function database_upgrade($args)
{ {
// Sanitize parameters sent
$filter = new InputFilter(); $filter = new InputFilter();
$command = $filter->xssFilterHard($command);
$args = $filter->xssFilterHard($args); $args = $filter->xssFilterHard($args);
// Load the attributes for the workspace // Load the attributes for the workspace
$workspaces = get_workspaces_from_args($args); $workspaces = get_workspaces_from_args($args);
$checkOnly = (strcmp($command, "check") == 0);
//Loop, read all the attributes related to the one workspace
$wsName = $workspaces[key($workspaces)]->name;
Bootstrap::setConstantsRelatedWs($wsName);
if ($checkOnly) {
print_r("Checking database in " . pakeColor::colorize($wsName, "INFO") . "\n");
} else {
print_r("Upgrading database in " . pakeColor::colorize($wsName, "INFO") . "\n");
}
// Get the name of the first workspace
$wsName = $workspaces[key($workspaces)]->name;
// Initialize workspace values
Bootstrap::setConstantsRelatedWs($wsName);
// Print a informative message
print_r("Upgrading database in " . pakeColor::colorize($wsName, "INFO") . "\n");
// Loop to update the databases of all workspaces
foreach ($workspaces as $workspace) { foreach ($workspaces as $workspace) {
try { try {
$changes = $workspace->upgradeDatabase($checkOnly); $workspace->upgradeDatabase();
if ($changes != false) {
if ($checkOnly) {
echo "> " . pakeColor::colorize("Run upgrade", "INFO") . "\n";
echo " Tables (add = " . count($changes['tablesToAdd']);
echo ", alter = " . count($changes['tablesToAlter']) . ") ";
echo "- Indexes (add = " . count($changes['tablesWithNewIndex']) . "";
echo ", alter = " . count($changes['tablesToAlterIndex']) . ")\n";
} else {
echo "-> Schema fixed\n";
}
} else {
echo "> OK\n";
}
} catch (Exception $e) { } catch (Exception $e) {
G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n"); G::outRes("> Error: " . CLI::error($e->getMessage()) . "\n");
} }

View File

@@ -252,7 +252,7 @@ class WorkspaceTools
CLI::logging("* Start updating database schema...\n"); CLI::logging("* Start updating database schema...\n");
$start = microtime(true); $start = microtime(true);
$this->upgradeDatabase(); $this->upgradeDatabase(false);
CLI::logging("* End updating database schema...(Completed on " . (microtime(true) - $start) . " seconds)\n"); CLI::logging("* End updating database schema...(Completed on " . (microtime(true) - $start) . " seconds)\n");
CLI::logging("* Start updating translations...\n"); CLI::logging("* Start updating translations...\n");
@@ -807,16 +807,17 @@ class WorkspaceTools
$oldSchema[$table][$field['Field']]['Default'] = $field['Default']; $oldSchema[$table][$field['Field']]['Default'] = $field['Default'];
} }
//get indexes of each table SHOW INDEX FROM `ADDITIONAL_TABLES`; -- WHERE Key_name <> 'PRIMARY' // Get indexes of each table SHOW INDEX FROM `ADDITIONAL_TABLES`;
$description = $database->executeQuery($database->generateTableIndexSQL($table)); $description = $database->executeQuery($database->generateTableIndexSQL($table));
foreach ($description as $field) { foreach ($description as $field) {
if (!isset($oldSchema[$table]['INDEXES'])) { $type = $field['Index_type'] != 'FULLTEXT' ? 'INDEXES' : 'FULLTEXT';
$oldSchema[$table]['INDEXES'] = []; if (!isset($oldSchema[$table][$type])) {
$oldSchema[$table][$type] = [];
} }
if (!isset($oldSchema[$table]['INDEXES'][$field['Key_name']])) { if (!isset($oldSchema[$table][$type][$field['Key_name']])) {
$oldSchema[$table]['INDEXES'][$field['Key_name']] = []; $oldSchema[$table][$type][$field['Key_name']] = [];
} }
$oldSchema[$table]['INDEXES'][$field['Key_name']][] = $field['Column_name']; $oldSchema[$table][$type][$field['Key_name']][] = $field['Column_name'];
} }
} }
@@ -1050,8 +1051,10 @@ class WorkspaceTools
/** /**
* Upgrade the workspace database to the latest system schema * Upgrade the workspace database to the latest system schema
*
* @param bool $includeIndexes
*/ */
public function upgradeDatabase() public function upgradeDatabase($includeIndexes = true)
{ {
$this->initPropel(true); $this->initPropel(true);
P11835::$dbAdapter = $this->dbAdapter; P11835::$dbAdapter = $this->dbAdapter;
@@ -1059,7 +1062,7 @@ class WorkspaceTools
$systemSchema = System::getSystemSchema($this->dbAdapter); $systemSchema = System::getSystemSchema($this->dbAdapter);
$systemSchemaRbac = System::getSystemSchemaRbac($this->dbAdapter);// Get the RBAC Schema $systemSchemaRbac = System::getSystemSchemaRbac($this->dbAdapter);// Get the RBAC Schema
$this->registerSystemTables(array_merge($systemSchema, $systemSchemaRbac)); $this->registerSystemTables(array_merge($systemSchema, $systemSchemaRbac));
$this->upgradeSchema($systemSchema, false, false, false); // Without add indexes $this->upgradeSchema($systemSchema, false, false, $includeIndexes);
$this->upgradeSchema($systemSchemaRbac, false, true); // Perform upgrade to RBAC $this->upgradeSchema($systemSchemaRbac, false, true); // Perform upgrade to RBAC
$this->upgradeData(); $this->upgradeData();
$this->checkRbacPermissions();//check or add new permissions $this->checkRbacPermissions();//check or add new permissions
@@ -1195,7 +1198,9 @@ class WorkspaceTools
$changes = System::compareSchema($workspaceSchema, $schema); $changes = System::compareSchema($workspaceSchema, $schema);
$changed = (count($changes['tablesToAdd']) > 0 || count($changes['tablesToAlter']) > 0 || count($changes['tablesWithNewIndex']) > 0 || count($changes['tablesToAlterIndex']) > 0); $changed = (count($changes['tablesToAdd']) > 0 || count($changes['tablesToAlter']) > 0 ||
count($changes['tablesWithNewIndex']) > 0 || count($changes['tablesToAlterIndex']) > 0 ||
count($changes['tablesWithNewFulltext']) > 0 || count($changes['tablesToAlterFulltext']) > 0);
if ($checkOnly || (!$changed)) { if ($checkOnly || (!$changed)) {
if ($changed) { if ($changed) {
@@ -1229,6 +1234,7 @@ class WorkspaceTools
$tablesToAddColumns = []; $tablesToAddColumns = [];
// Drop or change columns
foreach ($changes['tablesToAlter'] as $tableName => $actions) { foreach ($changes['tablesToAlter'] as $tableName => $actions) {
foreach ($actions as $action => $actionData) { foreach ($actions as $action => $actionData) {
if ($action == 'ADD') { if ($action == 'ADD') {
@@ -1255,17 +1261,27 @@ class WorkspaceTools
} }
} }
// Add columns
if (!empty($tablesToAddColumns)) { if (!empty($tablesToAddColumns)) {
$upgradeQueries = []; $upgradeQueries = [];
foreach ($tablesToAddColumns as $tableName => $tableColumn) { foreach ($tablesToAddColumns as $tableName => $tableColumn) {
// Normal indexes to add
$indexes = []; $indexes = [];
if (!empty($changes['tablesWithNewIndex'][$tableName]) && $includeIndexes) { if (!empty($changes['tablesWithNewIndex'][$tableName]) && $includeIndexes) {
$indexes = $changes['tablesWithNewIndex'][$tableName]; $indexes = $changes['tablesWithNewIndex'][$tableName];
unset($changes['tablesWithNewIndex'][$tableName]); unset($changes['tablesWithNewIndex'][$tableName]);
} }
// "fulltext" indexes to add
$fulltextIndexes = [];
if (!empty($changes['tablesWithNewFulltext'][$tableName]) && $includeIndexes) {
$fulltextIndexes = $changes['tablesWithNewFulltext'][$tableName];
unset($changes['tablesWithNewFulltext'][$tableName]);
}
// Instantiate the class to execute the query in background // Instantiate the class to execute the query in background
$upgradeQueries[] = new RunProcessUpgradeQuery($this->name, $database->generateAddColumnsSql($tableName, $tableColumn, $indexes), $rbac); $upgradeQueries[] = new RunProcessUpgradeQuery($this->name, $database->generateAddColumnsSql($tableName,
$tableColumn, $indexes, $fulltextIndexes), $rbac);
} }
// Run queries in multiple threads // Run queries in multiple threads
@@ -1282,14 +1298,24 @@ class WorkspaceTools
} }
} }
if (!empty($changes['tablesWithNewIndex']) && $includeIndexes) { // Add indexes
CLI::logging("-> " . count($changes['tablesWithNewIndex']) . " tables with indexes to add\n"); if ((!empty($changes['tablesWithNewIndex']) || !empty($changes['tablesWithNewFulltext'])) && $includeIndexes) {
CLI::logging("-> " . (count($changes['tablesWithNewIndex']) + count($changes['tablesWithNewFulltext'])) .
" tables with indexes to add\n");
$upgradeQueries = []; $upgradeQueries = [];
// Add normal indexes
foreach ($changes['tablesWithNewIndex'] as $tableName => $indexes) { foreach ($changes['tablesWithNewIndex'] as $tableName => $indexes) {
// Instantiate the class to execute the query in background // Instantiate the class to execute the query in background
$upgradeQueries[] = new RunProcessUpgradeQuery($this->name, $database->generateAddColumnsSql($tableName, [], $indexes), $rbac); $upgradeQueries[] = new RunProcessUpgradeQuery($this->name, $database->generateAddColumnsSql($tableName, [], $indexes), $rbac);
} }
// Add "fulltext" indexes
foreach ($changes['tablesWithNewFulltext'] as $tableName => $fulltextIndexes) {
// Instantiate the class to execute the query in background
$upgradeQueries[] = new RunProcessUpgradeQuery($this->name, $database->generateAddColumnsSql($tableName, [], [], $fulltextIndexes), $rbac);
}
// Run queries in multiple threads // Run queries in multiple threads
$processesManager = new ProcessesManager($upgradeQueries); $processesManager = new ProcessesManager($upgradeQueries);
$processesManager->run(); $processesManager->run();
@@ -1304,16 +1330,30 @@ class WorkspaceTools
} }
} }
if (!empty($changes['tablesToAlterIndex']) && $includeIndexes) { // Change indexes
CLI::logging("-> " . count($changes['tablesToAlterIndex']) . " tables with indexes to alter\n"); if ((!empty($changes['tablesToAlterIndex']) || !empty($changes['tablesToAlterFulltext'])) && $includeIndexes) {
CLI::logging("-> " . (count($changes['tablesToAlterIndex']) + count($changes['tablesToAlterFulltext'])) .
" tables with indexes to alter\n");
// Change normal indexes
foreach ($changes['tablesToAlterIndex'] as $tableName => $indexes) { foreach ($changes['tablesToAlterIndex'] as $tableName => $indexes) {
foreach ($indexes as $indexName => $indexFields) { foreach ($indexes as $indexName => $indexFields) {
$database->executeQuery($database->generateDropKeySQL($tableName, $indexName)); $database->executeQuery($database->generateDropKeySQL($tableName, $indexName));
$database->executeQuery($database->generateAddKeysSQL($tableName, $indexName, $indexFields)); $database->executeQuery($database->generateAddKeysSQL($tableName, $indexName, $indexFields));
} }
} }
// Change "fulltext" indexes
foreach ($changes['tablesToAlterFulltext'] as $tableName => $fulltextIndexes) {
foreach ($fulltextIndexes as $indexName => $indexFields) {
$database->executeQuery($database->generateDropKeySQL($tableName, $indexName));
$database->executeQuery($database->generateAddKeysSQL($tableName, $indexName, $indexFields, 'FULLTEXT'));
}
}
} }
// Ending the schema update
CLI::logging("-> Schema Updated\n");
$this->closeDatabase(); $this->closeDatabase();
return true; return true;
} }
@@ -2064,7 +2104,7 @@ class WorkspaceTools
// Upgrade the database schema and data // Upgrade the database schema and data
CLI::logging("* Start updating database schema...\n"); CLI::logging("* Start updating database schema...\n");
$start = microtime(true); $start = microtime(true);
$workspace->upgradeDatabase(); $workspace->upgradeDatabase(false);
CLI::logging("* End updating database schema...(Completed on " . (microtime(true) - $start) . " seconds)\n"); CLI::logging("* End updating database schema...(Completed on " . (microtime(true) - $start) . " seconds)\n");
CLI::logging("* Start checking MAFE requirements...\n"); CLI::logging("* Start checking MAFE requirements...\n");

View File

@@ -94,6 +94,15 @@
<parameter name="Seq_in_index" value="1"/> <parameter name="Seq_in_index" value="1"/>
</vendor> </vendor>
</index> </index>
<fulltext name="indexAppTitle">
<index-column name="APP_TITLE"/>
<vendor type="mysql">
<parameter name="Table" value="APPLICATION"/>
<parameter name="Non_unique" value="1"/>
<parameter name="Key_name" value="indexAppTitle"/>
<parameter name="Seq_in_index" value="1"/>
</vendor>
</fulltext>
<unique name="INDEX_APP_NUMBER"> <unique name="INDEX_APP_NUMBER">
<unique-column name="APP_NUMBER"/> <unique-column name="APP_NUMBER"/>
</unique> </unique>

View File

@@ -40,7 +40,8 @@ CREATE TABLE `APPLICATION`
KEY `indexApp`(`PRO_UID`, `APP_STATUS`, `APP_UID`), KEY `indexApp`(`PRO_UID`, `APP_STATUS`, `APP_UID`),
KEY `indexAppNumber`(`APP_NUMBER`), KEY `indexAppNumber`(`APP_NUMBER`),
KEY `indexAppStatus`(`APP_STATUS`), KEY `indexAppStatus`(`APP_STATUS`),
KEY `indexAppCreateDate`(`APP_CREATE_DATE`) KEY `indexAppCreateDate`(`APP_CREATE_DATE`),
FULLTEXT `indexAppTitle`(`APP_TITLE`)
)ENGINE=InnoDB DEFAULT CHARSET='utf8' COMMENT='The application'; )ENGINE=InnoDB DEFAULT CHARSET='utf8' COMMENT='The application';
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
#-- APP_SEQUENCE #-- APP_SEQUENCE

View File

@@ -712,12 +712,13 @@ class System
/** /**
* Retrieves a schema array from a file. * Retrieves a schema array from a file.
* *
* @param string $sSchemaFile schema filename * @param string $schemaFile schema filename
* @return string $sContent *
* @return array
*/ */
public static function getSchema($sSchemaFile) public static function getSchema($schemaFile)
{ {
/* This is the MySQL mapping that Propel uses (from MysqlPlatform.php) */ // This is the MySQL mapping that Propel uses (from MysqlPlatform.php)
$mysqlTypes = [ $mysqlTypes = [
'NUMERIC' => 'DECIMAL', 'NUMERIC' => 'DECIMAL',
'LONGVARCHAR' => 'MEDIUMTEXT', 'LONGVARCHAR' => 'MEDIUMTEXT',
@@ -728,32 +729,38 @@ class System
'LONGVARBINARY' => 'LONGBLOB', 'LONGVARBINARY' => 'LONGBLOB',
'BLOB' => 'LONGBLOB', 'BLOB' => 'LONGBLOB',
'CLOB' => 'LONGTEXT', 'CLOB' => 'LONGTEXT',
/* This is not from Propel, but is required to get INT right */ // This is not from Propel, but is required to get INT right
'INTEGER' => 'INT' 'INTEGER' => 'INT'
]; ];
$aSchema = []; $schema = [];
$oXml = new DomDocument();
$oXml->load($sSchemaFile);
$aTables = $oXml->getElementsByTagName('table');
foreach ($aTables as $oTable) {
$aPrimaryKeys = [];
$sTableName = $oTable->getAttribute('name');
$aSchema[$sTableName] = [];
$aColumns = $oTable->getElementsByTagName('column');
foreach ($aColumns as $oColumn) {
$sColumName = $oColumn->getAttribute('name');
/* Get the field type. Propel uses VARCHAR if nothing else is specified */ // Parse schema
$type = $oColumn->hasAttribute('type') ? strtoupper($oColumn->getAttribute('type')) : "VARCHAR"; $xml = new DomDocument();
$xml->load($schemaFile);
/* Convert type to MySQL type according to Propel */ // Build the schema array
$tablesNodes = $xml->getElementsByTagName('table');
foreach ($tablesNodes as $tableNode) {
$primaryKeys = [];
$tableName = $tableNode->getAttribute('name');
$schema[$tableName] = [];
$columnsNodes = $tableNode->getElementsByTagName('column');
foreach ($columnsNodes as $columnNode) {
$columnName = $columnNode->getAttribute('name');
// Get the field type. Propel uses VARCHAR if nothing else is specified
$type = $columnNode->hasAttribute('type') ? strtoupper($columnNode->getAttribute('type')) : "VARCHAR";
// Convert type to MySQL type according to Propel
if (array_key_exists($type, $mysqlTypes)) { if (array_key_exists($type, $mysqlTypes)) {
$type = $mysqlTypes[$type]; $type = $mysqlTypes[$type];
} }
$size = $oColumn->hasAttribute('size') ? $oColumn->getAttribute('size') : null; // Get "size" attribute
/* Add default sizes from MySQL */ $size = $columnNode->hasAttribute('size') ? $columnNode->getAttribute('size') : null;
// Add default sizes from MySQL
if ($type == "TINYINT" && !$size) { if ($type == "TINYINT" && !$size) {
$size = "4"; $size = "4";
} }
@@ -765,46 +772,64 @@ class System
$type = "$type($size)"; $type = "$type($size)";
} }
$required = $oColumn->hasAttribute('required') ? $oColumn->getAttribute('required') : null; // Get "required" attribute
/* Convert $required to a bool */ $required = $columnNode->hasAttribute('required') ? $columnNode->getAttribute('required') : null;
$required = (in_array(strtolower($required), array('1', 'true'
)));
$autoIncrement = $oColumn->hasAttribute('autoIncrement') ? $oColumn->hasAttribute('autoIncrement') : false;
$unique = $oColumn->hasAttribute('unique') ? $oColumn->hasAttribute('unique') : false;
$default = $oColumn->hasAttribute('default') ? $oColumn->getAttribute('default') : null;
$primaryKey = $oColumn->hasAttribute('primaryKey') ? $oColumn->getAttribute('primaryKey') : null; // Convert $required to a bool
/* Convert $primaryKey to a bool */ $required = (in_array(strtolower($required), ['1', 'true']));
$primaryKey = (in_array(strtolower($primaryKey), array('1', 'true' $autoIncrement = $columnNode->hasAttribute('autoIncrement') ? $columnNode->hasAttribute('autoIncrement') : false;
))); $unique = $columnNode->hasAttribute('unique') ? $columnNode->hasAttribute('unique') : false;
$default = $columnNode->hasAttribute('default') ? $columnNode->getAttribute('default') : null;
$primaryKey = $columnNode->hasAttribute('primaryKey') ? $columnNode->getAttribute('primaryKey') : null;
// Convert $primaryKey to a bool
$primaryKey = (in_array(strtolower($primaryKey), ['1', 'true']));
if ($primaryKey) { if ($primaryKey) {
$aPrimaryKeys[] = $sColumName; $primaryKeys[] = $columnName;
} }
$aSchema[$sTableName][$sColumName] = array(
'Field' => $sColumName, // Add the metadata from the column
$schema[$tableName][$columnName] = [
'Field' => $columnName,
'Type' => $type, 'Type' => $type,
'Null' => $required ? "NO" : "YES", 'Null' => $required ? "NO" : "YES",
'Default' => $default, 'Default' => $default,
'AutoIncrement' => $autoIncrement, 'AutoIncrement' => $autoIncrement,
'Unique' => $unique, 'Unique' => $unique,
'PrimaryKey' => $primaryKey 'PrimaryKey' => $primaryKey
); ];
} }
if (is_array($aPrimaryKeys) && count($aPrimaryKeys) > 0) { // Add primary keys to "indexes" list
$aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; if (is_array($primaryKeys) && count($primaryKeys) > 0) {
$schema[$tableName]['INDEXES']['PRIMARY'] = $primaryKeys;
} }
$aIndexes = $oTable->getElementsByTagName('index');
foreach ($aIndexes as $oIndex) { // Search normal indexes
$aIndex = []; $indexesNodes = $tableNode->getElementsByTagName('index');
$aIndexesColumns = $oIndex->getElementsByTagName('index-column'); foreach ($indexesNodes as $indexNode) {
foreach ($aIndexesColumns as $oIndexColumn) { $indexes = [];
$aIndex[] = $oIndexColumn->getAttribute('name'); $indexesColumnsNodes = $indexNode->getElementsByTagName('index-column');
foreach ($indexesColumnsNodes as $indexColumnNode) {
$indexes[] = $indexColumnNode->getAttribute('name');
} }
$aSchema[$sTableName]['INDEXES'][$oIndex->getAttribute('name')] = $aIndex; $schema[$tableName]['INDEXES'][$indexNode->getAttribute('name')] = $indexes;
}
// Search fulltext indexes
$fulltextNodes = $tableNode->getElementsByTagName('fulltext');
foreach ($fulltextNodes as $fulltextNode) {
$fulltextIndexes = [];
$indexColumnsNodes = $fulltextNode->getElementsByTagName('index-column');
foreach ($indexColumnsNodes as $indexColumnsNode) {
$fulltextIndexes[] = $indexColumnsNode->getAttribute('name');
}
$schema[$tableName]['FULLTEXT'][$fulltextNode->getAttribute('name')] = $fulltextIndexes;
} }
} }
return $aSchema;
return $schema;
} }
/** /**
@@ -827,63 +852,63 @@ class System
} }
/** /**
* Returns the difference between two schema arrays * Returns the difference between two schemas
* *
* @param array $aOldSchema original schema array * @param array $oldSchema original schema
* @param array $aNewSchema new schema array * @param array $newSchema new schema
* @return array with tablesToAdd, tablesToAlter, tablesWithNewIndex and tablesToAlterIndex *
* @return array with tablesToAdd, tablesToAlter, tablesWithNewIndex, tablesToAlterIndex, tablesWithNewFulltext and tablesToAlterFulltext
*/ */
public static function compareSchema($aOldSchema, $aNewSchema) public static function compareSchema($oldSchema, $newSchema)
{ {
$aChanges = array( $changes = [
'tablesToAdd' => array(), 'tablesToAdd' => [],
'tablesToAlter' => array(), 'tablesToAlter' => [],
'tablesWithNewIndex' => array(), 'tablesWithNewIndex' => [],
'tablesToAlterIndex' => array() 'tablesToAlterIndex' => [],
); 'tablesWithNewFulltext' => [],
'tablesToAlterFulltext' => []
];
//new tables to create and alter // New tables to create and alter
foreach ($aNewSchema as $sTableName => $aColumns) { foreach ($newSchema as $tableName => $columns) {
if (!isset($aOldSchema[$sTableName])) { if (!isset($oldSchema[$tableName])) {
$aChanges['tablesToAdd'][$sTableName] = $aColumns; $changes['tablesToAdd'][$tableName] = $columns;
} else { } else {
//drop old columns // Drop old columns
foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { foreach ($oldSchema[$tableName] as $columnName => $parameters) {
if (!isset($aNewSchema[$sTableName][$sColumName])) { if (!isset($newSchema[$tableName][$columnName])) {
if (!isset($aChanges['tablesToAlter'][$sTableName])) { if (!isset($changes['tablesToAlter'][$tableName])) {
$aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array() $changes['tablesToAlter'][$tableName] = ['DROP' => [], 'ADD' => [], 'CHANGE' => []];
);
} }
$aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; $changes['tablesToAlter'][$tableName]['DROP'][$columnName] = $columnName;
} }
} }
//create new columns // Create new columns
//foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { foreach ($columns as $columnName => $parameters) {
foreach ($aColumns as $sColumName => $aParameters) { if ($columnName != 'INDEXES' && $columnName != 'FULLTEXT') {
if ($sColumName != 'INDEXES') { if (!isset($oldSchema[$tableName][$columnName])) {
if (!isset($aOldSchema[$sTableName][$sColumName])) { // This column doesn't exist in old schema
//this column doesnt exist in oldschema if (!isset($changes['tablesToAlter'][$tableName])) {
if (!isset($aChanges['tablesToAlter'][$sTableName])) { $changes['tablesToAlter'][$tableName] = ['DROP' => [], 'ADD' => [], 'CHANGE' => []];
$aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()
);
} }
$aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; $changes['tablesToAlter'][$tableName]['ADD'][$columnName] = $parameters;
} else { } else {
//the column exists // The column exists
$newField = $aNewSchema[$sTableName][$sColumName]; $newField = $newSchema[$tableName][$columnName];
$oldField = $aOldSchema[$sTableName][$sColumName]; $oldField = $oldSchema[$tableName][$columnName];
//both are null, no change is required // Both are null, no change is required
if (!isset($newField['Default']) && !isset($oldField['Default'])) { if (!isset($newField['Default']) && !isset($oldField['Default'])) {
$changeDefaultAttr = false; $changeDefaultAttr = false;
//one of them is null, change IS required // One of them is null, change is required
} }
if (!isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default'] != '') { if (!isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default'] != '') {
$changeDefaultAttr = true; $changeDefaultAttr = true;
} }
if (isset($newField['Default']) && !isset($oldField['Default'])) { if (isset($newField['Default']) && !isset($oldField['Default'])) {
$changeDefaultAttr = true; $changeDefaultAttr = true;
//both are defined and they are different. // Both are defined and they are different.
} }
if (isset($newField['Default']) && isset($oldField['Default'])) { if (isset($newField['Default']) && isset($oldField['Default'])) {
if ($newField['Default'] != $oldField['Default']) { if ($newField['Default'] != $oldField['Default']) {
@@ -892,13 +917,12 @@ class System
$changeDefaultAttr = false; $changeDefaultAttr = false;
} }
} }
//special cases // Special cases, BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html
// BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html if (in_array(strtolower($newField['Type']), ['text', 'mediumtext'])) {
if (in_array(strtolower($newField['Type']), array('text', 'mediumtext'))) {
$changeDefaultAttr = false; $changeDefaultAttr = false;
} }
// #1067 - Invalid default value for datetime field // #1067 - Invalid default value for datetime field
if (in_array($newField['Type'], array('datetime')) && isset($newField['Default']) && $newField['Default'] == '') { if (in_array($newField['Type'], ['datetime']) && isset($newField['Default']) && $newField['Default'] == '') {
$changeDefaultAttr = false; $changeDefaultAttr = false;
} }
@@ -907,48 +931,64 @@ class System
$changeDefaultAttr = false; $changeDefaultAttr = false;
} }
//if any difference exists, then insert the difference in aChanges // If any difference exists, then insert the difference in "changes" variable
if (strcasecmp($newField['Field'], $oldField['Field']) !== 0 || strcasecmp($newField['Type'], $oldField['Type']) !== 0 || strcasecmp($newField['Null'], $oldField['Null']) !== 0 || $changeDefaultAttr) { if (strcasecmp($newField['Field'], $oldField['Field']) !== 0 || strcasecmp($newField['Type'], $oldField['Type']) !== 0 || strcasecmp($newField['Null'], $oldField['Null']) !== 0 || $changeDefaultAttr) {
if (!isset($aChanges['tablesToAlter'][$sTableName])) { if (!isset($changes['tablesToAlter'][$tableName])) {
$aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); $changes['tablesToAlter'][$tableName] = ['DROP' => [], 'ADD' => [], 'CHANGE' => []];
} }
$aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; $changes['tablesToAlter'][$tableName]['CHANGE'][$columnName]['Field'] = $newField['Field'];
$aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; $changes['tablesToAlter'][$tableName]['CHANGE'][$columnName]['Type'] = $newField['Type'];
$aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; $changes['tablesToAlter'][$tableName]['CHANGE'][$columnName]['Null'] = $newField['Null'];
if (isset($newField['Default'])) { if (isset($newField['Default'])) {
$aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; $changes['tablesToAlter'][$tableName]['CHANGE'][$columnName]['Default'] = $newField['Default'];
} else { } else {
$aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; $changes['tablesToAlter'][$tableName]['CHANGE'][$columnName]['Default'] = null;
} }
} }
} }
} }
//only columns, no the indexes column // Only columns, no the indexes column
} }
//foreach $aColumns // Now check the normal indexes of the table
//now check the indexes of table if (isset($newSchema[$tableName]['INDEXES'])) {
if (isset($aNewSchema[$sTableName]['INDEXES'])) { foreach ($newSchema[$tableName]['INDEXES'] as $indexName => $indexFields) {
foreach ($aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields) { if (!isset($oldSchema[$tableName]['INDEXES'][$indexName])) {
if (!isset($aOldSchema[$sTableName]['INDEXES'][$indexName])) { if (!isset($changes['tablesWithNewIndex'][$tableName])) {
if (!isset($aChanges['tablesWithNewIndex'][$sTableName])) { $changes['tablesWithNewIndex'][$tableName] = [];
$aChanges['tablesWithNewIndex'][$sTableName] = [];
} }
$aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; $changes['tablesWithNewIndex'][$tableName][$indexName] = $indexFields;
} else { } else {
if ($aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields) { if ($oldSchema[$tableName]['INDEXES'][$indexName] != $indexFields) {
if (!isset($aChanges['tablesToAlterIndex'][$sTableName])) { if (!isset($changes['tablesToAlterIndex'][$tableName])) {
$aChanges['tablesToAlterIndex'][$sTableName] = []; $changes['tablesToAlterIndex'][$tableName] = [];
} }
$aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; $changes['tablesToAlterIndex'][$tableName][$indexName] = $indexFields;
}
}
}
}
// Now check the "fulltext" indexes of the table
if (isset($newSchema[$tableName]['FULLTEXT'])) {
foreach ($newSchema[$tableName]['FULLTEXT'] as $indexName => $indexFields) {
if (!isset($oldSchema[$tableName]['FULLTEXT'][$indexName])) {
if (!isset($changes['tablesWithNewFulltext'][$tableName])) {
$changes['tablesWithNewFulltext'][$tableName] = [];
}
$changes['tablesWithNewFulltext'][$tableName][$indexName] = $indexFields;
} else {
if ($oldSchema[$tableName]['FULLTEXT'][$indexName] != $indexFields) {
if (!isset($changes['tablesToAlterFulltext'][$tableName])) {
$changes['tablesToAlterFulltext'][$tableName] = [];
}
$changes['tablesToAlterFulltext'][$tableName][$indexName] = $indexFields;
} }
} }
} }
} }
} }
//for-else table exists
} }
//for new schema return $changes;
return $aChanges;
} }
public static function getEmailConfiguration() public static function getEmailConfiguration()

View File

@@ -225,7 +225,14 @@ class Delegation extends Model
$query->join('APPLICATION', function ($join) use ($filterBy, $search, $status, $query) { $query->join('APPLICATION', function ($join) use ($filterBy, $search, $status, $query) {
$join->on('APP_DELEGATION.APP_NUMBER', '=', 'APPLICATION.APP_NUMBER'); $join->on('APP_DELEGATION.APP_NUMBER', '=', 'APPLICATION.APP_NUMBER');
if ($filterBy == 'APP_TITLE' && $search) { if ($filterBy == 'APP_TITLE' && $search) {
$join->where('APPLICATION.APP_TITLE', 'LIKE', "%${search}%"); // Cleaning "fulltext" operators in order to avoid unexpected results
$search = str_replace(['-', '+', '<', '>', '(', ')', '~', '*', '"'], ['', '', '', '', '', '', '', '', ''], $search);
// Build the "fulltext" expression
$search = '+"' . preg_replace('/\s+/', '" +"', addslashes($search)) . '"';
// Searching using "fulltext" index
$join->whereRaw("MATCH(APPLICATION.APP_TITLE) AGAINST('{$search}' IN BOOLEAN MODE)");
} }
// Based on the below, we can further limit the join so that we have a smaller data set based on join criteria // Based on the below, we can further limit the join so that we have a smaller data set based on join criteria
switch ($status) { switch ($status) {