/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = NULL) { $connections = []; foreach (Database::getAllConnectionInfo() as $key => $info) { $database = Database::getConnection('default', $key); $connections[$key] = $database->getLogger()->get('webprofiler'); } $this->data['connections'] = array_keys($connections); $data = []; foreach ($connections as $key => $queries) { foreach ($queries as $query) { // Remove caller args. unset($query['caller']['args']); // Remove query args element if empty. if (empty($query['args'])) { unset($query['args']); } // Save time in milliseconds. $query['time'] = $query['time'] * 1000; $query['database'] = $key; $data[] = $query; } } $querySort = $this->configFactory->get('webprofiler.config')->get('query_sort'); if ('duration' === $querySort) { usort($data, ["Drupal\\webprofiler\\DataCollector\\DatabaseDataCollector", "orderQueryByTime"]); } $this->data['queries'] = $data; $options = $this->database->getConnectionOptions(); // Remove password for security. unset($options['password']); $this->data['database'] = $options; }
/** * Executes all steps of migrations upgrade. */ protected function testMigrateUpgrade() { $connection_options = $this->sourceDatabase->getConnectionOptions(); $this->drupalGet('/upgrade'); $this->assertText('Upgrade a Drupal site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the upgrading handbook for more detailed information.'); $this->drupalPostForm(NULL, [], t('Continue')); $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); $this->assertFieldByName('mysql[host]'); $driver = $connection_options['driver']; $connection_options['prefix'] = $connection_options['prefix']['default']; // Use the driver connection form to get the correct options out of the // database settings. This supports all of the databases we test against. $drivers = drupal_get_database_types(); $form = $drivers[$driver]->getFormOptions($connection_options); $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); $edits = $this->translatePostValues(['driver' => $driver, $driver => $connection_options, 'source_base_path' => $this->getSourceBasePath()]); $this->drupalPostForm(NULL, $edits, t('Review upgrade')); $this->assertResponse(200); $this->assertText('Are you sure?'); $this->drupalPostForm(NULL, [], t('Perform upgrade')); $this->assertText(t('Congratulations, you upgraded Drupal!')); // Have to reset all the statics after migration to ensure entities are // loadable. $this->resetAll(); $expected_counts = $this->getEntityCounts(); foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) { $real_count = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple()); $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; $this->assertEqual($expected_count, $real_count, "Found {$real_count} {$entity_type} entities, expected {$expected_count}."); } }
/** * Build a condition to match a table name against a standard information_schema. * * The information_schema is a SQL standard that provides information about the * database server and the databases, schemas, tables, columns and users within * it. This makes information_schema a useful tool to use across the drupal * database drivers and is used by a few different functions. The function below * describes the conditions to be meet when querying information_schema.tables * for drupal tables or information associated with drupal tables. Even though * this is the standard method, not all databases follow standards and so this * method should be overwritten by a database driver if the database provider * uses alternate methods. Because information_schema.tables is used in a few * different functions, a database driver will only need to override this function * to make all the others work. For example see * core/includes/databases/mysql/schema.inc. * * @param $table_name * The name of the table in question. * @param $operator * The operator to apply on the 'table' part of the condition. * @param $add_prefix * Boolean to indicate whether the table name needs to be prefixed. * * @return \Drupal\Core\Database\Query\Condition * A Condition object. */ protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) { $info = $this->connection->getConnectionOptions(); // Retrieve the table name and schema $table_info = $this->getPrefixInfo($table_name, $add_prefix); $condition = new Condition('AND'); $condition->condition('table_catalog', $info['database']); $condition->condition('table_schema', $table_info['schema']); $condition->condition('table_name', $table_info['table'], $operator); return $condition; }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = NULL) { $queries = $this->database->getLogger()->get('webprofiler'); foreach ($queries as &$query) { // Remove caller args. unset($query['caller']['args']); // Remove query args element if empty. if (empty($query['args'])) { unset($query['args']); } // Save time in milliseconds. $query['time'] = $query['time'] * 1000; } $querySort = $this->configFactory->get('webprofiler.config')->get('query_sort'); if ('duration' === $querySort) { usort($queries, ["Drupal\\webprofiler\\DataCollector\\DatabaseDataCollector", "orderQueryByTime"]); } $this->data['queries'] = $queries; $options = $this->database->getConnectionOptions(); // Remove password for security. unset($options['password']); $this->data['database'] = $options; }
/** * Gets field ordering for a given table. * * @param string $table * The table name. * * @return string * The order string to append to the query. */ protected function getFieldOrder($table) { // @todo this is MySQL only since there are no Database API functions for // table column data. // @todo this code is duplicated in `core/scripts/migrate-db.sh`. $connection_info = $this->connection->getConnectionOptions(); // Order by primary keys. $order = ''; $query = "SELECT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`\n WHERE (`TABLE_SCHEMA` = '" . $connection_info['database'] . "')\n AND (`TABLE_NAME` = '{" . $table . "}') AND (`COLUMN_KEY` = 'PRI')\n ORDER BY COLUMN_NAME"; $results = $this->connection->query($query); while (($row = $results->fetchAssoc()) !== FALSE) { $order .= $row['COLUMN_NAME'] . ', '; } if (!empty($order)) { $order = ' ORDER BY ' . rtrim($order, ', '); } return $order; }
/** * Executes all steps of migrations upgrade. */ protected function testMigrateUpgrade() { $connection_options = $this->sourceDatabase->getConnectionOptions(); $this->drupalGet('/upgrade'); $this->assertText('Upgrade a Drupal site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the upgrading handbook for more detailed information.'); $this->drupalPostForm(NULL, [], t('Continue')); $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); $this->assertFieldByName('mysql[host]'); $driver = $connection_options['driver']; $connection_options['prefix'] = $connection_options['prefix']['default']; // Use the driver connection form to get the correct options out of the // database settings. This supports all of the databases we test against. $drivers = drupal_get_database_types(); $form = $drivers[$driver]->getFormOptions($connection_options); $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); $edit = [$driver => $connection_options, 'source_base_path' => $this->getSourceBasePath()]; if (count($drivers) !== 1) { $edit['driver'] = $driver; } $edits = $this->translatePostValues($edit); // Ensure submitting the form with invalid database credentials gives us a // nice warning. $this->drupalPostForm(NULL, [$driver . '[database]' => 'wrong'] + $edits, t('Review upgrade')); $this->assertText('Resolve the issue below to continue the upgrade.'); $this->drupalPostForm(NULL, $edits, t('Review upgrade')); $this->assertResponse(200); $this->assertText('Are you sure?'); $this->drupalPostForm(NULL, [], t('Perform upgrade')); $this->assertText(t('Congratulations, you upgraded Drupal!')); // Have to reset all the statics after migration to ensure entities are // loadable. $this->resetAll(); $expected_counts = $this->getEntityCounts(); foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) { $real_count = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple()); $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; $this->assertEqual($expected_count, $real_count, "Found {$real_count} {$entity_type} entities, expected {$expected_count}."); } $version_tag = 'Drupal ' . $this->getLegacyDrupalVersion($this->sourceDatabase); $plugin_manager = \Drupal::service('plugin.manager.migration'); /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */ $all_migrations = $plugin_manager->createInstancesByTag($version_tag); foreach ($all_migrations as $migration) { $id_map = $migration->getIdMap(); foreach ($id_map as $source_id => $map) { // Convert $source_id into a keyless array so that // \Drupal\migrate\Plugin\migrate\id_map\Sql::getSourceHash() works as // expected. $source_id_values = array_values(unserialize($source_id)); $row = $id_map->getRowBySource($source_id_values); $destination = serialize($id_map->currentDestination()); $message = "Successful migration of {$source_id} to {$destination} as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; // A completed migration should have maps with // MigrateIdMapInterface::STATUS_IGNORED or // MigrateIdMapInterface::STATUS_IMPORTED. if ($row['source_row_status'] == MigrateIdMapInterface::STATUS_FAILED || $row['source_row_status'] == MigrateIdMapInterface::STATUS_NEEDS_UPDATE) { $this->fail($message); } else { $this->pass($message); } } } }