/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $uid = $input->getArgument('user'); $user = User::load($uid); if (!$user) { $io->error(sprintf($this->trans('commands.user.password.reset.errors.invalid-user'), $uid)); return 1; } $password = $input->getArgument('password'); if (!$password) { $io->error(sprintf($this->trans('commands.user.password.reset.errors.empty-password'), $uid)); return 1; } try { $user->setPassword($password); $user->save(); $schema = $this->database->schema(); $flood = $schema->findTables('flood'); if ($flood) { $this - $this->chainQueue->addCommand('user:login:clear:attempts', ['uid' => $uid]); } } catch (\Exception $e) { $io->error($e->getMessage()); return 1; } $io->success(sprintf($this->trans('commands.user.password.reset.messages.reset-successful'), $uid)); }
/** * Tests that entity schema responds to changes in the entity type definition. */ public function testEntitySchemaUpdate() { $this->installModule('entity_schema_test'); $storage_definitions = $this->entityManager->getFieldStorageDefinitions('entity_test'); $this->entityManager->onFieldStorageDefinitionCreate($storage_definitions['custom_base_field']); $this->entityManager->onFieldStorageDefinitionCreate($storage_definitions['custom_bundle_field']); $schema_handler = $this->database->schema(); $tables = array('entity_test', 'entity_test_revision', 'entity_test_field_data', 'entity_test_field_revision'); $dedicated_tables = array('entity_test__custom_bundle_field', 'entity_test_revision__custom_bundle_field'); // Initially only the base table and the dedicated field data table should // exist. foreach ($tables as $index => $table) { $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); } $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); // Update the entity type definition and check that the entity schema now // supports translations and revisions. $this->updateEntityType(TRUE); foreach ($tables as $table) { $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); } foreach ($dedicated_tables as $table) { $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); } // Revert changes and check that the entity schema now does not support // neither translations nor revisions. $this->updateEntityType(FALSE); foreach ($tables as $index => $table) { $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); } $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); }
/** * Create a new table from a Drupal table definition if it doesn't exist. * * @param string $name * The name of the table to create. * @param array $table * A Schema API table definition array. */ protected function createTable($name, array $table) { // This must be on the database connection to be shared among classes. if (empty($this->database->migrateTables[$name])) { $this->database->migrateTables[$name] = TRUE; $this->database->schema()->createTable($name, $table); } }
/** * Create a new table from a Drupal table definition if it doesn't exist. * * @param $name * The name of the table to create. * @param $table * A Schema API table definition array. */ protected function createTable($name, $table = NULL) { // This must be on the database connection to be shared among classes. if (empty($this->database->migrateTables[$name])) { $this->database->migrateTables[$name] = TRUE; $this->database->schema()->createTable($name, $table ?: $this->tableDefinitions()[$name]); } }
/** * Ensures that table gets created on the fly. */ protected function doTestTable() { // Test that we can create a tree storage with an arbitrary table name and // that selecting from the storage creates the table. $tree_storage = new MenuTreeStorage($this->container->get('database'), $this->container->get('cache.menu'), $this->container->get('cache_tags.invalidator'), 'test_menu_tree'); $this->assertFalse($this->connection->schema()->tableExists('test_menu_tree'), 'Test table is not yet created'); $tree_storage->countMenuLinks(); $this->assertTrue($this->connection->schema()->tableExists('test_menu_tree'), 'Test table was created'); }
/** * Tests the custom bundle field creation and deletion. */ public function testCustomBundleFieldCreateDelete() { // Install the module which adds the field. $this->moduleHandler->install(array('entity_bundle_field_test'), FALSE); $definition = $this->entityManager->getFieldDefinitions('entity_test', 'custom')['custom_field']; $this->assertNotNull($definition, 'Field definition found.'); // Make sure the table has been created. $table = $this->entityManager->getStorage('entity_test')->_fieldTableName($definition); $this->assertTrue($this->database->schema()->tableExists($table), 'Table created'); $this->moduleHandler->uninstall(array('entity_bundle_field_test'), FALSE); $this->assertFalse($this->database->schema()->tableExists($table), 'Table dropped'); }
/** * Checks if the table exists and create it if not. * * @return bool * TRUE if the table was created, FALSE otherwise. */ protected function ensureTableExists() { try { if (!$this->connection->schema()->tableExists($this->tableName)) { $this->connection->schema()->createTable($this->tableName, $this->schemaDefinition()); return TRUE; } } catch (SchemaObjectExistsException $e) { // If another process has already created the table, attempting to // recreate it will throw an exception. In this case just catch the // exception and do nothing. return TRUE; } return FALSE; }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $uid = $input->getArgument('uid'); $account = User::load($uid); if (!$account) { // Error loading User entity. $io->error(sprintf($this->trans('commands.user.login.clear.attempts.errors.invalid-user'), $uid)); return 1; } // Define event name and identifier. $event = 'user.failed_login_user'; // Identifier is created by uid and IP address, // Then we defined a generic identifier. $identifier = "{$account->id()}-"; // Retrieve current database connection. $schema = $this->database->schema(); $flood = $schema->findTables('flood'); if (!$flood) { $io->error($this->trans('commands.user.login.clear.attempts.errors.no-flood')); return 1; } // Clear login attempts. $this->database->delete('flood')->condition('event', $event)->condition('identifier', $this->database->escapeLike($identifier) . '%', 'LIKE')->execute(); // Command executed successful. $io->success(sprintf($this->trans('commands.user.login.clear.attempts.messages.successful'), $uid)); }
/** * {@inheritdoc} */ public function removeIndex($index) { if (!is_object($index)) { // If the index got deleted, create a dummy to simplify the code. Since we // can't know, we assume the index was read-only, just to be on the safe // side. $index = Index::create(array('id' => $index, 'read_only' => TRUE)); } try { if (!isset($this->configuration['field_tables'][$index->id()]) && !isset($this->configuration['index_tables'][$index->id()])) { return; } // Don't delete the index data of read-only indexes. if (!$index->isReadOnly()) { foreach ($this->configuration['field_tables'][$index->id()] as $field) { if ($this->database->schema()->tableExists($field['table'])) { $this->database->schema()->dropTable($field['table']); } } if ($this->database->schema()->tableExists($this->configuration['index_tables'][$index->id()])) { $this->database->schema()->dropTable($this->configuration['index_tables'][$index->id()]); } } unset($this->configuration['field_tables'][$index->id()]); unset($this->configuration['index_tables'][$index->id()]); $this->server->save(); } catch (\Exception $e) { throw new SearchApiException($e->getMessage(), $e->getCode(), $e); } }
/** * Drop the tables used for the sample data. * * @param \Drupal\Core\Database\Connection $connection * The connection to use to drop the tables. */ public function dropTables(Connection $connection) { $tables = $this->routingTableDefinition(); $schema = $connection->schema(); foreach ($tables as $name => $table) { $schema->dropTable($name); } }
/** * Tests creating a multi-field index when there are existing entities. */ public function testEntityIndexCreateWithData() { // Save an entity. $name = $this->randomString(); $entity = $this->entityManager->getStorage('entity_test_update')->create(array('name' => $name)); $entity->save(); // Add an entity index, run the update. Ensure that the index is created // despite having data. $this->addEntityIndex(); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index added.'); }
/** * Given a database field type, return a Drupal size. * * @param string $type * The MySQL field type. * * @return string * The Drupal schema field size. */ protected function fieldSizeMap($type) { // Convert everything to lowercase. $map = array_map('strtolower', $this->connection->schema()->getFieldTypeMap()); $map = array_flip($map); $schema_type = explode(':', $map[$type])[0]; // Only specify size on these types. if (in_array($schema_type, ['blob', 'float', 'int', 'text'])) { // The MySql map contains type:size. Remove the type part. return explode(':', $map[$type])[1]; } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $database = $input->getOption('database'); $table = $input->getArgument('table'); $databaseConnection = $this->resolveConnection($io, $database); if ($table) { $this->redBean = $this->getRedBeanConnection($database); $tableInfo = $this->redBean->inspect($table); $tableHeader = [$this->trans('commands.database.table.debug.messages.column'), $this->trans('commands.database.table.debug.messages.type')]; $tableRows = []; foreach ($tableInfo as $column => $type) { $tableRows[] = ['column' => $column, 'type' => $type]; } $io->table($tableHeader, $tableRows); return 0; } $schema = $this->database->schema(); $tables = $schema->findTables('%'); $io->comment(sprintf($this->trans('commands.database.table.debug.messages.table-show'), $databaseConnection['database'])); $io->table([$this->trans('commands.database.table.debug.messages.table')], $tables); return 0; }
/** * Check if the config table exists and create it if not. * * @return bool * TRUE if the table was created, FALSE otherwise. * * @throws \Drupal\Core\Config\StorageException * If a database error occurs. */ protected function ensureTableExists() { try { if (!$this->connection->schema()->tableExists($this->table)) { $this->connection->schema()->createTable($this->table, static::schemaDefinition()); return TRUE; } } catch (SchemaObjectExistsException $e) { return TRUE; } catch (\Exception $e) { throw new StorageException($e->getMessage(), NULL, $e); } return FALSE; }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $database = $input->getArgument('database'); $yes = $input->getOption('yes'); $databaseConnection = $this->resolveConnection($io, $database); if (!$yes) { if (!$io->confirm(sprintf($this->trans('commands.database.drop.question.drop-tables'), $databaseConnection['database']), true)) { return 1; } } $schema = $this->database->schema(); $tables = $schema->findTables('%'); $tableRows = []; foreach ($tables as $table) { if ($schema->dropTable($table)) { $tableRows['success'][] = [$table]; } else { $tableRows['error'][] = [$table]; } } $io->success(sprintf($this->trans('commands.database.drop.messages.table-drop'), count($tableRows['success']))); return 0; }
/** * Tests the destroy method. * * Scenarios to test for: * - No errors. * - One error. * - Multiple errors. */ public function testDestroy() { $id_map = $this->getIdMap(); // Initialize the ID map. $id_map->getDatabase(); $map_table_name = $id_map->mapTableName(); $message_table_name = $id_map->messageTableName(); $row = new Row(['source_id_property' => 'source_value'], ['source_id_property' => []]); $id_map->saveIdMapping($row, ['destination_id_property' => 2]); $id_map->saveMessage(['source_id_property' => 'source_value'], 'A message'); $this->assertTrue($this->database->schema()->tableExists($map_table_name), "{$map_table_name} exists"); $this->assertTrue($this->database->schema()->tableExists($message_table_name), "{$message_table_name} exists"); $id_map->destroy(); $this->assertFalse($this->database->schema()->tableExists($map_table_name), "{$map_table_name} does not exist"); $this->assertFalse($this->database->schema()->tableExists($message_table_name), "{$message_table_name} does not exist"); }
/** * Tests ::applyEntityUpdate() and ::applyFieldUpdate(). */ public function testSingleActionCalls() { // Ensure that the methods return FALSE when called with bogus information. $this->assertFalse($this->entityDefinitionUpdateManager->applyEntityUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'foo'), 'Calling applyEntityUpdate() with a non-existent entity returns FALSE.'); $this->assertFalse($this->entityDefinitionUpdateManager->applyFieldUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'foo', 'bar'), 'Calling applyFieldUpdate() with a non-existent entity returns FALSE.'); $this->assertFalse($this->entityDefinitionUpdateManager->applyFieldUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'entity_test_update', 'bar'), 'Calling applyFieldUpdate() with a non-existent field returns FALSE.'); $this->assertFalse($this->entityDefinitionUpdateManager->applyEntityUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'entity_test_update'), 'Calling applyEntityUpdate() with an $op that is not applicable to the entity type returns FALSE.'); $this->assertFalse($this->entityDefinitionUpdateManager->applyFieldUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_DELETED, 'entity_test_update', 'new_base_field'), 'Calling applyFieldUpdate() with an $op that is not applicable to the field returns FALSE.'); // Create a new base field. $this->addRevisionableBaseField(); $this->assertTrue($this->entityDefinitionUpdateManager->applyFieldUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'entity_test_update', 'new_base_field'), 'Calling applyFieldUpdate() correctly returns TRUE.'); $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table."); // Make the entity type revisionable. $this->updateEntityTypeToRevisionable(); $this->assertTrue($this->entityDefinitionUpdateManager->applyEntityUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED, 'entity_test_update'), 'Calling applyEntityUpdate() correctly returns TRUE.'); $this->assertTrue($this->database->schema()->tableExists('entity_test_update_revision'), "The 'entity_test_update_revision' table has been created."); }
/** * Checks if the tree table exists and create it if not. * * @return bool * TRUE if the table was created, FALSE otherwise. * * @throws \Drupal\Component\Plugin\Exception\PluginException * If a database error occurs. */ protected function ensureTableExists() { try { if (!$this->connection->schema()->tableExists($this->table)) { $this->connection->schema()->createTable($this->table, static::schemaDefinition()); return TRUE; } } catch (SchemaObjectExistsException $e) { // If another process has already created the config table, attempting to // recreate it will throw an exception. In this case just catch the // exception and do nothing. return TRUE; } catch (\Exception $e) { throw new PluginException($e->getMessage(), NULL, $e); } return FALSE; }
/** * Ensures that a new entity level index is created when data exists. * * @see Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::onEntityTypeUpdate */ public function testCreateIndexUsingEntityStorageSchemaWithData() { // Save an entity. $name = $this->randomString(); $storage = $this->entityManager->getStorage('entity_test_update'); $entity = $storage->create(array('name' => $name)); $entity->save(); // Create an index. $indexes = array('entity_test_update__type_index' => array('type')); $this->state->set('entity_test_update.additional_entity_indexes', $indexes); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__type_index'), "New index 'entity_test_update__type_index' has been created on the 'entity_test_update' table."); // Check index size in for MySQL. if (Database::getConnection()->driver() == 'mysql') { $result = Database::getConnection()->query('SHOW INDEX FROM {entity_test_update} WHERE key_name = \'entity_test_update__type_index\' and column_name = \'type\'')->fetchObject(); $this->assertEqual(191, $result->Sub_part, 'The index length has been restricted to 191 characters for UTF8MB4 compatibility.'); } }
/** * {@inheritdoc} */ public function query() { // The table doesn't exist until a moderated node has been saved at least // once. Just in case, disable this filter until then. Note that this means // the view will still show all revisions, not just latest, but this is // sufficiently edge-case-y that it's probably not worth the time to // handle more robustly. if (!$this->connection->schema()->tableExists('content_revision_tracker')) { return; } $table = $this->ensureMyTable(); /** @var \Drupal\views\Plugin\views\query\Sql $query */ $query = $this->query; $definition = $this->entityTypeManager->getDefinition($this->getEntityType()); $keys = $definition->getKeys(); $definition = ['table' => 'content_revision_tracker', 'type' => 'INNER', 'field' => 'entity_id', 'left_table' => $table, 'left_field' => $keys['id'], 'extra' => [['left_field' => $keys['langcode'], 'field' => 'langcode'], ['left_field' => $keys['revision'], 'field' => 'revision_id'], ['field' => 'entity_type', 'value' => $this->getEntityType()]]]; $join = $this->joinHandler->createInstance('standard', $definition); $query->ensureTable('content_revision_tracker', $this->relationship, $join); }
/** * Tests creating and deleting a multi-field index when there are no existing entities. */ public function testEntityIndexCreateDeleteWithoutData() { // Add an entity index and ensure the update manager reports that as an // update to the entity type. $this->addEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the new index is created. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.'); // Remove the index and ensure the update manager reports that as an // update to the entity type. $this->removeEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the index is deleted. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.'); }
/** * {@inheritdoc} */ public function removeIndex($index) { if (!is_object($index)) { // If the index got deleted, create a dummy to simplify the code. Since we // can't know, we assume the index was read-only, just to be on the safe // side. $index = Index::create(array( 'id' => $index, 'read_only' => TRUE, )); } $db_info = $this->getIndexDbInfo($index); try { if (!isset($db_info['field_tables']) && !isset($db_info['index_table'])) { return; } // Don't delete the index data of read-only indexes. if (!$index->isReadOnly()) { foreach ($db_info['field_tables'] as $field) { if ($this->database->schema()->tableExists($field['table'])) { $this->database->schema()->dropTable($field['table']); } } if ($this->database->schema()->tableExists($db_info['index_table'])) { $this->database->schema()->dropTable($db_info['index_table']); } } $this->getKeyValueStore()->delete($index->id()); } // The database operations might throw PDO or other exceptions, so we catch // them all and re-wrap them appropriately. catch (\Exception $e) { throw new SearchApiException($e->getMessage(), $e->getCode(), $e); } }
/** * Act on an exception when cache might be stale. * * If the {cachetags} table does not yet exist, that's fine but if the table * exists and yet the query failed, then the cache is stale and the * exception needs to propagate. * * @param $e * The exception. * @param string|null $table_name * The table name, defaults to $this->bin. Can be cachetags. */ protected function catchException(\Exception $e, $table_name = NULL) { if ($this->connection->schema()->tableExists($table_name ?: $this->bin)) { throw $e; } }
/** * {@inheritdoc} */ public function destroy() { $this->db->schema()->dropTable($this->table); }
/** * Creates a unique key, dropping it if already existing. * * @param string $table * The table name. * @param string $name * The index name. * @param array $specifier * The unique fields. * * @see \Drupal\Core\Database\Schema::addUniqueKey() */ protected function addUniqueKey($table, $name, array $specifier) { $schema_handler = $this->database->schema(); $schema_handler->dropUniqueKey($table, $name); $schema_handler->addUniqueKey($table, $name, $specifier); }
/** * Checks whether a database table is non-existent or empty. * * Empty tables can be dropped and recreated without data loss. * * @param string $table_name * The database table to check. * * @return bool * TRUE if the table is empty, FALSE otherwise. */ protected function isTableEmpty($table_name) { return !$this->database->schema()->tableExists($table_name) || !$this->database->select($table_name)->countQuery()->range(0, 1)->execute()->fetchField(); }
/** * Act on an exception when cache might be stale. * * If the {cachetags} table does not yet exist, that's fine but if the table * exists and yet the query failed, then the cache is stale and the * exception needs to propagate. * * @param \Exception $e * The exception. * * @throws \Exception */ protected function catchException(\Exception $e) { if ($this->connection->schema()->tableExists('cachetags')) { throw $e; } }
/** * {@inheritdoc} */ public function finalizePurge(FieldStorageDefinitionInterface $storage_definition) { $table_name = static::_fieldTableName($storage_definition, TRUE); $revision_name = static::_fieldRevisionTableName($storage_definition, TRUE); $this->database->schema()->dropTable($table_name); $this->database->schema()->dropTable($revision_name); }
/** * Determine what version of Drupal the source database contains, copied from \Drupal\migrate_upgrade\MigrationCreationTrait * * @param \Drupal\Core\Database\Connection $connection * * @return int|FALSE */ protected function getLegacyDrupalVersion(Connection $connection) { // Don't assume because a table of that name exists, that it has the columns // we're querying. Catch exceptions and report that the source database is // not Drupal. // Druppal 5/6/7 can be detected by the schema_version in the system table. if ($connection->schema()->tableExists('system')) { try { $version_string = $connection->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system'])->fetchField(); if ($version_string && $version_string[0] == '1') { if ((int) $version_string >= 1000) { $version_string = '5'; } else { $version_string = false; } } } catch (\PDOException $e) { $version_string = false; } } elseif ($connection->schema()->tableExists('key_value')) { $result = $connection->query("SELECT value FROM {key_value} WHERE collection = :system_schema and name = :module", [':system_schema' => 'system.schema', ':module' => 'system'])->fetchField(); $version_string = unserialize($result); } else { $version_string = false; } return $version_string ? substr($version_string, 0, 1) : false; }
/** * Act on an exception when semaphore might be stale. * * If the table does not yet exist, that's fine, but if the table exists and * yet the query failed, then the semaphore is stale and the exception needs * to propagate. * * @param $e * The exception. * * @throws \Exception */ protected function catchException(\Exception $e) { if ($this->database->schema()->tableExists(static::TABLE_NAME)) { throw $e; } }