/** * Reverse engineers the View definitions of this database * * @param DriverBase $dbi Database connection to INFORMATION_SCHEMA */ protected function reverse_engineer_views(&$dbi) { $schema_name = $this->database; $sql = 'SELECT * FROM [INFORMATION_SCHEMA].[VIEWS] WHERE [table_catalog] = ' . $dbi->quote($schema_name); $dbi->setQuery($sql); $all_views = $dbi->loadObjectList(); $registry = Factory::getConfiguration(); $root = $registry->get('volatile.database.root', '[SITEDB]'); // If we have filters, make sure the tables pass the filtering $filters = Factory::getFilters(); // First pass: populate the table_name_map if (!empty($all_views)) { foreach ($all_views as $table_object) { // Extract the table name $table_name = $table_object->TABLE_NAME; // Filter and convert if (substr($table_name, 0, 3) == '#__') { $warningMessage = __CLASS__ . " :: Table {$table_name} has a prefix of #__. This would cause restoration errors; table skipped."; $this->setWarning($warningMessage); Factory::getLog()->log(LogLevel::WARNING, $warningMessage); continue; } $table_abstract = $this->getAbstract($table_name); if (substr($table_abstract, 0, 4) != 'bak_') { // Apply exclusion filters if (!$filters->isFiltered($table_abstract, $root, 'dbobject', 'all')) { Factory::getLog()->log(LogLevel::INFO, __CLASS__ . " :: Adding {$table_name} (internal name {$table_abstract})"); $this->table_name_map[$table_name] = $table_abstract; } else { Factory::getLog()->log(LogLevel::INFO, __CLASS__ . " :: Skipping {$table_name} (internal name {$table_abstract})"); continue; } } else { Factory::getLog()->log(LogLevel::INFO, __CLASS__ . " :: Backup view {$table_name} automatically skipped."); continue; } } } // Second pass: get the create commands if (!empty($all_views)) { foreach ($all_views as $table_object) { // Extract the table name $table_name = $table_object->TABLE_NAME; if (!in_array($table_name, $this->table_name_map)) { // Skip any views which have been filtered out continue; } $table_abstract = $this->getAbstract($table_name); // Still here? The view is added. We now have to store its // create command, dependency info and so on $new_entry = array('type' => 'view', 'dump_records' => false); $dependencies = array(); $table_sql = $table_object->VIEW_DEFINITION; $old_table_sql = $table_sql; foreach ($this->table_name_map as $ref_normal => $ref_abstract) { if ($pos = strpos($table_sql, ".{$ref_normal}")) { // Add a reference hit $this->dependencies[$ref_normal][] = $table_name; // Add the dependency to this table's metadata $dependencies[] = $ref_normal; // Do the replacement $table_sql = str_replace(".{$ref_normal}", ".{$ref_abstract}", $table_sql); } } // On DB only backup we don't want any replacing to take place, do we? if (!Factory::getEngineParamsProvider()->getScriptingParameter('db.abstractnames', 1)) { $table_sql = $old_table_sql; } // Replace newlines with spaces $table_sql = str_replace("\n", " ", $table_sql) . ";\n"; $table_sql = str_replace("\r", " ", $table_sql); $table_sql = str_replace("\t", " ", $table_sql); $new_entry['create'] = $table_sql; $new_entry['dependencies'] = $dependencies; $this->tables_data[$table_name] = $new_entry; } } }