Completed
Pull Request — master (#4514)
by Joas
17:05
created
core/Command/Db/ConvertMysqlToMB4.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -34,59 +34,59 @@
 block discarded – undo
34 34
 use Symfony\Component\Console\Output\OutputInterface;
35 35
 
36 36
 class ConvertMysqlToMB4 extends Command {
37
-	/** @var IConfig */
38
-	private $config;
37
+    /** @var IConfig */
38
+    private $config;
39 39
 
40
-	/** @var IDBConnection */
41
-	private $connection;
40
+    /** @var IDBConnection */
41
+    private $connection;
42 42
 
43
-	/** @var IURLGenerator */
44
-	private $urlGenerator;
43
+    /** @var IURLGenerator */
44
+    private $urlGenerator;
45 45
 
46
-	/** @var ILogger */
47
-	private $logger;
46
+    /** @var ILogger */
47
+    private $logger;
48 48
 
49
-	/**
50
-	 * @param IConfig $config
51
-	 * @param IDBConnection $connection
52
-	 * @param IURLGenerator $urlGenerator
53
-	 * @param ILogger $logger
54
-	 */
55
-	public function __construct(IConfig $config, IDBConnection $connection, IURLGenerator $urlGenerator, ILogger $logger) {
56
-		$this->config = $config;
57
-		$this->connection = $connection;
58
-		$this->urlGenerator = $urlGenerator;
59
-		$this->logger = $logger;
60
-		parent::__construct();
61
-	}
49
+    /**
50
+     * @param IConfig $config
51
+     * @param IDBConnection $connection
52
+     * @param IURLGenerator $urlGenerator
53
+     * @param ILogger $logger
54
+     */
55
+    public function __construct(IConfig $config, IDBConnection $connection, IURLGenerator $urlGenerator, ILogger $logger) {
56
+        $this->config = $config;
57
+        $this->connection = $connection;
58
+        $this->urlGenerator = $urlGenerator;
59
+        $this->logger = $logger;
60
+        parent::__construct();
61
+    }
62 62
 
63
-	protected function configure() {
64
-		$this
65
-			->setName('db:convert-mysql-charset')
66
-			->setDescription('Convert charset of MySQL/MariaDB to use utf8mb4');
67
-	}
63
+    protected function configure() {
64
+        $this
65
+            ->setName('db:convert-mysql-charset')
66
+            ->setDescription('Convert charset of MySQL/MariaDB to use utf8mb4');
67
+    }
68 68
 
69
-	protected function execute(InputInterface $input, OutputInterface $output) {
70
-		if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
71
-			$output->writeln("This command is only valid for MySQL/MariaDB databases.");
72
-			return 1;
73
-		}
69
+    protected function execute(InputInterface $input, OutputInterface $output) {
70
+        if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
71
+            $output->writeln("This command is only valid for MySQL/MariaDB databases.");
72
+            return 1;
73
+        }
74 74
 
75
-		$tools = new MySqlTools();
76
-		if (!$tools->supports4ByteCharset($this->connection)) {
77
-			$url = $this->urlGenerator->linkToDocs('admin-mysql-utf8mb4');
78
-			$output->writeln("The database is not properly setup to use the charset utf8mb4.");
79
-			$output->writeln("For more information please read the documentation at $url");
80
-			return 1;
81
-		}
75
+        $tools = new MySqlTools();
76
+        if (!$tools->supports4ByteCharset($this->connection)) {
77
+            $url = $this->urlGenerator->linkToDocs('admin-mysql-utf8mb4');
78
+            $output->writeln("The database is not properly setup to use the charset utf8mb4.");
79
+            $output->writeln("For more information please read the documentation at $url");
80
+            return 1;
81
+        }
82 82
 
83
-		// enable charset
84
-		$this->config->setSystemValue('mysql.utf8mb4', true);
83
+        // enable charset
84
+        $this->config->setSystemValue('mysql.utf8mb4', true);
85 85
 
86
-		// run conversion
87
-		$coll = new Collation($this->config, $this->logger, $this->connection, false);
88
-		$coll->run(new ConsoleOutput($output));
86
+        // run conversion
87
+        $coll = new Collation($this->config, $this->logger, $this->connection, false);
88
+        $coll->run(new ConsoleOutput($output));
89 89
 
90
-		return 0;
91
-	}
90
+        return 0;
91
+    }
92 92
 }
