/**
  * Perform necessary database schema migrations
  *
  * @param SchemaUpdateType[] $schemaUpdateTypes List of permitted schema update types
  * @return SchemaUpdateResult Result of the schema update
  */
 public function updateSchema(array $schemaUpdateTypes)
 {
     $expectedSchema = $this->expectedSchemaService->getExpectedDatabaseSchema();
     $currentSchema = $this->schemaMigrationService->getFieldDefinitions_database();
     $addCreateChange = $this->schemaMigrationService->getDatabaseExtra($expectedSchema, $currentSchema);
     $dropRename = $this->schemaMigrationService->getDatabaseExtra($currentSchema, $expectedSchema);
     $updateStatements = array();
     ArrayUtility::mergeRecursiveWithOverrule($updateStatements, $this->schemaMigrationService->getUpdateSuggestions($addCreateChange));
     ArrayUtility::mergeRecursiveWithOverrule($updateStatements, $this->schemaMigrationService->getUpdateSuggestions($dropRename, 'remove'));
     $updateResult = new SchemaUpdateResult();
     foreach ($schemaUpdateTypes as $schemaUpdateType) {
         $statementTypes = $this->getStatementTypes($schemaUpdateType);
         foreach ($statementTypes as $statementType) {
             if (isset($updateStatements[$statementType])) {
                 $statements = $updateStatements[$statementType];
                 $result = $this->schemaMigrationService->performUpdateQueries($statements, array_combine(array_keys($statements), array_fill(0, count($statements), TRUE)));
                 if ($result === TRUE) {
                     $updateResult->addPerformedUpdates($schemaUpdateType, count($statements));
                 } elseif (is_array($result)) {
                     $updateResult->addErrors($schemaUpdateType, $result);
                 }
             }
         }
     }
     return $updateResult;
 }
 /**
  * @test
  */
 public function columnAndKeyDeletionDoesNotReturnAnError()
 {
     // Get the current database fields.
     $currentDatabaseSchema = $this->sqlSchemaMigrationService->getFieldDefinitions_database();
     // Limit our scope to the be_users table:
     $currentDatabaseSchemaForBeUsers = array();
     $currentDatabaseSchemaForBeUsers['be_users'] = $currentDatabaseSchema['be_users'];
     unset($currentDatabaseSchema);
     // Create a key and a field that belongs to that key:
     $expectedDatabaseSchemaForBeUsers = $currentDatabaseSchemaForBeUsers;
     $expectedDatabaseSchemaForBeUsers['be_users']['fields']['functional_test_field_1'] = "tinyint(1) unsigned NOT NULL default '0'";
     $expectedDatabaseSchemaForBeUsers['be_users']['keys']['functional_test_key_1'] = 'KEY functional_test_key_1 (functional_test_field_1)';
     $createFieldDiff = $this->sqlSchemaMigrationService->getDatabaseExtra($expectedDatabaseSchemaForBeUsers, $currentDatabaseSchemaForBeUsers);
     $createFieldDiff = $this->sqlSchemaMigrationService->getUpdateSuggestions($createFieldDiff);
     $this->sqlSchemaMigrationService->performUpdateQueries($createFieldDiff['add'], $createFieldDiff['add']);
     // Now remove the fields again (without the renaming step).
     unset($currentDatabaseSchemaForBeUsers['be_users']['fields']['functional_test_field_1']);
     unset($currentDatabaseSchemaForBeUsers['be_users']['keys']['functional_test_key_1']);
     $this->sqlSchemaMigrationService->setDeletedPrefixKey('');
     $removeFieldDiff = $this->sqlSchemaMigrationService->getDatabaseExtra($expectedDatabaseSchemaForBeUsers, $currentDatabaseSchemaForBeUsers);
     $removeFieldDiff = $this->sqlSchemaMigrationService->getUpdateSuggestions($removeFieldDiff, 'remove');
     $result = $this->sqlSchemaMigrationService->performUpdateQueries($removeFieldDiff['drop'], $removeFieldDiff['drop']);
     $this->assertTrue($result, 'performUpdateQueries() did not return TRUE, this means an error occurred: ' . (is_array($result) ? array_pop($result) : ''));
 }