Please login to merge, or discard this patch.
lib/private/Repair/Collation.php 1 patch
Indentation   +118 added lines, -118 removed lines patch added patch discarded remove patch
@@ -33,123 +33,123 @@
 block discarded – undo
33 33
 use OCP\Migration\IRepairStep;
34 34
 
35 35
 class Collation implements IRepairStep {
36
-	/**  @var IConfig */
37
-	protected $config;
38
-
39
-	/** @var ILogger */
40
-	protected $logger;
41
-
42
-	/** @var IDBConnection */
43
-	protected $connection;
44
-
45
-	/** @var bool */
46
-	protected $ignoreFailures;
47
-
48
-	/**
49
-	 * @param IConfig $config
50
-	 * @param ILogger $logger
51
-	 * @param IDBConnection $connection
52
-	 * @param bool $ignoreFailures
53
-	 */
54
-	public function __construct(IConfig $config, ILogger $logger, IDBConnection $connection, $ignoreFailures) {
55
-		$this->connection = $connection;
56
-		$this->config = $config;
57
-		$this->logger = $logger;
58
-		$this->ignoreFailures = $ignoreFailures;
59
-	}
60
-
61
-	public function getName() {
62
-		return 'Repair MySQL collation';
63
-	}
64
-
65
-	/**
66
-	 * Fix mime types
67
-	 */
68
-	public function run(IOutput $output) {
69
-		if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
70
-			$output->info('Not a mysql database -> nothing to do');
71
-			return;
72
-		}
73
-
74
-		$characterSet = $this->config->getSystemValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
75
-
76
-		$tables = $this->getAllNonUTF8BinTables($this->connection);
77
-		foreach ($tables as $table) {
78
-			$output->info("Change row format for $table ...");
79
-			$query = $this->connection->prepare('ALTER TABLE `' . $table . '` ROW_FORMAT = DYNAMIC;');
80
-			try {
81
-				$query->execute();
82
-			} catch (DriverException $e) {
83
-				// Just log this
84
-				$this->logger->logException($e);
85
-				if (!$this->ignoreFailures) {
86
-					throw $e;
87
-				}
88
-			}
89
-
90
-			$output->info("Change collation for $table ...");
91
-			if ($characterSet === 'utf8mb4') {
92
-				// need to set row compression first
93
-				$query = $this->connection->prepare('ALTER TABLE `' . $table . '` ROW_FORMAT=COMPRESSED;');
94
-				$query->execute();
95
-			}
96
-			$query = $this->connection->prepare('ALTER TABLE `' . $table . '` CONVERT TO CHARACTER SET ' . $characterSet . ' COLLATE ' . $characterSet . '_bin;');
97
-			try {
98
-				$query->execute();
99
-			} catch (DriverException $e) {
100
-				// Just log this
101
-				$this->logger->logException($e);
102
-				if (!$this->ignoreFailures) {
103
-					throw $e;
104
-				}
105
-			}
106
-		}
107
-		if (empty($tables)) {
108
-			$output->info('All tables already have the correct collation -> nothing to do');
109
-		}
110
-		if (empty($tables)) {
111
-			$output->info('All tables already have the correct collation -> nothing to do');
112
-		}
113
-	}
114
-
115
-	/**
116
-	 * @param IDBConnection $connection
117
-	 * @return string[]
118
-	 */
119
-	protected function getAllNonUTF8BinTables(IDBConnection $connection) {
120
-		$dbName = $this->config->getSystemValue("dbname");
121
-		$characterSet = $this->config->getSystemValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
122
-
123
-		// fetch tables by columns
124
-		$statement = $connection->executeQuery(
125
-			"SELECT DISTINCT(TABLE_NAME) AS `table`" .
126
-			"	FROM INFORMATION_SCHEMA . COLUMNS" .
127
-			"	WHERE TABLE_SCHEMA = ?" .
128
-			"	AND (COLLATION_NAME <> '" . $characterSet . "_bin' OR CHARACTER_SET_NAME <> '" . $characterSet . "')" .
129
-			"	AND TABLE_NAME LIKE \"*PREFIX*%\"",
130
-			array($dbName)
131
-		);
132
-		$rows = $statement->fetchAll();
133
-		$result = [];
134
-		foreach ($rows as $row) {
135
-			$result[$row['table']] = true;
136
-		}
137
-
138
-		// fetch tables by collation
139
-		$statement = $connection->executeQuery(
140
-			"SELECT DISTINCT(TABLE_NAME) AS `table`" .
141
-			"	FROM INFORMATION_SCHEMA . TABLES" .
142
-			"	WHERE TABLE_SCHEMA = ?" .
143
-			"	AND TABLE_COLLATION <> '" . $characterSet . "_bin'" .
144
-			"	AND TABLE_NAME LIKE \"*PREFIX*%\"",
145
-			[$dbName]
146
-		);
147
-		$rows = $statement->fetchAll();
148
-		foreach ($rows as $row) {
149
-			$result[$row['table']] = true;
150
-		}
151
-
152
-		return array_keys($result);
153
-	}
36
+    /**  @var IConfig */
37
+    protected $config;
38
+
39
+    /** @var ILogger */
40
+    protected $logger;
41
+
42
+    /** @var IDBConnection */
43
+    protected $connection;
44
+
45
+    /** @var bool */
46
+    protected $ignoreFailures;
47
+
48
+    /**
49
+     * @param IConfig $config
50
+     * @param ILogger $logger
51
+     * @param IDBConnection $connection
52
+     * @param bool $ignoreFailures
53
+     */
54
+    public function __construct(IConfig $config, ILogger $logger, IDBConnection $connection, $ignoreFailures) {
55
+        $this->connection = $connection;
56
+        $this->config = $config;
57
+        $this->logger = $logger;
58
+        $this->ignoreFailures = $ignoreFailures;
59
+    }
60
+
61
+    public function getName() {
62
+        return 'Repair MySQL collation';
63
+    }
64
+
65
+    /**
66
+     * Fix mime types
67
+     */
68
+    public function run(IOutput $output) {
69
+        if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
70
+            $output->info('Not a mysql database -> nothing to do');
71
+            return;
72
+        }
73
+
74
+        $characterSet = $this->config->getSystemValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
75
+
76
+        $tables = $this->getAllNonUTF8BinTables($this->connection);
77
+        foreach ($tables as $table) {
78
+            $output->info("Change row format for $table ...");
79
+            $query = $this->connection->prepare('ALTER TABLE `' . $table . '` ROW_FORMAT = DYNAMIC;');
80
+            try {
81
+                $query->execute();
82
+            } catch (DriverException $e) {
83
+                // Just log this
84
+                $this->logger->logException($e);
85
+                if (!$this->ignoreFailures) {
86
+                    throw $e;
87
+                }
88
+            }
89
+
90
+            $output->info("Change collation for $table ...");
91
+            if ($characterSet === 'utf8mb4') {
92
+                // need to set row compression first
93
+                $query = $this->connection->prepare('ALTER TABLE `' . $table . '` ROW_FORMAT=COMPRESSED;');
94
+                $query->execute();
95
+            }
96
+            $query = $this->connection->prepare('ALTER TABLE `' . $table . '` CONVERT TO CHARACTER SET ' . $characterSet . ' COLLATE ' . $characterSet . '_bin;');
97
+            try {
98
+                $query->execute();
99
+            } catch (DriverException $e) {
100
+                // Just log this
101
+                $this->logger->logException($e);
102
+                if (!$this->ignoreFailures) {
103
+                    throw $e;
104
+                }
105
+            }
106
+        }
107
+        if (empty($tables)) {
108
+            $output->info('All tables already have the correct collation -> nothing to do');
109
+        }
110
+        if (empty($tables)) {
111
+            $output->info('All tables already have the correct collation -> nothing to do');
112
+        }
113
+    }
114
+
115
+    /**
116
+     * @param IDBConnection $connection
117
+     * @return string[]
118
+     */
119
+    protected function getAllNonUTF8BinTables(IDBConnection $connection) {
120
+        $dbName = $this->config->getSystemValue("dbname");
121
+        $characterSet = $this->config->getSystemValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
122
+
123
+        // fetch tables by columns
124
+        $statement = $connection->executeQuery(
125
+            "SELECT DISTINCT(TABLE_NAME) AS `table`" .
126
+            "	FROM INFORMATION_SCHEMA . COLUMNS" .
127
+            "	WHERE TABLE_SCHEMA = ?" .
128
+            "	AND (COLLATION_NAME <> '" . $characterSet . "_bin' OR CHARACTER_SET_NAME <> '" . $characterSet . "')" .
129
+            "	AND TABLE_NAME LIKE \"*PREFIX*%\"",
130
+            array($dbName)
131
+        );
132
+        $rows = $statement->fetchAll();
133
+        $result = [];
134
+        foreach ($rows as $row) {
135
+            $result[$row['table']] = true;
136
+        }
137
+
138
+        // fetch tables by collation
139
+        $statement = $connection->executeQuery(
140
+            "SELECT DISTINCT(TABLE_NAME) AS `table`" .
141
+            "	FROM INFORMATION_SCHEMA . TABLES" .
142
+            "	WHERE TABLE_SCHEMA = ?" .
143
+            "	AND TABLE_COLLATION <> '" . $characterSet . "_bin'" .
144
+            "	AND TABLE_NAME LIKE \"*PREFIX*%\"",
145
+            [$dbName]
146
+        );
147
+        $rows = $statement->fetchAll();
148
+        foreach ($rows as $row) {
149
+            $result[$row['table']] = true;
150
+        }
151
+
152
+        return array_keys($result);
153
+    }
154 154
 }
155 155
 
Please login to merge, or discard this patch.
lib/private/DB/MySqlTools.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -28,22 +28,22 @@
 block discarded – undo
28 28
 */
29 29
 class MySqlTools {
30 30
 
31
-	/**
32
-	 * @param Connection $connection
33
-	 * @return bool
34
-	 */
35
-	public function supports4ByteCharset(IDBConnection $connection) {
36
-		foreach (['innodb_file_format' => 'Barracuda', 'innodb_large_prefix' => 'ON', 'innodb_file_per_table' => 'ON'] as $var => $val) {
37
-			$result = $connection->executeQuery("SHOW VARIABLES LIKE '$var'");
38
-			$rows = $result->fetch();
39
-			$result->closeCursor();
40
-			if ($rows === false) {
41
-				return false;
42
-			}
43
-			if (strcasecmp($rows['Value'], $val) !== 0) {
44
-				return false;
45
-			}
46
-		}
47
-		return true;
48
-	}
31
+    /**
32
+     * @param Connection $connection
33
+     * @return bool
34
+     */
35
+    public function supports4ByteCharset(IDBConnection $connection) {
36
+        foreach (['innodb_file_format' => 'Barracuda', 'innodb_large_prefix' => 'ON', 'innodb_file_per_table' => 'ON'] as $var => $val) {
37
+            $result = $connection->executeQuery("SHOW VARIABLES LIKE '$var'");
38
+            $rows = $result->fetch();
39
+            $result->closeCursor();
40
+            if ($rows === false) {
41
+                return false;
42
+            }
43
+            if (strcasecmp($rows['Value'], $val) !== 0) {
44
+                return false;
45
+            }
46
+        }
47
+        return true;
48
+    }
49 49
 }
Please login to merge, or discard this patch.
lib/private/Setup/MySQL.php 1 patch
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -31,143 +31,143 @@
 block discarded – undo
31 31
 use OCP\IDBConnection;
32 32
 
33 33
 class MySQL extends AbstractDatabase {
34
-	public $dbprettyname = 'MySQL/MariaDB';
35
-
36
-	public function setupDatabase($username) {
37
-		//check if the database user has admin right
38
-		$connection = $this->connect(['dbname' => null]);
39
-
40
-		// detect mb4
41
-		$tools = new MySqlTools();
42
-		if ($tools->supports4ByteCharset($connection)) {
43
-			$this->config->setValue('mysql.utf8mb4', true);
44
-			$connection = $this->connect();
45
-		}
46
-
47
-		$this->createSpecificUser($username, $connection);
48
-
49
-		//create the database
50
-		$this->createDatabase($connection);
51
-
52
-		//fill the database if needed
53
-		$query='select count(*) from information_schema.tables where table_schema=? AND table_name = ?';
54
-		$result = $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']);
55
-		$row = $result->fetch();
56
-		if (!$row or $row['count(*)'] === '0') {
57
-			\OC_DB::createDbFromStructure($this->dbDefinitionFile);
58
-		}
59
-	}
60
-
61
-	/**
62
-	 * @param \OC\DB\Connection $connection
63
-	 */
64
-	private function createDatabase($connection) {
65
-		try{
66
-			$name = $this->dbName;
67
-			$user = $this->dbUser;
68
-			//we can't use OC_DB functions here because we need to connect as the administrative user.
69
-			$characterSet = $this->config->getValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
70
-			$query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET $characterSet COLLATE ${characterSet}_bin;";
71
-			$connection->executeUpdate($query);
72
-		} catch (\Exception $ex) {
73
-			$this->logger->error('Database creation failed: {error}', [
74
-				'app' => 'mysql.setup',
75
-				'error' => $ex->getMessage()
76
-			]);
77
-			return;
78
-		}
79
-
80
-		try {
81
-			//this query will fail if there aren't the right permissions, ignore the error
82
-			$query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'";
83
-			$connection->executeUpdate($query);
84
-		} catch (\Exception $ex) {
85
-			$this->logger->debug('Could not automatically grant privileges, this can be ignored if database user already had privileges: {error}', [
86
-				'app' => 'mysql.setup',
87
-				'error' => $ex->getMessage()
88
-			]);
89
-		}
90
-	}
91
-
92
-	/**
93
-	 * @param IDBConnection $connection
94
-	 * @throws \OC\DatabaseSetupException
95
-	 */
96
-	private function createDBUser($connection) {
97
-		try{
98
-			$name = $this->dbUser;
99
-			$password = $this->dbPassword;
100
-			// we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one,
101
-			// the anonymous user would take precedence when there is one.
102
-			$query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
103
-			$connection->executeUpdate($query);
104
-			$query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
105
-			$connection->executeUpdate($query);
106
-		}
107
-		catch (\Exception $ex){
108
-			$this->logger->error('Database User creation failed: {error}', [
34
+    public $dbprettyname = 'MySQL/MariaDB';
35
+
36
+    public function setupDatabase($username) {
37
+        //check if the database user has admin right
38
+        $connection = $this->connect(['dbname' => null]);
39
+
40
+        // detect mb4
41
+        $tools = new MySqlTools();
42
+        if ($tools->supports4ByteCharset($connection)) {
43
+            $this->config->setValue('mysql.utf8mb4', true);
44
+            $connection = $this->connect();
45
+        }
46
+
47
+        $this->createSpecificUser($username, $connection);
48
+
49
+        //create the database
50
+        $this->createDatabase($connection);
51
+
52
+        //fill the database if needed
53
+        $query='select count(*) from information_schema.tables where table_schema=? AND table_name = ?';
54
+        $result = $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']);
55
+        $row = $result->fetch();
56
+        if (!$row or $row['count(*)'] === '0') {
57
+            \OC_DB::createDbFromStructure($this->dbDefinitionFile);
58
+        }
59
+    }
60
+
61
+    /**
62
+     * @param \OC\DB\Connection $connection
63
+     */
64
+    private function createDatabase($connection) {
65
+        try{
66
+            $name = $this->dbName;
67
+            $user = $this->dbUser;
68
+            //we can't use OC_DB functions here because we need to connect as the administrative user.
69
+            $characterSet = $this->config->getValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
70
+            $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET $characterSet COLLATE ${characterSet}_bin;";
71
+            $connection->executeUpdate($query);
72
+        } catch (\Exception $ex) {
73
+            $this->logger->error('Database creation failed: {error}', [
74
+                'app' => 'mysql.setup',
75
+                'error' => $ex->getMessage()
76
+            ]);
77
+            return;
78
+        }
79
+
80
+        try {
81
+            //this query will fail if there aren't the right permissions, ignore the error
82
+            $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'";
83
+            $connection->executeUpdate($query);
84
+        } catch (\Exception $ex) {
85
+            $this->logger->debug('Could not automatically grant privileges, this can be ignored if database user already had privileges: {error}', [
86
+                'app' => 'mysql.setup',
87
+                'error' => $ex->getMessage()
88
+            ]);
89
+        }
90
+    }
91
+
92
+    /**
93
+     * @param IDBConnection $connection
94
+     * @throws \OC\DatabaseSetupException
95
+     */
96
+    private function createDBUser($connection) {
97
+        try{
98
+            $name = $this->dbUser;
99
+            $password = $this->dbPassword;
100
+            // we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one,
101
+            // the anonymous user would take precedence when there is one.
102
+            $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
103
+            $connection->executeUpdate($query);
104
+            $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
105
+            $connection->executeUpdate($query);
106
+        }
107
+        catch (\Exception $ex){
108
+            $this->logger->error('Database User creation failed: {error}', [
109 109
                                 'app' => 'mysql.setup',
110 110
                                 'error' => $ex->getMessage()
111 111
                         ]);
112
-		}
113
-	}
114
-
115
-	/**
116
-	 * @param $username
117
-	 * @param IDBConnection $connection
118
-	 * @return array
119
-	 */
120
-	private function createSpecificUser($username, $connection) {
121
-		try {
122
-			//user already specified in config
123
-			$oldUser = $this->config->getValue('dbuser', false);
124
-
125
-			//we don't have a dbuser specified in config
126
-			if ($this->dbUser !== $oldUser) {
127
-				//add prefix to the admin username to prevent collisions
128
-				$adminUser = substr('oc_' . $username, 0, 16);
129
-
130
-				$i = 1;
131
-				while (true) {
132
-					//this should be enough to check for admin rights in mysql
133
-					$query = 'SELECT user FROM mysql.user WHERE user=?';
134
-					$result = $connection->executeQuery($query, [$adminUser]);
135
-
136
-					//current dbuser has admin rights
137
-					if ($result) {
138
-						$data = $result->fetchAll();
139
-						//new dbuser does not exist
140
-						if (count($data) === 0) {
141
-							//use the admin login data for the new database user
142
-							$this->dbUser = $adminUser;
143
-
144
-							//create a random password so we don't need to store the admin password in the config file
145
-							$this->dbPassword =  $this->random->generate(30);
146
-
147
-							$this->createDBUser($connection);
148
-
149
-							break;
150
-						} else {
151
-							//repeat with different username
152
-							$length = strlen((string)$i);
153
-							$adminUser = substr('oc_' . $username, 0, 16 - $length) . $i;
154
-							$i++;
155
-						}
156
-					} else {
157
-						break;
158
-					}
159
-				};
160
-			}
161
-		} catch (\Exception $ex) {
162
-			$this->logger->info('Can not create a new MySQL user, will continue with the provided user: {error}', [
163
-				'app' => 'mysql.setup',
164
-				'error' => $ex->getMessage()
165
-			]);
166
-		}
167
-
168
-		$this->config->setValues([
169
-			'dbuser' => $this->dbUser,
170
-			'dbpassword' => $this->dbPassword,
171
-		]);
172
-	}
112
+        }
113
+    }
114
+
115
+    /**
116
+     * @param $username
117
+     * @param IDBConnection $connection
118
+     * @return array
119
+     */
120
+    private function createSpecificUser($username, $connection) {
121
+        try {
122
+            //user already specified in config
123
+            $oldUser = $this->config->getValue('dbuser', false);
124
+
125
+            //we don't have a dbuser specified in config
126
+            if ($this->dbUser !== $oldUser) {
127
+                //add prefix to the admin username to prevent collisions
128
+                $adminUser = substr('oc_' . $username, 0, 16);
129
+
130
+                $i = 1;
131
+                while (true) {
132
+                    //this should be enough to check for admin rights in mysql
133
+                    $query = 'SELECT user FROM mysql.user WHERE user=?';
134
+                    $result = $connection->executeQuery($query, [$adminUser]);
135
+
136
+                    //current dbuser has admin rights
137
+                    if ($result) {
138
+                        $data = $result->fetchAll();
139
+                        //new dbuser does not exist
140
+                        if (count($data) === 0) {
141
+                            //use the admin login data for the new database user
142
+                            $this->dbUser = $adminUser;
143
+
144
+                            //create a random password so we don't need to store the admin password in the config file
145
+                            $this->dbPassword =  $this->random->generate(30);
146
+
147
+                            $this->createDBUser($connection);
148
+
149
+                            break;
150
+                        } else {
151
+                            //repeat with different username
152
+                            $length = strlen((string)$i);
153
+                            $adminUser = substr('oc_' . $username, 0, 16 - $length) . $i;
154
+                            $i++;
155
+                        }
156
+                    } else {
157
+                        break;
158
+                    }
159
+                };
160
+            }
161
+        } catch (\Exception $ex) {
162
+            $this->logger->info('Can not create a new MySQL user, will continue with the provided user: {error}', [
163
+                'app' => 'mysql.setup',
164
+                'error' => $ex->getMessage()
165
+            ]);
166
+        }
167
+
168
+        $this->config->setValues([
169
+            'dbuser' => $this->dbUser,
170
+            'dbpassword' => $this->dbPassword,
171
+        ]);
172
+    }
173 173
 }
Please login to merge, or discard this patch.