Completed
Pull Request — master (#5231)
by Joas
23:26 queued 08:22
created
core/Command/Db/Migrations/MigrateCommand.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -32,33 +32,33 @@
 block discarded – undo
32 32
 
33 33
 class MigrateCommand extends Command {
34 34
 
35
-	/** @var IDBConnection */
36
-	private $connection;
35
+    /** @var IDBConnection */
36
+    private $connection;
37 37
 
38
-	/**
39
-	 * @param IDBConnection $connection
40
-	 */
41
-	public function __construct(IDBConnection $connection) {
42
-		$this->connection = $connection;
43
-		parent::__construct();
44
-	}
38
+    /**
39
+     * @param IDBConnection $connection
40
+     */
41
+    public function __construct(IDBConnection $connection) {
42
+        $this->connection = $connection;
43
+        parent::__construct();
44
+    }
45 45
 
46
-	protected function configure() {
47
-		$this
48
-			->setName('migrations:migrate')
49
-			->setDescription('Execute a migration to a specified version or the latest available version.')
50
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
51
-			->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest');
46
+    protected function configure() {
47
+        $this
48
+            ->setName('migrations:migrate')
49
+            ->setDescription('Execute a migration to a specified version or the latest available version.')
50
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
51
+            ->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest');
52 52
 
53
-		parent::configure();
54
-	}
53
+        parent::configure();
54
+    }
55 55
 
56
-	public function execute(InputInterface $input, OutputInterface $output) {
57
-		$appName = $input->getArgument('app');
58
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
59
-		$version = $input->getArgument('version');
56
+    public function execute(InputInterface $input, OutputInterface $output) {
57
+        $appName = $input->getArgument('app');
58
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
59
+        $version = $input->getArgument('version');
60 60
 
61
-		$ms->migrate($version);
62
-	}
61
+        $ms->migrate($version);
62
+    }
63 63
 
64 64
 }
Please login to merge, or discard this patch.
core/Command/Db/Migrations/ExecuteCommand.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -36,57 +36,57 @@
 block discarded – undo
36 36
 
37 37
 class ExecuteCommand extends Command {
38 38
 
39
-	/** @var IDBConnection */
40
-	private $connection;
41
-	/** @var IConfig */
42
-	private $config;
39
+    /** @var IDBConnection */
40
+    private $connection;
41
+    /** @var IConfig */
42
+    private $config;
43 43
 
44
-	/**
45
-	 * ExecuteCommand constructor.
46
-	 *
47
-	 * @param IDBConnection $connection
48
-	 * @param IConfig $config
49
-	 */
50
-	public function __construct(IDBConnection $connection, IConfig $config) {
51
-		$this->connection = $connection;
52
-		$this->config = $config;
44
+    /**
45
+     * ExecuteCommand constructor.
46
+     *
47
+     * @param IDBConnection $connection
48
+     * @param IConfig $config
49
+     */
50
+    public function __construct(IDBConnection $connection, IConfig $config) {
51
+        $this->connection = $connection;
52
+        $this->config = $config;
53 53
 
54
-		parent::__construct();
55
-	}
54
+        parent::__construct();
55
+    }
56 56
 
57
-	protected function configure() {
58
-		$this
59
-			->setName('migrations:execute')
60
-			->setDescription('Execute a single migration version manually.')
61
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
62
-			->addArgument('version', InputArgument::REQUIRED, 'The version to execute.', null);
57
+    protected function configure() {
58
+        $this
59
+            ->setName('migrations:execute')
60
+            ->setDescription('Execute a single migration version manually.')
61
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
62
+            ->addArgument('version', InputArgument::REQUIRED, 'The version to execute.', null);
63 63
 
64
-		parent::configure();
65
-	}
64
+        parent::configure();
65
+    }
66 66
 
67
-	/**
68
-	 * @param InputInterface $input
69
-	 * @param OutputInterface $output
70
-	 * @return int
71
-	 */
72
-	public function execute(InputInterface $input, OutputInterface $output) {
73
-		$appName = $input->getArgument('app');
74
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
75
-		$version = $input->getArgument('version');
67
+    /**
68
+     * @param InputInterface $input
69
+     * @param OutputInterface $output
70
+     * @return int
71
+     */
72
+    public function execute(InputInterface $input, OutputInterface $output) {
73
+        $appName = $input->getArgument('app');
74
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
75
+        $version = $input->getArgument('version');
76 76
 
77
-		if ($this->config->getSystemValue('debug', false) === false) {
78
-			$olderVersions = $ms->getMigratedVersions();
79
-			$olderVersions[] = '0';
80
-			$olderVersions[] = 'prev';
81
-			if (in_array($version,  $olderVersions, true)) {
82
-				$output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83
-				return 1;
84
-			}
85
-		}
77
+        if ($this->config->getSystemValue('debug', false) === false) {
78
+            $olderVersions = $ms->getMigratedVersions();
79
+            $olderVersions[] = '0';
80
+            $olderVersions[] = 'prev';
81
+            if (in_array($version,  $olderVersions, true)) {
82
+                $output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83
+                return 1;
84
+            }
85
+        }
86 86
 
87 87
 
88
-		$ms->executeStep($version);
89
-		return 0;
90
-	}
88
+        $ms->executeStep($version);
89
+        return 0;
90
+    }
91 91
 
92 92
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@
 block discarded – undo
78 78
 			$olderVersions = $ms->getMigratedVersions();
79 79
 			$olderVersions[] = '0';
80 80
 			$olderVersions[] = 'prev';
81
-			if (in_array($version,  $olderVersions, true)) {
81
+			if (in_array($version, $olderVersions, true)) {
82 82
 				$output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83 83
 				return 1;
84 84
 			}
Please login to merge, or discard this patch.
core/Command/Db/Migrations/StatusCommand.php 2 patches
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -31,85 +31,85 @@
 block discarded – undo
31 31
 
32 32
 class StatusCommand extends Command {
33 33
 
34
-	/** @var IDBConnection */
35
-	private $connection;
36
-
37
-	/**
38
-	 * @param IDBConnection $connection
39
-	 */
40
-	public function __construct(IDBConnection $connection) {
41
-		$this->connection = $connection;
42
-		parent::__construct();
43
-	}
44
-
45
-	protected function configure() {
46
-		$this
47
-			->setName('migrations:status')
48
-			->setDescription('View the status of a set of migrations.')
49
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on');
50
-	}
51
-
52
-	public function execute(InputInterface $input, OutputInterface $output) {
53
-		$appName = $input->getArgument('app');
54
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
55
-
56
-		$infos = $this->getMigrationsInfos($ms);
57
-		foreach ($infos as $key => $value) {
58
-			$output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
59
-		}
60
-	}
61
-
62
-	/**
63
-	 * @param MigrationService $ms
64
-	 * @return array associative array of human readable info name as key and the actual information as value
65
-	 */
66
-	public function getMigrationsInfos(MigrationService $ms) {
67
-
68
-		$executedMigrations = $ms->getMigratedVersions();
69
-		$availableMigrations = $ms->getAvailableVersions();
70
-		$executedUnavailableMigrations = array_diff($executedMigrations, array_keys($availableMigrations));
71
-
72
-		$numExecutedUnavailableMigrations = count($executedUnavailableMigrations);
73
-		$numNewMigrations = count(array_diff(array_keys($availableMigrations), $executedMigrations));
74
-
75
-		$infos = [
76
-			'App'								=> $ms->getApp(),
77
-			'Version Table Name'				=> $ms->getMigrationsTableName(),
78
-			'Migrations Namespace'				=> $ms->getMigrationsNamespace(),
79
-			'Migrations Directory'				=> $ms->getMigrationsDirectory(),
80
-			'Previous Version'					=> $this->getFormattedVersionAlias($ms, 'prev'),
81
-			'Current Version'					=> $this->getFormattedVersionAlias($ms, 'current'),
82
-			'Next Version'						=> $this->getFormattedVersionAlias($ms, 'next'),
83
-			'Latest Version'					=> $this->getFormattedVersionAlias($ms, 'latest'),
84
-			'Executed Migrations'				=> count($executedMigrations),
85
-			'Executed Unavailable Migrations'	=> $numExecutedUnavailableMigrations,
86
-			'Available Migrations'				=> count($availableMigrations),
87
-			'New Migrations'					=> $numNewMigrations,
88
-		];
89
-
90
-		return $infos;
91
-	}
92
-
93
-	/**
94
-	 * @param MigrationService $migrationService
95
-	 * @param string $alias
96
-	 * @return mixed|null|string
97
-	 */
98
-	private function getFormattedVersionAlias(MigrationService $migrationService, $alias) {
99
-		$migration = $migrationService->getMigration($alias);
100
-		//No version found
101
-		if ($migration === null) {
102
-			if ($alias === 'next') {
103
-				return 'Already at latest migration step';
104
-			}
105
-
106
-			if ($alias === 'prev') {
107
-				return 'Already at first migration step';
108
-			}
109
-		}
110
-
111
-		return $migration;
112
-	}
34
+    /** @var IDBConnection */
35
+    private $connection;
36
+
37
+    /**
38
+     * @param IDBConnection $connection
39
+     */
40
+    public function __construct(IDBConnection $connection) {
41
+        $this->connection = $connection;
42
+        parent::__construct();
43
+    }
44
+
45
+    protected function configure() {
46
+        $this
47
+            ->setName('migrations:status')
48
+            ->setDescription('View the status of a set of migrations.')
49
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on');
50
+    }
51
+
52
+    public function execute(InputInterface $input, OutputInterface $output) {
53
+        $appName = $input->getArgument('app');
54
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
55
+
56
+        $infos = $this->getMigrationsInfos($ms);
57
+        foreach ($infos as $key => $value) {
58
+            $output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
59
+        }
60
+    }
61
+
62
+    /**
63
+     * @param MigrationService $ms
64
+     * @return array associative array of human readable info name as key and the actual information as value
65
+     */
66
+    public function getMigrationsInfos(MigrationService $ms) {
67
+
68
+        $executedMigrations = $ms->getMigratedVersions();
69
+        $availableMigrations = $ms->getAvailableVersions();
70
+        $executedUnavailableMigrations = array_diff($executedMigrations, array_keys($availableMigrations));
71
+
72
+        $numExecutedUnavailableMigrations = count($executedUnavailableMigrations);
73
+        $numNewMigrations = count(array_diff(array_keys($availableMigrations), $executedMigrations));
74
+
75
+        $infos = [
76
+            'App'								=> $ms->getApp(),
77
+            'Version Table Name'				=> $ms->getMigrationsTableName(),
78
+            'Migrations Namespace'				=> $ms->getMigrationsNamespace(),
79
+            'Migrations Directory'				=> $ms->getMigrationsDirectory(),
80
+            'Previous Version'					=> $this->getFormattedVersionAlias($ms, 'prev'),
81
+            'Current Version'					=> $this->getFormattedVersionAlias($ms, 'current'),
82
+            'Next Version'						=> $this->getFormattedVersionAlias($ms, 'next'),
83
+            'Latest Version'					=> $this->getFormattedVersionAlias($ms, 'latest'),
84
+            'Executed Migrations'				=> count($executedMigrations),
85
+            'Executed Unavailable Migrations'	=> $numExecutedUnavailableMigrations,
86
+            'Available Migrations'				=> count($availableMigrations),
87
+            'New Migrations'					=> $numNewMigrations,
88
+        ];
89
+
90
+        return $infos;
91
+    }
92
+
93
+    /**
94
+     * @param MigrationService $migrationService
95
+     * @param string $alias
96
+     * @return mixed|null|string
97
+     */
98
+    private function getFormattedVersionAlias(MigrationService $migrationService, $alias) {
99
+        $migration = $migrationService->getMigration($alias);
100
+        //No version found
101
+        if ($migration === null) {
102
+            if ($alias === 'next') {
103
+                return 'Already at latest migration step';
104
+            }
105
+
106
+            if ($alias === 'prev') {
107
+                return 'Already at first migration step';
108
+            }
109
+        }
110
+
111
+        return $migration;
112
+    }
113 113
 
114 114
 
115 115
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@
 block discarded – undo
55 55
 
56 56
 		$infos = $this->getMigrationsInfos($ms);
57 57
 		foreach ($infos as $key => $value) {
58
-			$output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
58
+			$output->writeln("    <comment>>></comment> $key: ".str_repeat(' ', 50 - strlen($key)).$value);
59 59
 		}
60 60
 	}
61 61
 
Please login to merge, or discard this patch.
core/register_command.php 1 patch
Indentation   +92 added lines, -92 removed lines patch added patch discarded remove patch
@@ -40,119 +40,119 @@
 block discarded – undo
40 40
 $application->add(new OC\Core\Command\App\CheckCode($infoParser));
41 41
 $application->add(new OC\Core\Command\L10n\CreateJs());
42 42
 $application->add(new \OC\Core\Command\Integrity\SignApp(
43
-		\OC::$server->getIntegrityCodeChecker(),
44
-		new \OC\IntegrityCheck\Helpers\FileAccessHelper(),
45
-		\OC::$server->getURLGenerator()
43
+        \OC::$server->getIntegrityCodeChecker(),
44
+        new \OC\IntegrityCheck\Helpers\FileAccessHelper(),
45
+        \OC::$server->getURLGenerator()
46 46
 ));
47 47
 $application->add(new \OC\Core\Command\Integrity\SignCore(
48
-		\OC::$server->getIntegrityCodeChecker(),
49
-		new \OC\IntegrityCheck\Helpers\FileAccessHelper()
48
+        \OC::$server->getIntegrityCodeChecker(),
49
+        new \OC\IntegrityCheck\Helpers\FileAccessHelper()
50 50
 ));
51 51
 $application->add(new \OC\Core\Command\Integrity\CheckApp(
52
-		\OC::$server->getIntegrityCodeChecker()
52
+        \OC::$server->getIntegrityCodeChecker()
53 53
 ));
54 54
 $application->add(new \OC\Core\Command\Integrity\CheckCore(
55
-		\OC::$server->getIntegrityCodeChecker()
55
+        \OC::$server->getIntegrityCodeChecker()
56 56
 ));
57 57
 
58 58
 
59 59
 if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
60
-	$application->add(new OC\Core\Command\App\Disable(\OC::$server->getAppManager()));
61
-	$application->add(new OC\Core\Command\App\Enable(\OC::$server->getAppManager()));
62
-	$application->add(new OC\Core\Command\App\GetPath());
63
-	$application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager()));
60
+    $application->add(new OC\Core\Command\App\Disable(\OC::$server->getAppManager()));
61
+    $application->add(new OC\Core\Command\App\Enable(\OC::$server->getAppManager()));
62
+    $application->add(new OC\Core\Command\App\GetPath());
63
+    $application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager()));
64 64
 	
65
-	$application->add(new OC\Core\Command\TwoFactorAuth\Enable(
66
-		\OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
67
-	));
68
-	$application->add(new OC\Core\Command\TwoFactorAuth\Disable(
69
-		\OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
70
-	));
65
+    $application->add(new OC\Core\Command\TwoFactorAuth\Enable(
66
+        \OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
67
+    ));
68
+    $application->add(new OC\Core\Command\TwoFactorAuth\Disable(
69
+        \OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
70
+    ));
71 71
 
72
-	$application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
73
-	$application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
74
-	$application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
72
+    $application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
73
+    $application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
74
+    $application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
75 75
 
76
-	$application->add(new OC\Core\Command\Config\App\DeleteConfig(\OC::$server->getConfig()));
77
-	$application->add(new OC\Core\Command\Config\App\GetConfig(\OC::$server->getConfig()));
78
-	$application->add(new OC\Core\Command\Config\App\SetConfig(\OC::$server->getConfig()));
79
-	$application->add(new OC\Core\Command\Config\Import(\OC::$server->getConfig()));
80
-	$application->add(new OC\Core\Command\Config\ListConfigs(\OC::$server->getSystemConfig(), \OC::$server->getAppConfig()));
81
-	$application->add(new OC\Core\Command\Config\System\DeleteConfig(\OC::$server->getSystemConfig()));
82
-	$application->add(new OC\Core\Command\Config\System\GetConfig(\OC::$server->getSystemConfig()));
83
-	$application->add(new OC\Core\Command\Config\System\SetConfig(\OC::$server->getSystemConfig()));
76
+    $application->add(new OC\Core\Command\Config\App\DeleteConfig(\OC::$server->getConfig()));
77
+    $application->add(new OC\Core\Command\Config\App\GetConfig(\OC::$server->getConfig()));
78
+    $application->add(new OC\Core\Command\Config\App\SetConfig(\OC::$server->getConfig()));
79
+    $application->add(new OC\Core\Command\Config\Import(\OC::$server->getConfig()));
80
+    $application->add(new OC\Core\Command\Config\ListConfigs(\OC::$server->getSystemConfig(), \OC::$server->getAppConfig()));
81
+    $application->add(new OC\Core\Command\Config\System\DeleteConfig(\OC::$server->getSystemConfig()));
82
+    $application->add(new OC\Core\Command\Config\System\GetConfig(\OC::$server->getSystemConfig()));
83
+    $application->add(new OC\Core\Command\Config\System\SetConfig(\OC::$server->getSystemConfig()));
84 84
 
85
-	$application->add(new OC\Core\Command\Db\GenerateChangeScript());
86
-	$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig())));
87
-	$application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger()));
88
-	$application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection()));
89
-	$application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection()));
90
-	$application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection()));
91
-	$application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()));
85
+    $application->add(new OC\Core\Command\Db\GenerateChangeScript());
86
+    $application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig())));
87
+    $application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger()));
88
+    $application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection()));
89
+    $application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection()));
90
+    $application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection()));
91
+    $application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()));
92 92
 
93
-	$application->add(new OC\Core\Command\Encryption\Disable(\OC::$server->getConfig()));
94
-	$application->add(new OC\Core\Command\Encryption\Enable(\OC::$server->getConfig(), \OC::$server->getEncryptionManager()));
95
-	$application->add(new OC\Core\Command\Encryption\ListModules(\OC::$server->getEncryptionManager()));
96
-	$application->add(new OC\Core\Command\Encryption\SetDefaultModule(\OC::$server->getEncryptionManager()));
97
-	$application->add(new OC\Core\Command\Encryption\Status(\OC::$server->getEncryptionManager()));
98
-	$application->add(new OC\Core\Command\Encryption\EncryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getAppManager(), \OC::$server->getConfig(), new \Symfony\Component\Console\Helper\QuestionHelper()));
99
-	$application->add(new OC\Core\Command\Encryption\DecryptAll(
100
-		\OC::$server->getEncryptionManager(),
101
-		\OC::$server->getAppManager(),
102
-		\OC::$server->getConfig(),
103
-		new \OC\Encryption\DecryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getUserManager(), new \OC\Files\View()),
104
-		new \Symfony\Component\Console\Helper\QuestionHelper())
105
-	);
93
+    $application->add(new OC\Core\Command\Encryption\Disable(\OC::$server->getConfig()));
94
+    $application->add(new OC\Core\Command\Encryption\Enable(\OC::$server->getConfig(), \OC::$server->getEncryptionManager()));
95
+    $application->add(new OC\Core\Command\Encryption\ListModules(\OC::$server->getEncryptionManager()));
96
+    $application->add(new OC\Core\Command\Encryption\SetDefaultModule(\OC::$server->getEncryptionManager()));
97
+    $application->add(new OC\Core\Command\Encryption\Status(\OC::$server->getEncryptionManager()));
98
+    $application->add(new OC\Core\Command\Encryption\EncryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getAppManager(), \OC::$server->getConfig(), new \Symfony\Component\Console\Helper\QuestionHelper()));
99
+    $application->add(new OC\Core\Command\Encryption\DecryptAll(
100
+        \OC::$server->getEncryptionManager(),
101
+        \OC::$server->getAppManager(),
102
+        \OC::$server->getConfig(),
103
+        new \OC\Encryption\DecryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getUserManager(), new \OC\Files\View()),
104
+        new \Symfony\Component\Console\Helper\QuestionHelper())
105
+    );
106 106
 
107
-	$application->add(new OC\Core\Command\Log\Manage(\OC::$server->getConfig()));
108
-	$application->add(new OC\Core\Command\Log\File(\OC::$server->getConfig()));
107
+    $application->add(new OC\Core\Command\Log\Manage(\OC::$server->getConfig()));
108
+    $application->add(new OC\Core\Command\Log\File(\OC::$server->getConfig()));
109 109
 
110
-	$view = new \OC\Files\View();
111
-	$util = new \OC\Encryption\Util(
112
-		$view,
113
-		\OC::$server->getUserManager(),
114
-		\OC::$server->getGroupManager(),
115
-		\OC::$server->getConfig()
116
-	);
117
-	$application->add(new OC\Core\Command\Encryption\ChangeKeyStorageRoot(
118
-			$view,
119
-			\OC::$server->getUserManager(),
120
-			\OC::$server->getConfig(),
121
-			$util,
122
-			new \Symfony\Component\Console\Helper\QuestionHelper()
123
-		)
124
-	);
125
-	$application->add(new OC\Core\Command\Encryption\ShowKeyStorageRoot($util));
110
+    $view = new \OC\Files\View();
111
+    $util = new \OC\Encryption\Util(
112
+        $view,
113
+        \OC::$server->getUserManager(),
114
+        \OC::$server->getGroupManager(),
115
+        \OC::$server->getConfig()
116
+    );
117
+    $application->add(new OC\Core\Command\Encryption\ChangeKeyStorageRoot(
118
+            $view,
119
+            \OC::$server->getUserManager(),
120
+            \OC::$server->getConfig(),
121
+            $util,
122
+            new \Symfony\Component\Console\Helper\QuestionHelper()
123
+        )
124
+    );
125
+    $application->add(new OC\Core\Command\Encryption\ShowKeyStorageRoot($util));
126 126
 
127
-	$application->add(new OC\Core\Command\Maintenance\DataFingerprint(\OC::$server->getConfig(), new \OC\AppFramework\Utility\TimeFactory()));
128
-	$application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateDB(\OC::$server->getMimeTypeDetector(), \OC::$server->getMimeTypeLoader()));
129
-	$application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateJS(\OC::$server->getMimeTypeDetector()));
130
-	$application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
131
-	$application->add(new OC\Core\Command\Maintenance\UpdateHtaccess());
127
+    $application->add(new OC\Core\Command\Maintenance\DataFingerprint(\OC::$server->getConfig(), new \OC\AppFramework\Utility\TimeFactory()));
128
+    $application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateDB(\OC::$server->getMimeTypeDetector(), \OC::$server->getMimeTypeLoader()));
129
+    $application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateJS(\OC::$server->getMimeTypeDetector()));
130
+    $application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
131
+    $application->add(new OC\Core\Command\Maintenance\UpdateHtaccess());
132 132
 
133
-	$application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger()));
134
-	$application->add(new OC\Core\Command\Maintenance\Repair(
135
-		new \OC\Repair(\OC\Repair::getRepairSteps(), \OC::$server->getEventDispatcher()), \OC::$server->getConfig(),
136
-		\OC::$server->getEventDispatcher()));
133
+    $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger()));
134
+    $application->add(new OC\Core\Command\Maintenance\Repair(
135
+        new \OC\Repair(\OC\Repair::getRepairSteps(), \OC::$server->getEventDispatcher()), \OC::$server->getConfig(),
136
+        \OC::$server->getEventDispatcher()));
137 137
 
138
-	$application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
139
-	$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
140
-	$application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
141
-	$application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));
142
-	$application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
143
-	$application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
144
-	$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
145
-	$application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
146
-	$application->add(new OC\Core\Command\User\ListCommand(\OC::$server->getUserManager()));
147
-	$application->add(new OC\Core\Command\User\Info(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
138
+    $application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
139
+    $application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
140
+    $application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
141
+    $application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));
142
+    $application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
143
+    $application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
144
+    $application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
145
+    $application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
146
+    $application->add(new OC\Core\Command\User\ListCommand(\OC::$server->getUserManager()));
147
+    $application->add(new OC\Core\Command\User\Info(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
148 148
 
149
-	$application->add(new OC\Core\Command\Group\ListCommand(\OC::$server->getGroupManager()));
150
-	$application->add(new OC\Core\Command\Group\AddUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
151
-	$application->add(new OC\Core\Command\Group\RemoveUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
149
+    $application->add(new OC\Core\Command\Group\ListCommand(\OC::$server->getGroupManager()));
150
+    $application->add(new OC\Core\Command\Group\AddUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
151
+    $application->add(new OC\Core\Command\Group\RemoveUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
152 152
 
153
-	$application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
154
-	$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
155
-	$application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
153
+    $application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
154
+    $application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
155
+    $application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
156 156
 } else {
157
-	$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
157
+    $application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
158 158
 }
Please login to merge, or discard this patch.
lib/private/Setup.php 1 patch
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -48,487 +48,487 @@
 block discarded – undo
48 48
 use OCP\Security\ISecureRandom;
49 49
 
50 50
 class Setup {
51
-	/** @var SystemConfig */
52
-	protected $config;
53
-	/** @var IniGetWrapper */
54
-	protected $iniWrapper;
55
-	/** @var IL10N */
56
-	protected $l10n;
57
-	/** @var Defaults */
58
-	protected $defaults;
59
-	/** @var ILogger */
60
-	protected $logger;
61
-	/** @var ISecureRandom */
62
-	protected $random;
63
-
64
-	/**
65
-	 * @param SystemConfig $config
66
-	 * @param IniGetWrapper $iniWrapper
67
-	 * @param IL10N $l10n
68
-	 * @param Defaults $defaults
69
-	 * @param ILogger $logger
70
-	 * @param ISecureRandom $random
71
-	 */
72
-	public function __construct(SystemConfig $config,
73
-						 IniGetWrapper $iniWrapper,
74
-						 IL10N $l10n,
75
-						 Defaults $defaults,
76
-						 ILogger $logger,
77
-						 ISecureRandom $random
78
-		) {
79
-		$this->config = $config;
80
-		$this->iniWrapper = $iniWrapper;
81
-		$this->l10n = $l10n;
82
-		$this->defaults = $defaults;
83
-		$this->logger = $logger;
84
-		$this->random = $random;
85
-	}
86
-
87
-	static $dbSetupClasses = [
88
-		'mysql' => \OC\Setup\MySQL::class,
89
-		'pgsql' => \OC\Setup\PostgreSQL::class,
90
-		'oci'   => \OC\Setup\OCI::class,
91
-		'sqlite' => \OC\Setup\Sqlite::class,
92
-		'sqlite3' => \OC\Setup\Sqlite::class,
93
-	];
94
-
95
-	/**
96
-	 * Wrapper around the "class_exists" PHP function to be able to mock it
97
-	 * @param string $name
98
-	 * @return bool
99
-	 */
100
-	protected function class_exists($name) {
101
-		return class_exists($name);
102
-	}
103
-
104
-	/**
105
-	 * Wrapper around the "is_callable" PHP function to be able to mock it
106
-	 * @param string $name
107
-	 * @return bool
108
-	 */
109
-	protected function is_callable($name) {
110
-		return is_callable($name);
111
-	}
112
-
113
-	/**
114
-	 * Wrapper around \PDO::getAvailableDrivers
115
-	 *
116
-	 * @return array
117
-	 */
118
-	protected function getAvailableDbDriversForPdo() {
119
-		return \PDO::getAvailableDrivers();
120
-	}
121
-
122
-	/**
123
-	 * Get the available and supported databases of this instance
124
-	 *
125
-	 * @param bool $allowAllDatabases
126
-	 * @return array
127
-	 * @throws Exception
128
-	 */
129
-	public function getSupportedDatabases($allowAllDatabases = false) {
130
-		$availableDatabases = array(
131
-			'sqlite' =>  array(
132
-				'type' => 'pdo',
133
-				'call' => 'sqlite',
134
-				'name' => 'SQLite'
135
-			),
136
-			'mysql' => array(
137
-				'type' => 'pdo',
138
-				'call' => 'mysql',
139
-				'name' => 'MySQL/MariaDB'
140
-			),
141
-			'pgsql' => array(
142
-				'type' => 'pdo',
143
-				'call' => 'pgsql',
144
-				'name' => 'PostgreSQL'
145
-			),
146
-			'oci' => array(
147
-				'type' => 'function',
148
-				'call' => 'oci_connect',
149
-				'name' => 'Oracle'
150
-			)
151
-		);
152
-		if ($allowAllDatabases) {
153
-			$configuredDatabases = array_keys($availableDatabases);
154
-		} else {
155
-			$configuredDatabases = $this->config->getValue('supportedDatabases',
156
-				array('sqlite', 'mysql', 'pgsql'));
157
-		}
158
-		if(!is_array($configuredDatabases)) {
159
-			throw new Exception('Supported databases are not properly configured.');
160
-		}
161
-
162
-		$supportedDatabases = array();
163
-
164
-		foreach($configuredDatabases as $database) {
165
-			if(array_key_exists($database, $availableDatabases)) {
166
-				$working = false;
167
-				$type = $availableDatabases[$database]['type'];
168
-				$call = $availableDatabases[$database]['call'];
169
-
170
-				if ($type === 'function') {
171
-					$working = $this->is_callable($call);
172
-				} elseif($type === 'pdo') {
173
-					$working = in_array($call, $this->getAvailableDbDriversForPdo(), TRUE);
174
-				}
175
-				if($working) {
176
-					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
177
-				}
178
-			}
179
-		}
180
-
181
-		return $supportedDatabases;
182
-	}
183
-
184
-	/**
185
-	 * Gathers system information like database type and does
186
-	 * a few system checks.
187
-	 *
188
-	 * @return array of system info, including an "errors" value
189
-	 * in case of errors/warnings
190
-	 */
191
-	public function getSystemInfo($allowAllDatabases = false) {
192
-		$databases = $this->getSupportedDatabases($allowAllDatabases);
193
-
194
-		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
195
-
196
-		$errors = array();
197
-
198
-		// Create data directory to test whether the .htaccess works
199
-		// Notice that this is not necessarily the same data directory as the one
200
-		// that will effectively be used.
201
-		if(!file_exists($dataDir)) {
202
-			@mkdir($dataDir);
203
-		}
204
-		$htAccessWorking = true;
205
-		if (is_dir($dataDir) && is_writable($dataDir)) {
206
-			// Protect data directory here, so we can test if the protection is working
207
-			\OC\Setup::protectDataDirectory();
208
-
209
-			try {
210
-				$util = new \OC_Util();
211
-				$htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
212
-			} catch (\OC\HintException $e) {
213
-				$errors[] = array(
214
-					'error' => $e->getMessage(),
215
-					'hint' => $e->getHint()
216
-				);
217
-				$htAccessWorking = false;
218
-			}
219
-		}
220
-
221
-		if (\OC_Util::runningOnMac()) {
222
-			$errors[] = array(
223
-				'error' => $this->l10n->t(
224
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
225
-					'Use it at your own risk! ',
226
-					$this->defaults->getName()
227
-				),
228
-				'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.')
229
-			);
230
-		}
231
-
232
-		if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
233
-			$errors[] = array(
234
-				'error' => $this->l10n->t(
235
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
236
-					'This will lead to problems with files over 4 GB and is highly discouraged.',
237
-					$this->defaults->getName()
238
-				),
239
-				'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.')
240
-			);
241
-		}
242
-
243
-		return array(
244
-			'hasSQLite' => isset($databases['sqlite']),
245
-			'hasMySQL' => isset($databases['mysql']),
246
-			'hasPostgreSQL' => isset($databases['pgsql']),
247
-			'hasOracle' => isset($databases['oci']),
248
-			'databases' => $databases,
249
-			'directory' => $dataDir,
250
-			'htaccessWorking' => $htAccessWorking,
251
-			'errors' => $errors,
252
-		);
253
-	}
254
-
255
-	/**
256
-	 * @param $options
257
-	 * @return array
258
-	 */
259
-	public function install($options) {
260
-		$l = $this->l10n;
261
-
262
-		$error = array();
263
-		$dbType = $options['dbtype'];
264
-
265
-		if(empty($options['adminlogin'])) {
266
-			$error[] = $l->t('Set an admin username.');
267
-		}
268
-		if(empty($options['adminpass'])) {
269
-			$error[] = $l->t('Set an admin password.');
270
-		}
271
-		if(empty($options['directory'])) {
272
-			$options['directory'] = \OC::$SERVERROOT."/data";
273
-		}
274
-
275
-		if (!isset(self::$dbSetupClasses[$dbType])) {
276
-			$dbType = 'sqlite';
277
-		}
278
-
279
-		$username = htmlspecialchars_decode($options['adminlogin']);
280
-		$password = htmlspecialchars_decode($options['adminpass']);
281
-		$dataDir = htmlspecialchars_decode($options['directory']);
282
-
283
-		$class = self::$dbSetupClasses[$dbType];
284
-		/** @var \OC\Setup\AbstractDatabase $dbSetup */
285
-		$dbSetup = new $class($l, 'db_structure.xml', $this->config,
286
-			$this->logger, $this->random);
287
-		$error = array_merge($error, $dbSetup->validate($options));
288
-
289
-		// validate the data directory
290
-		if (
291
-			(!is_dir($dataDir) and !mkdir($dataDir)) or
292
-			!is_writable($dataDir)
293
-		) {
294
-			$error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
295
-		}
296
-
297
-		if(count($error) != 0) {
298
-			return $error;
299
-		}
300
-
301
-		$request = \OC::$server->getRequest();
302
-
303
-		//no errors, good
304
-		if(isset($options['trusted_domains'])
305
-		    && is_array($options['trusted_domains'])) {
306
-			$trustedDomains = $options['trusted_domains'];
307
-		} else {
308
-			$trustedDomains = [$request->getInsecureServerHost()];
309
-		}
310
-
311
-		//use sqlite3 when available, otherwise sqlite2 will be used.
312
-		if($dbType=='sqlite' and class_exists('SQLite3')) {
313
-			$dbType='sqlite3';
314
-		}
315
-
316
-		//generate a random salt that is used to salt the local user passwords
317
-		$salt = $this->random->generate(30);
318
-		// generate a secret
319
-		$secret = $this->random->generate(48);
320
-
321
-		//write the config file
322
-		$this->config->setValues([
323
-			'passwordsalt'		=> $salt,
324
-			'secret'			=> $secret,
325
-			'trusted_domains'	=> $trustedDomains,
326
-			'datadirectory'		=> $dataDir,
327
-			'overwrite.cli.url'	=> $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT,
328
-			'dbtype'			=> $dbType,
329
-			'version'			=> implode('.', \OCP\Util::getVersion()),
330
-		]);
331
-
332
-		try {
333
-			$dbSetup->initialize($options);
334
-			$dbSetup->setupDatabase($username);
335
-			// apply necessary migrations
336
-			$dbSetup->runMigrations();
337
-		} catch (\OC\DatabaseSetupException $e) {
338
-			$error[] = array(
339
-				'error' => $e->getMessage(),
340
-				'hint' => $e->getHint()
341
-			);
342
-			return($error);
343
-		} catch (Exception $e) {
344
-			$error[] = array(
345
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
346
-				'hint' => ''
347
-			);
348
-			return($error);
349
-		}
350
-
351
-		//create the user and group
352
-		$user =  null;
353
-		try {
354
-			$user = \OC::$server->getUserManager()->createUser($username, $password);
355
-			if (!$user) {
356
-				$error[] = "User <$username> could not be created.";
357
-			}
358
-		} catch(Exception $exception) {
359
-			$error[] = $exception->getMessage();
360
-		}
361
-
362
-		if(count($error) == 0) {
363
-			$config = \OC::$server->getConfig();
364
-			$config->setAppValue('core', 'installedat', microtime(true));
365
-			$config->setAppValue('core', 'lastupdatedat', microtime(true));
366
-			$config->setAppValue('core', 'vendor', $this->getVendor());
367
-
368
-			$group =\OC::$server->getGroupManager()->createGroup('admin');
369
-			$group->addUser($user);
370
-
371
-			// Install shipped apps and specified app bundles
372
-			Installer::installShippedApps();
373
-			$installer = new Installer(
374
-				\OC::$server->getAppFetcher(),
375
-				\OC::$server->getHTTPClientService(),
376
-				\OC::$server->getTempManager(),
377
-				\OC::$server->getLogger(),
378
-				\OC::$server->getConfig()
379
-			);
380
-			$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
381
-			$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
382
-			foreach($defaultInstallationBundles as $bundle) {
383
-				try {
384
-					$installer->installAppBundle($bundle);
385
-				} catch (Exception $e) {}
386
-			}
387
-
388
-			// create empty file in data dir, so we can later find
389
-			// out that this is indeed an ownCloud data directory
390
-			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
391
-
392
-			// Update .htaccess files
393
-			Setup::updateHtaccess();
394
-			Setup::protectDataDirectory();
395
-
396
-			self::installBackgroundJobs();
397
-
398
-			//and we are done
399
-			$config->setSystemValue('installed', true);
400
-
401
-			// Create a session token for the newly created user
402
-			// The token provider requires a working db, so it's not injected on setup
403
-			/* @var $userSession User\Session */
404
-			$userSession = \OC::$server->getUserSession();
405
-			$defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
406
-			$userSession->setTokenProvider($defaultTokenProvider);
407
-			$userSession->login($username, $password);
408
-			$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
409
-		}
410
-
411
-		return $error;
412
-	}
413
-
414
-	public static function installBackgroundJobs() {
415
-		\OC::$server->getJobList()->add('\OC\Authentication\Token\DefaultTokenCleanupJob');
416
-	}
417
-
418
-	/**
419
-	 * @return string Absolute path to htaccess
420
-	 */
421
-	private function pathToHtaccess() {
422
-		return \OC::$SERVERROOT.'/.htaccess';
423
-	}
424
-
425
-	/**
426
-	 * Append the correct ErrorDocument path for Apache hosts
427
-	 * @return bool True when success, False otherwise
428
-	 */
429
-	public static function updateHtaccess() {
430
-		$config = \OC::$server->getSystemConfig();
431
-
432
-		// For CLI read the value from overwrite.cli.url
433
-		if(\OC::$CLI) {
434
-			$webRoot = $config->getValue('overwrite.cli.url', '');
435
-			if($webRoot === '') {
436
-				return false;
437
-			}
438
-			$webRoot = parse_url($webRoot, PHP_URL_PATH);
439
-			$webRoot = rtrim($webRoot, '/');
440
-		} else {
441
-			$webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
442
-		}
443
-
444
-		$setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(),
445
-			\OC::$server->getL10N('lib'), \OC::$server->query(Defaults::class), \OC::$server->getLogger(),
446
-			\OC::$server->getSecureRandom());
447
-
448
-		$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
449
-		$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
450
-		$htaccessContent = explode($content, $htaccessContent, 2)[0];
451
-
452
-		//custom 403 error page
453
-		$content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
454
-
455
-		//custom 404 error page
456
-		$content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
457
-
458
-		// Add rewrite rules if the RewriteBase is configured
459
-		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
460
-		if($rewriteBase !== '') {
461
-			$content .= "\n<IfModule mod_rewrite.c>";
462
-			$content .= "\n  Options -MultiViews";
463
-			$content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
464
-			$content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
465
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
466
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
467
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
468
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
469
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
470
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
471
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
472
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
473
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
474
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
475
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
476
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
477
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
478
-			$content .= "\n  RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*";
479
-			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
480
-			$content .= "\n  RewriteBase " . $rewriteBase;
481
-			$content .= "\n  <IfModule mod_env.c>";
482
-			$content .= "\n    SetEnv front_controller_active true";
483
-			$content .= "\n    <IfModule mod_dir.c>";
484
-			$content .= "\n      DirectorySlash off";
485
-			$content .= "\n    </IfModule>";
486
-			$content .= "\n  </IfModule>";
487
-			$content .= "\n</IfModule>";
488
-		}
489
-
490
-		if ($content !== '') {
491
-			//suppress errors in case we don't have permissions for it
492
-			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
493
-		}
494
-
495
-		return false;
496
-	}
497
-
498
-	public static function protectDataDirectory() {
499
-		//Require all denied
500
-		$now =  date('Y-m-d H:i:s');
501
-		$content = "# Generated by Nextcloud on $now\n";
502
-		$content.= "# line below if for Apache 2.4\n";
503
-		$content.= "<ifModule mod_authz_core.c>\n";
504
-		$content.= "Require all denied\n";
505
-		$content.= "</ifModule>\n\n";
506
-		$content.= "# line below if for Apache 2.2\n";
507
-		$content.= "<ifModule !mod_authz_core.c>\n";
508
-		$content.= "deny from all\n";
509
-		$content.= "Satisfy All\n";
510
-		$content.= "</ifModule>\n\n";
511
-		$content.= "# section for Apache 2.2 and 2.4\n";
512
-		$content.= "<ifModule mod_autoindex.c>\n";
513
-		$content.= "IndexIgnore *\n";
514
-		$content.= "</ifModule>\n";
515
-
516
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
517
-		file_put_contents($baseDir . '/.htaccess', $content);
518
-		file_put_contents($baseDir . '/index.html', '');
519
-	}
520
-
521
-	/**
522
-	 * Return vendor from which this version was published
523
-	 *
524
-	 * @return string Get the vendor
525
-	 *
526
-	 * Copy of \OC\Updater::getVendor()
527
-	 */
528
-	private function getVendor() {
529
-		// this should really be a JSON file
530
-		require \OC::$SERVERROOT . '/version.php';
531
-		/** @var string $vendor */
532
-		return (string) $vendor;
533
-	}
51
+    /** @var SystemConfig */
52
+    protected $config;
53
+    /** @var IniGetWrapper */
54
+    protected $iniWrapper;
55
+    /** @var IL10N */
56
+    protected $l10n;
57
+    /** @var Defaults */
58
+    protected $defaults;
59
+    /** @var ILogger */
60
+    protected $logger;
61
+    /** @var ISecureRandom */
62
+    protected $random;
63
+
64
+    /**
65
+     * @param SystemConfig $config
66
+     * @param IniGetWrapper $iniWrapper
67
+     * @param IL10N $l10n
68
+     * @param Defaults $defaults
69
+     * @param ILogger $logger
70
+     * @param ISecureRandom $random
71
+     */
72
+    public function __construct(SystemConfig $config,
73
+                            IniGetWrapper $iniWrapper,
74
+                            IL10N $l10n,
75
+                            Defaults $defaults,
76
+                            ILogger $logger,
77
+                            ISecureRandom $random
78
+        ) {
79
+        $this->config = $config;
80
+        $this->iniWrapper = $iniWrapper;
81
+        $this->l10n = $l10n;
82
+        $this->defaults = $defaults;
83
+        $this->logger = $logger;
84
+        $this->random = $random;
85
+    }
86
+
87
+    static $dbSetupClasses = [
88
+        'mysql' => \OC\Setup\MySQL::class,
89
+        'pgsql' => \OC\Setup\PostgreSQL::class,
90
+        'oci'   => \OC\Setup\OCI::class,
91
+        'sqlite' => \OC\Setup\Sqlite::class,
92
+        'sqlite3' => \OC\Setup\Sqlite::class,
93
+    ];
94
+
95
+    /**
96
+     * Wrapper around the "class_exists" PHP function to be able to mock it
97
+     * @param string $name
98
+     * @return bool
99
+     */
100
+    protected function class_exists($name) {
101
+        return class_exists($name);
102
+    }
103
+
104
+    /**
105
+     * Wrapper around the "is_callable" PHP function to be able to mock it
106
+     * @param string $name
107
+     * @return bool
108
+     */
109
+    protected function is_callable($name) {
110
+        return is_callable($name);
111
+    }
112
+
113
+    /**
114
+     * Wrapper around \PDO::getAvailableDrivers
115
+     *
116
+     * @return array
117
+     */
118
+    protected function getAvailableDbDriversForPdo() {
119
+        return \PDO::getAvailableDrivers();
120
+    }
121
+
122
+    /**
123
+     * Get the available and supported databases of this instance
124
+     *
125
+     * @param bool $allowAllDatabases
126
+     * @return array
127
+     * @throws Exception
128
+     */
129
+    public function getSupportedDatabases($allowAllDatabases = false) {
130
+        $availableDatabases = array(
131
+            'sqlite' =>  array(
132
+                'type' => 'pdo',
133
+                'call' => 'sqlite',
134
+                'name' => 'SQLite'
135
+            ),
136
+            'mysql' => array(
137
+                'type' => 'pdo',
138
+                'call' => 'mysql',
139
+                'name' => 'MySQL/MariaDB'
140
+            ),
141
+            'pgsql' => array(
142
+                'type' => 'pdo',
143
+                'call' => 'pgsql',
144
+                'name' => 'PostgreSQL'
145
+            ),
146
+            'oci' => array(
147
+                'type' => 'function',
148
+                'call' => 'oci_connect',
149
+                'name' => 'Oracle'
150
+            )
151
+        );
152
+        if ($allowAllDatabases) {
153
+            $configuredDatabases = array_keys($availableDatabases);
154
+        } else {
155
+            $configuredDatabases = $this->config->getValue('supportedDatabases',
156
+                array('sqlite', 'mysql', 'pgsql'));
157
+        }
158
+        if(!is_array($configuredDatabases)) {
159
+            throw new Exception('Supported databases are not properly configured.');
160
+        }
161
+
162
+        $supportedDatabases = array();
163
+
164
+        foreach($configuredDatabases as $database) {
165
+            if(array_key_exists($database, $availableDatabases)) {
166
+                $working = false;
167
+                $type = $availableDatabases[$database]['type'];
168
+                $call = $availableDatabases[$database]['call'];
169
+
170
+                if ($type === 'function') {
171
+                    $working = $this->is_callable($call);
172
+                } elseif($type === 'pdo') {
173
+                    $working = in_array($call, $this->getAvailableDbDriversForPdo(), TRUE);
174
+                }
175
+                if($working) {
176
+                    $supportedDatabases[$database] = $availableDatabases[$database]['name'];
177
+                }
178
+            }
179
+        }
180
+
181
+        return $supportedDatabases;
182
+    }
183
+
184
+    /**
185
+     * Gathers system information like database type and does
186
+     * a few system checks.
187
+     *
188
+     * @return array of system info, including an "errors" value
189
+     * in case of errors/warnings
190
+     */
191
+    public function getSystemInfo($allowAllDatabases = false) {
192
+        $databases = $this->getSupportedDatabases($allowAllDatabases);
193
+
194
+        $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
195
+
196
+        $errors = array();
197
+
198
+        // Create data directory to test whether the .htaccess works
199
+        // Notice that this is not necessarily the same data directory as the one
200
+        // that will effectively be used.
201
+        if(!file_exists($dataDir)) {
202
+            @mkdir($dataDir);
203
+        }
204
+        $htAccessWorking = true;
205
+        if (is_dir($dataDir) && is_writable($dataDir)) {
206
+            // Protect data directory here, so we can test if the protection is working
207
+            \OC\Setup::protectDataDirectory();
208
+
209
+            try {
210
+                $util = new \OC_Util();
211
+                $htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
212
+            } catch (\OC\HintException $e) {
213
+                $errors[] = array(
214
+                    'error' => $e->getMessage(),
215
+                    'hint' => $e->getHint()
216
+                );
217
+                $htAccessWorking = false;
218
+            }
219
+        }
220
+
221
+        if (\OC_Util::runningOnMac()) {
222
+            $errors[] = array(
223
+                'error' => $this->l10n->t(
224
+                    'Mac OS X is not supported and %s will not work properly on this platform. ' .
225
+                    'Use it at your own risk! ',
226
+                    $this->defaults->getName()
227
+                ),
228
+                'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.')
229
+            );
230
+        }
231
+
232
+        if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
233
+            $errors[] = array(
234
+                'error' => $this->l10n->t(
235
+                    'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
236
+                    'This will lead to problems with files over 4 GB and is highly discouraged.',
237
+                    $this->defaults->getName()
238
+                ),
239
+                'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.')
240
+            );
241
+        }
242
+
243
+        return array(
244
+            'hasSQLite' => isset($databases['sqlite']),
245
+            'hasMySQL' => isset($databases['mysql']),
246
+            'hasPostgreSQL' => isset($databases['pgsql']),
247
+            'hasOracle' => isset($databases['oci']),
248
+            'databases' => $databases,
249
+            'directory' => $dataDir,
250
+            'htaccessWorking' => $htAccessWorking,
251
+            'errors' => $errors,
252
+        );
253
+    }
254
+
255
+    /**
256
+     * @param $options
257
+     * @return array
258
+     */
259
+    public function install($options) {
260
+        $l = $this->l10n;
261
+
262
+        $error = array();
263
+        $dbType = $options['dbtype'];
264
+
265
+        if(empty($options['adminlogin'])) {
266
+            $error[] = $l->t('Set an admin username.');
267
+        }
268
+        if(empty($options['adminpass'])) {
269
+            $error[] = $l->t('Set an admin password.');
270
+        }
271
+        if(empty($options['directory'])) {
272
+            $options['directory'] = \OC::$SERVERROOT."/data";
273
+        }
274
+
275
+        if (!isset(self::$dbSetupClasses[$dbType])) {
276
+            $dbType = 'sqlite';
277
+        }
278
+
279
+        $username = htmlspecialchars_decode($options['adminlogin']);
280
+        $password = htmlspecialchars_decode($options['adminpass']);
281
+        $dataDir = htmlspecialchars_decode($options['directory']);
282
+
283
+        $class = self::$dbSetupClasses[$dbType];
284
+        /** @var \OC\Setup\AbstractDatabase $dbSetup */
285
+        $dbSetup = new $class($l, 'db_structure.xml', $this->config,
286
+            $this->logger, $this->random);
287
+        $error = array_merge($error, $dbSetup->validate($options));
288
+
289
+        // validate the data directory
290
+        if (
291
+            (!is_dir($dataDir) and !mkdir($dataDir)) or
292
+            !is_writable($dataDir)
293
+        ) {
294
+            $error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
295
+        }
296
+
297
+        if(count($error) != 0) {
298
+            return $error;
299
+        }
300
+
301
+        $request = \OC::$server->getRequest();
302
+
303
+        //no errors, good
304
+        if(isset($options['trusted_domains'])
305
+            && is_array($options['trusted_domains'])) {
306
+            $trustedDomains = $options['trusted_domains'];
307
+        } else {
308
+            $trustedDomains = [$request->getInsecureServerHost()];
309
+        }
310
+
311
+        //use sqlite3 when available, otherwise sqlite2 will be used.
312
+        if($dbType=='sqlite' and class_exists('SQLite3')) {
313
+            $dbType='sqlite3';
314
+        }
315
+
316
+        //generate a random salt that is used to salt the local user passwords
317
+        $salt = $this->random->generate(30);
318
+        // generate a secret
319
+        $secret = $this->random->generate(48);
320
+
321
+        //write the config file
322
+        $this->config->setValues([
323
+            'passwordsalt'		=> $salt,
324
+            'secret'			=> $secret,
325
+            'trusted_domains'	=> $trustedDomains,
326
+            'datadirectory'		=> $dataDir,
327
+            'overwrite.cli.url'	=> $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT,
328
+            'dbtype'			=> $dbType,
329
+            'version'			=> implode('.', \OCP\Util::getVersion()),
330
+        ]);
331
+
332
+        try {
333
+            $dbSetup->initialize($options);
334
+            $dbSetup->setupDatabase($username);
335
+            // apply necessary migrations
336
+            $dbSetup->runMigrations();
337
+        } catch (\OC\DatabaseSetupException $e) {
338
+            $error[] = array(
339
+                'error' => $e->getMessage(),
340
+                'hint' => $e->getHint()
341
+            );
342
+            return($error);
343
+        } catch (Exception $e) {
344
+            $error[] = array(
345
+                'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
346
+                'hint' => ''
347
+            );
348
+            return($error);
349
+        }
350
+
351
+        //create the user and group
352
+        $user =  null;
353
+        try {
354
+            $user = \OC::$server->getUserManager()->createUser($username, $password);
355
+            if (!$user) {
356
+                $error[] = "User <$username> could not be created.";
357
+            }
358
+        } catch(Exception $exception) {
359
+            $error[] = $exception->getMessage();
360
+        }
361
+
362
+        if(count($error) == 0) {
363
+            $config = \OC::$server->getConfig();
364
+            $config->setAppValue('core', 'installedat', microtime(true));
365
+            $config->setAppValue('core', 'lastupdatedat', microtime(true));
366
+            $config->setAppValue('core', 'vendor', $this->getVendor());
367
+
368
+            $group =\OC::$server->getGroupManager()->createGroup('admin');
369
+            $group->addUser($user);
370
+
371
+            // Install shipped apps and specified app bundles
372
+            Installer::installShippedApps();
373
+            $installer = new Installer(
374
+                \OC::$server->getAppFetcher(),
375
+                \OC::$server->getHTTPClientService(),
376
+                \OC::$server->getTempManager(),
377
+                \OC::$server->getLogger(),
378
+                \OC::$server->getConfig()
379
+            );
380
+            $bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
381
+            $defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
382
+            foreach($defaultInstallationBundles as $bundle) {
383
+                try {
384
+                    $installer->installAppBundle($bundle);
385
+                } catch (Exception $e) {}
386
+            }
387
+
388
+            // create empty file in data dir, so we can later find
389
+            // out that this is indeed an ownCloud data directory
390
+            file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
391
+
392
+            // Update .htaccess files
393
+            Setup::updateHtaccess();
394
+            Setup::protectDataDirectory();
395
+
396
+            self::installBackgroundJobs();
397
+
398
+            //and we are done
399
+            $config->setSystemValue('installed', true);
400
+
401
+            // Create a session token for the newly created user
402
+            // The token provider requires a working db, so it's not injected on setup
403
+            /* @var $userSession User\Session */
404
+            $userSession = \OC::$server->getUserSession();
405
+            $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
406
+            $userSession->setTokenProvider($defaultTokenProvider);
407
+            $userSession->login($username, $password);
408
+            $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
409
+        }
410
+
411
+        return $error;
412
+    }
413
+
414
+    public static function installBackgroundJobs() {
415
+        \OC::$server->getJobList()->add('\OC\Authentication\Token\DefaultTokenCleanupJob');
416
+    }
417
+
418
+    /**
419
+     * @return string Absolute path to htaccess
420
+     */
421
+    private function pathToHtaccess() {
422
+        return \OC::$SERVERROOT.'/.htaccess';
423
+    }
424
+
425
+    /**
426
+     * Append the correct ErrorDocument path for Apache hosts
427
+     * @return bool True when success, False otherwise
428
+     */
429
+    public static function updateHtaccess() {
430
+        $config = \OC::$server->getSystemConfig();
431
+
432
+        // For CLI read the value from overwrite.cli.url
433
+        if(\OC::$CLI) {
434
+            $webRoot = $config->getValue('overwrite.cli.url', '');
435
+            if($webRoot === '') {
436
+                return false;
437
+            }
438
+            $webRoot = parse_url($webRoot, PHP_URL_PATH);
439
+            $webRoot = rtrim($webRoot, '/');
440
+        } else {
441
+            $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
442
+        }
443
+
444
+        $setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(),
445
+            \OC::$server->getL10N('lib'), \OC::$server->query(Defaults::class), \OC::$server->getLogger(),
446
+            \OC::$server->getSecureRandom());
447
+
448
+        $htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
449
+        $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
450
+        $htaccessContent = explode($content, $htaccessContent, 2)[0];
451
+
452
+        //custom 403 error page
453
+        $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
454
+
455
+        //custom 404 error page
456
+        $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
457
+
458
+        // Add rewrite rules if the RewriteBase is configured
459
+        $rewriteBase = $config->getValue('htaccess.RewriteBase', '');
460
+        if($rewriteBase !== '') {
461
+            $content .= "\n<IfModule mod_rewrite.c>";
462
+            $content .= "\n  Options -MultiViews";
463
+            $content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
464
+            $content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
465
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
466
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
467
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
468
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
469
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
470
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
471
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
472
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
473
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
474
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
475
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
476
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
477
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
478
+            $content .= "\n  RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*";
479
+            $content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
480
+            $content .= "\n  RewriteBase " . $rewriteBase;
481
+            $content .= "\n  <IfModule mod_env.c>";
482
+            $content .= "\n    SetEnv front_controller_active true";
483
+            $content .= "\n    <IfModule mod_dir.c>";
484
+            $content .= "\n      DirectorySlash off";
485
+            $content .= "\n    </IfModule>";
486
+            $content .= "\n  </IfModule>";
487
+            $content .= "\n</IfModule>";
488
+        }
489
+
490
+        if ($content !== '') {
491
+            //suppress errors in case we don't have permissions for it
492
+            return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
493
+        }
494
+
495
+        return false;
496
+    }
497
+
498
+    public static function protectDataDirectory() {
499
+        //Require all denied
500
+        $now =  date('Y-m-d H:i:s');
501
+        $content = "# Generated by Nextcloud on $now\n";
502
+        $content.= "# line below if for Apache 2.4\n";
503
+        $content.= "<ifModule mod_authz_core.c>\n";
504
+        $content.= "Require all denied\n";
505
+        $content.= "</ifModule>\n\n";
506
+        $content.= "# line below if for Apache 2.2\n";
507
+        $content.= "<ifModule !mod_authz_core.c>\n";
508
+        $content.= "deny from all\n";
509
+        $content.= "Satisfy All\n";
510
+        $content.= "</ifModule>\n\n";
511
+        $content.= "# section for Apache 2.2 and 2.4\n";
512
+        $content.= "<ifModule mod_autoindex.c>\n";
513
+        $content.= "IndexIgnore *\n";
514
+        $content.= "</ifModule>\n";
515
+
516
+        $baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
517
+        file_put_contents($baseDir . '/.htaccess', $content);
518
+        file_put_contents($baseDir . '/index.html', '');
519
+    }
520
+
521
+    /**
522
+     * Return vendor from which this version was published
523
+     *
524
+     * @return string Get the vendor
525
+     *
526
+     * Copy of \OC\Updater::getVendor()
527
+     */
528
+    private function getVendor() {
529
+        // this should really be a JSON file
530
+        require \OC::$SERVERROOT . '/version.php';
531
+        /** @var string $vendor */
532
+        return (string) $vendor;
533
+    }
534 534
 }
Please login to merge, or discard this patch.
lib/private/DB/OracleMigrator.php 1 patch
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -32,106 +32,106 @@
 block discarded – undo
32 32
 use Doctrine\DBAL\Schema\Table;
33 33
 
34 34
 class OracleMigrator extends NoCheckMigrator {
35
-	/**
36
-	 * @param Schema $targetSchema
37
-	 * @param \Doctrine\DBAL\Connection $connection
38
-	 * @return \Doctrine\DBAL\Schema\SchemaDiff
39
-	 * @throws DBALException
40
-	 */
41
-	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
42
-		$schemaDiff = parent::getDiff($targetSchema, $connection);
35
+    /**
36
+     * @param Schema $targetSchema
37
+     * @param \Doctrine\DBAL\Connection $connection
38
+     * @return \Doctrine\DBAL\Schema\SchemaDiff
39
+     * @throws DBALException
40
+     */
41
+    protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
42
+        $schemaDiff = parent::getDiff($targetSchema, $connection);
43 43
 
44
-		// oracle forces us to quote the identifiers
45
-		$schemaDiff->newTables = array_map(function(Table $table) {
46
-			return new Table(
47
-				$this->connection->quoteIdentifier($table->getName()),
48
-				array_map(function(Column $column) {
49
-					$newColumn = new Column(
50
-						$this->connection->quoteIdentifier($column->getName()),
51
-						$column->getType()
52
-					);
53
-					$newColumn->setAutoincrement($column->getAutoincrement());
54
-					$newColumn->setColumnDefinition($column->getColumnDefinition());
55
-					$newColumn->setComment($column->getComment());
56
-					$newColumn->setDefault($column->getDefault());
57
-					$newColumn->setFixed($column->getFixed());
58
-					$newColumn->setLength($column->getLength());
59
-					$newColumn->setNotnull($column->getNotnull());
60
-					$newColumn->setPrecision($column->getPrecision());
61
-					$newColumn->setScale($column->getScale());
62
-					$newColumn->setUnsigned($column->getUnsigned());
63
-					$newColumn->setPlatformOptions($column->getPlatformOptions());
64
-					$newColumn->setCustomSchemaOptions($column->getPlatformOptions());
65
-					return $newColumn;
66
-				}, $table->getColumns()),
67
-				array_map(function(Index $index) {
68
-					return new Index(
69
-						$this->connection->quoteIdentifier($index->getName()),
70
-						array_map(function($columnName) {
71
-							return $this->connection->quoteIdentifier($columnName);
72
-						}, $index->getColumns()),
73
-						$index->isUnique(),
74
-						$index->isPrimary(),
75
-						$index->getFlags(),
76
-						$index->getOptions()
77
-					);
78
-				}, $table->getIndexes()),
79
-				$table->getForeignKeys(),
80
-				0,
81
-				$table->getOptions()
82
-			);
83
-		}, $schemaDiff->newTables);
44
+        // oracle forces us to quote the identifiers
45
+        $schemaDiff->newTables = array_map(function(Table $table) {
46
+            return new Table(
47
+                $this->connection->quoteIdentifier($table->getName()),
48
+                array_map(function(Column $column) {
49
+                    $newColumn = new Column(
50
+                        $this->connection->quoteIdentifier($column->getName()),
51
+                        $column->getType()
52
+                    );
53
+                    $newColumn->setAutoincrement($column->getAutoincrement());
54
+                    $newColumn->setColumnDefinition($column->getColumnDefinition());
55
+                    $newColumn->setComment($column->getComment());
56
+                    $newColumn->setDefault($column->getDefault());
57
+                    $newColumn->setFixed($column->getFixed());
58
+                    $newColumn->setLength($column->getLength());
59
+                    $newColumn->setNotnull($column->getNotnull());
60
+                    $newColumn->setPrecision($column->getPrecision());
61
+                    $newColumn->setScale($column->getScale());
62
+                    $newColumn->setUnsigned($column->getUnsigned());
63
+                    $newColumn->setPlatformOptions($column->getPlatformOptions());
64
+                    $newColumn->setCustomSchemaOptions($column->getPlatformOptions());
65
+                    return $newColumn;
66
+                }, $table->getColumns()),
67
+                array_map(function(Index $index) {
68
+                    return new Index(
69
+                        $this->connection->quoteIdentifier($index->getName()),
70
+                        array_map(function($columnName) {
71
+                            return $this->connection->quoteIdentifier($columnName);
72
+                        }, $index->getColumns()),
73
+                        $index->isUnique(),
74
+                        $index->isPrimary(),
75
+                        $index->getFlags(),
76
+                        $index->getOptions()
77
+                    );
78
+                }, $table->getIndexes()),
79
+                $table->getForeignKeys(),
80
+                0,
81
+                $table->getOptions()
82
+            );
83
+        }, $schemaDiff->newTables);
84 84
 
85
-		$schemaDiff->removedTables = array_map(function(Table $table) {
86
-			return new Table(
87
-				$this->connection->quoteIdentifier($table->getName()),
88
-				$table->getColumns(),
89
-				$table->getIndexes(),
90
-				$table->getForeignKeys(),
91
-				0,
92
-				$table->getOptions()
93
-			);
94
-		}, $schemaDiff->removedTables);
85
+        $schemaDiff->removedTables = array_map(function(Table $table) {
86
+            return new Table(
87
+                $this->connection->quoteIdentifier($table->getName()),
88
+                $table->getColumns(),
89
+                $table->getIndexes(),
90
+                $table->getForeignKeys(),
91
+                0,
92
+                $table->getOptions()
93
+            );
94
+        }, $schemaDiff->removedTables);
95 95
 
96
-		foreach ($schemaDiff->changedTables as $tableDiff) {
97
-			$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
98
-			foreach ($tableDiff->changedColumns as $column) {
99
-				$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
100
-				// auto increment is not relevant for oracle and can anyhow not be applied on change
101
-				$column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
102
-			}
103
-			$tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
104
-				return count($column->changedProperties) > 0;
105
-			});
106
-		}
96
+        foreach ($schemaDiff->changedTables as $tableDiff) {
97
+            $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
98
+            foreach ($tableDiff->changedColumns as $column) {
99
+                $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
100
+                // auto increment is not relevant for oracle and can anyhow not be applied on change
101
+                $column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
102
+            }
103
+            $tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
104
+                return count($column->changedProperties) > 0;
105
+            });
106
+        }
107 107
 
108
-		return $schemaDiff;
109
-	}
108
+        return $schemaDiff;
109
+    }
110 110
 
111
-	/**
112
-	 * @param string $name
113
-	 * @return string
114
-	 */
115
-	protected function generateTemporaryTableName($name) {
116
-		return 'oc_' . uniqid();
117
-	}
111
+    /**
112
+     * @param string $name
113
+     * @return string
114
+     */
115
+    protected function generateTemporaryTableName($name) {
116
+        return 'oc_' . uniqid();
117
+    }
118 118
 
119
-	/**
120
-	 * @param $statement
121
-	 * @return string
122
-	 */
123
-	protected function convertStatementToScript($statement) {
124
-		if (substr($statement, -1) === ';') {
125
-			return $statement . PHP_EOL . '/' . PHP_EOL;
126
-		}
127
-		$script = $statement . ';';
128
-		$script .= PHP_EOL;
129
-		$script .= PHP_EOL;
130
-		return $script;
131
-	}
119
+    /**
120
+     * @param $statement
121
+     * @return string
122
+     */
123
+    protected function convertStatementToScript($statement) {
124
+        if (substr($statement, -1) === ';') {
125
+            return $statement . PHP_EOL . '/' . PHP_EOL;
126
+        }
127
+        $script = $statement . ';';
128
+        $script .= PHP_EOL;
129
+        $script .= PHP_EOL;
130
+        return $script;
131
+    }
132 132
 
133
-	protected function getFilterExpression() {
134
-		return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
135
-	}
133
+    protected function getFilterExpression() {
134
+        return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
135
+    }
136 136
 
137 137
 }
Please login to merge, or discard this patch.
lib/private/DB/OracleConnection.php 2 patches
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -26,80 +26,80 @@
 block discarded – undo
26 26
 namespace OC\DB;
27 27
 
28 28
 class OracleConnection extends Connection {
29
-	/**
30
-	 * Quote the keys of the array
31
-	 */
32
-	private function quoteKeys(array $data) {
33
-		$return = [];
34
-		$c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
-		foreach($data as $key => $value) {
36
-			if ($key[0] !== $c) {
37
-				$return[$this->quoteIdentifier($key)] = $value;
38
-			} else {
39
-				$return[$key] = $value;
40
-			}
41
-		}
42
-		return $return;
43
-	}
29
+    /**
30
+     * Quote the keys of the array
31
+     */
32
+    private function quoteKeys(array $data) {
33
+        $return = [];
34
+        $c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
+        foreach($data as $key => $value) {
36
+            if ($key[0] !== $c) {
37
+                $return[$this->quoteIdentifier($key)] = $value;
38
+            } else {
39
+                $return[$key] = $value;
40
+            }
41
+        }
42
+        return $return;
43
+    }
44 44
 
45
-	/**
46
-	 * {@inheritDoc}
47
-	 */
48
-	public function insert($tableName, array $data, array $types = array()) {
49
-		if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
50
-			$tableName = $this->quoteIdentifier($tableName);
51
-		}
52
-		$data = $this->quoteKeys($data);
53
-		return parent::insert($tableName, $data, $types);
54
-	}
45
+    /**
46
+     * {@inheritDoc}
47
+     */
48
+    public function insert($tableName, array $data, array $types = array()) {
49
+        if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
50
+            $tableName = $this->quoteIdentifier($tableName);
51
+        }
52
+        $data = $this->quoteKeys($data);
53
+        return parent::insert($tableName, $data, $types);
54
+    }
55 55
 
56
-	/**
57
-	 * {@inheritDoc}
58
-	 */
59
-	public function update($tableName, array $data, array $identifier, array $types = array()) {
60
-		if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
61
-			$tableName = $this->quoteIdentifier($tableName);
62
-		}
63
-		$data = $this->quoteKeys($data);
64
-		$identifier = $this->quoteKeys($identifier);
65
-		return parent::update($tableName, $data, $identifier, $types);
66
-	}
56
+    /**
57
+     * {@inheritDoc}
58
+     */
59
+    public function update($tableName, array $data, array $identifier, array $types = array()) {
60
+        if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
61
+            $tableName = $this->quoteIdentifier($tableName);
62
+        }
63
+        $data = $this->quoteKeys($data);
64
+        $identifier = $this->quoteKeys($identifier);
65
+        return parent::update($tableName, $data, $identifier, $types);
66
+    }
67 67
 
68
-	/**
69
-	 * {@inheritDoc}
70
-	 */
71
-	public function delete($tableExpression, array $identifier, array $types = array()) {
72
-		if ($tableExpression[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
73
-			$tableExpression = $this->quoteIdentifier($tableExpression);
74
-		}
75
-		$identifier = $this->quoteKeys($identifier);
76
-		return parent::delete($tableExpression, $identifier);
77
-	}
68
+    /**
69
+     * {@inheritDoc}
70
+     */
71
+    public function delete($tableExpression, array $identifier, array $types = array()) {
72
+        if ($tableExpression[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
73
+            $tableExpression = $this->quoteIdentifier($tableExpression);
74
+        }
75
+        $identifier = $this->quoteKeys($identifier);
76
+        return parent::delete($tableExpression, $identifier);
77
+    }
78 78
 
79
-	/**
80
-	 * Drop a table from the database if it exists
81
-	 *
82
-	 * @param string $table table name without the prefix
83
-	 */
84
-	public function dropTable($table) {
85
-		$table = $this->tablePrefix . trim($table);
86
-		$table = $this->quoteIdentifier($table);
87
-		$schema = $this->getSchemaManager();
88
-		if($schema->tablesExist(array($table))) {
89
-			$schema->dropTable($table);
90
-		}
91
-	}
79
+    /**
80
+     * Drop a table from the database if it exists
81
+     *
82
+     * @param string $table table name without the prefix
83
+     */
84
+    public function dropTable($table) {
85
+        $table = $this->tablePrefix . trim($table);
86
+        $table = $this->quoteIdentifier($table);
87
+        $schema = $this->getSchemaManager();
88
+        if($schema->tablesExist(array($table))) {
89
+            $schema->dropTable($table);
90
+        }
91
+    }
92 92
 
93
-	/**
94
-	 * Check if a table exists
95
-	 *
96
-	 * @param string $table table name without the prefix
97
-	 * @return bool
98
-	 */
99
-	public function tableExists($table){
100
-		$table = $this->tablePrefix . trim($table);
101
-		$table = $this->quoteIdentifier($table);
102
-		$schema = $this->getSchemaManager();
103
-		return $schema->tablesExist(array($table));
104
-	}
93
+    /**
94
+     * Check if a table exists
95
+     *
96
+     * @param string $table table name without the prefix
97
+     * @return bool
98
+     */
99
+    public function tableExists($table){
100
+        $table = $this->tablePrefix . trim($table);
101
+        $table = $this->quoteIdentifier($table);
102
+        $schema = $this->getSchemaManager();
103
+        return $schema->tablesExist(array($table));
104
+    }
105 105
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
 	private function quoteKeys(array $data) {
33 33
 		$return = [];
34 34
 		$c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
-		foreach($data as $key => $value) {
35
+		foreach ($data as $key => $value) {
36 36
 			if ($key[0] !== $c) {
37 37
 				$return[$this->quoteIdentifier($key)] = $value;
38 38
 			} else {
@@ -82,10 +82,10 @@  discard block
 block discarded – undo
82 82
 	 * @param string $table table name without the prefix
83 83
 	 */
84 84
 	public function dropTable($table) {
85
-		$table = $this->tablePrefix . trim($table);
85
+		$table = $this->tablePrefix.trim($table);
86 86
 		$table = $this->quoteIdentifier($table);
87 87
 		$schema = $this->getSchemaManager();
88
-		if($schema->tablesExist(array($table))) {
88
+		if ($schema->tablesExist(array($table))) {
89 89
 			$schema->dropTable($table);
90 90
 		}
91 91
 	}
@@ -96,8 +96,8 @@  discard block
 block discarded – undo
96 96
 	 * @param string $table table name without the prefix
97 97
 	 * @return bool
98 98
 	 */
99
-	public function tableExists($table){
100
-		$table = $this->tablePrefix . trim($table);
99
+	public function tableExists($table) {
100
+		$table = $this->tablePrefix.trim($table);
101 101
 		$table = $this->quoteIdentifier($table);
102 102
 		$schema = $this->getSchemaManager();
103 103
 		return $schema->tablesExist(array($table));
Please login to merge, or discard this patch.
lib/private/DB/Migrator.php 1 patch
Indentation   +268 added lines, -268 removed lines patch added patch discarded remove patch
@@ -43,272 +43,272 @@
 block discarded – undo
43 43
 
44 44
 class Migrator {
45 45
 
46
-	/** @var \Doctrine\DBAL\Connection */
47
-	protected $connection;
48
-
49
-	/** @var ISecureRandom */
50
-	private $random;
51
-
52
-	/** @var IConfig */
53
-	protected $config;
54
-
55
-	/** @var EventDispatcher  */
56
-	private $dispatcher;
57
-
58
-	/** @var bool */
59
-	private $noEmit = false;
60
-
61
-	/**
62
-	 * @param \Doctrine\DBAL\Connection|Connection $connection
63
-	 * @param ISecureRandom $random
64
-	 * @param IConfig $config
65
-	 * @param EventDispatcher $dispatcher
66
-	 */
67
-	public function __construct(\Doctrine\DBAL\Connection $connection,
68
-								ISecureRandom $random,
69
-								IConfig $config,
70
-								EventDispatcher $dispatcher = null) {
71
-		$this->connection = $connection;
72
-		$this->random = $random;
73
-		$this->config = $config;
74
-		$this->dispatcher = $dispatcher;
75
-	}
76
-
77
-	/**
78
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
79
-	 */
80
-	public function migrate(Schema $targetSchema) {
81
-		$this->noEmit = true;
82
-		$this->applySchema($targetSchema);
83
-	}
84
-
85
-	/**
86
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
87
-	 * @return string
88
-	 */
89
-	public function generateChangeScript(Schema $targetSchema) {
90
-		$schemaDiff = $this->getDiff($targetSchema, $this->connection);
91
-
92
-		$script = '';
93
-		$sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
94
-		foreach ($sqls as $sql) {
95
-			$script .= $this->convertStatementToScript($sql);
96
-		}
97
-
98
-		return $script;
99
-	}
100
-
101
-	/**
102
-	 * @param Schema $targetSchema
103
-	 * @throws \OC\DB\MigrationException
104
-	 */
105
-	public function checkMigrate(Schema $targetSchema) {
106
-		$this->noEmit = true;
107
-		/**@var \Doctrine\DBAL\Schema\Table[] $tables */
108
-		$tables = $targetSchema->getTables();
109
-		$filterExpression = $this->getFilterExpression();
110
-		$this->connection->getConfiguration()->
111
-			setFilterSchemaAssetsExpression($filterExpression);
112
-		$existingTables = $this->connection->getSchemaManager()->listTableNames();
113
-
114
-		$step = 0;
115
-		foreach ($tables as $table) {
116
-			if (strpos($table->getName(), '.')) {
117
-				list(, $tableName) = explode('.', $table->getName());
118
-			} else {
119
-				$tableName = $table->getName();
120
-			}
121
-			$this->emitCheckStep($tableName, $step++, count($tables));
122
-			// don't need to check for new tables
123
-			if (array_search($tableName, $existingTables) !== false) {
124
-				$this->checkTableMigrate($table);
125
-			}
126
-		}
127
-	}
128
-
129
-	/**
130
-	 * Create a unique name for the temporary table
131
-	 *
132
-	 * @param string $name
133
-	 * @return string
134
-	 */
135
-	protected function generateTemporaryTableName($name) {
136
-		return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
137
-	}
138
-
139
-	/**
140
-	 * Check the migration of a table on a copy so we can detect errors before messing with the real table
141
-	 *
142
-	 * @param \Doctrine\DBAL\Schema\Table $table
143
-	 * @throws \OC\DB\MigrationException
144
-	 */
145
-	protected function checkTableMigrate(Table $table) {
146
-		$name = $table->getName();
147
-		$tmpName = $this->generateTemporaryTableName($name);
148
-
149
-		$this->copyTable($name, $tmpName);
150
-
151
-		//create the migration schema for the temporary table
152
-		$tmpTable = $this->renameTableSchema($table, $tmpName);
153
-		$schemaConfig = new SchemaConfig();
154
-		$schemaConfig->setName($this->connection->getDatabase());
155
-		$schema = new Schema(array($tmpTable), array(), $schemaConfig);
156
-
157
-		try {
158
-			$this->applySchema($schema);
159
-			$this->dropTable($tmpName);
160
-		} catch (DBALException $e) {
161
-			// pgsql needs to commit it's failed transaction before doing anything else
162
-			if ($this->connection->isTransactionActive()) {
163
-				$this->connection->commit();
164
-			}
165
-			$this->dropTable($tmpName);
166
-			throw new MigrationException($table->getName(), $e->getMessage());
167
-		}
168
-	}
169
-
170
-	/**
171
-	 * @param \Doctrine\DBAL\Schema\Table $table
172
-	 * @param string $newName
173
-	 * @return \Doctrine\DBAL\Schema\Table
174
-	 */
175
-	protected function renameTableSchema(Table $table, $newName) {
176
-		/**
177
-		 * @var \Doctrine\DBAL\Schema\Index[] $indexes
178
-		 */
179
-		$indexes = $table->getIndexes();
180
-		$newIndexes = array();
181
-		foreach ($indexes as $index) {
182
-			if ($index->isPrimary()) {
183
-				// do not rename primary key
184
-				$indexName = $index->getName();
185
-			} else {
186
-				// avoid conflicts in index names
187
-				$indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
188
-			}
189
-			$newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
190
-		}
191
-
192
-		// foreign keys are not supported so we just set it to an empty array
193
-		return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions());
194
-	}
195
-
196
-	public function createSchema() {
197
-		$filterExpression = $this->getFilterExpression();
198
-		$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
199
-		return $this->connection->getSchemaManager()->createSchema();
200
-	}
201
-
202
-	/**
203
-	 * @param Schema $targetSchema
204
-	 * @param \Doctrine\DBAL\Connection $connection
205
-	 * @return \Doctrine\DBAL\Schema\SchemaDiff
206
-	 * @throws DBALException
207
-	 */
208
-	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
209
-		// adjust varchar columns with a length higher then getVarcharMaxLength to clob
210
-		foreach ($targetSchema->getTables() as $table) {
211
-			foreach ($table->getColumns() as $column) {
212
-				if ($column->getType() instanceof StringType) {
213
-					if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
214
-						$column->setType(Type::getType('text'));
215
-						$column->setLength(null);
216
-					}
217
-				}
218
-			}
219
-		}
220
-
221
-		$filterExpression = $this->getFilterExpression();
222
-		$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
223
-		$sourceSchema = $connection->getSchemaManager()->createSchema();
224
-
225
-		// remove tables we don't know about
226
-		/** @var $table \Doctrine\DBAL\Schema\Table */
227
-		foreach ($sourceSchema->getTables() as $table) {
228
-			if (!$targetSchema->hasTable($table->getName())) {
229
-				$sourceSchema->dropTable($table->getName());
230
-			}
231
-		}
232
-		// remove sequences we don't know about
233
-		foreach ($sourceSchema->getSequences() as $table) {
234
-			if (!$targetSchema->hasSequence($table->getName())) {
235
-				$sourceSchema->dropSequence($table->getName());
236
-			}
237
-		}
238
-
239
-		$comparator = new Comparator();
240
-		return $comparator->compare($sourceSchema, $targetSchema);
241
-	}
242
-
243
-	/**
244
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
245
-	 * @param \Doctrine\DBAL\Connection $connection
246
-	 */
247
-	protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
248
-		if (is_null($connection)) {
249
-			$connection = $this->connection;
250
-		}
251
-
252
-		$schemaDiff = $this->getDiff($targetSchema, $connection);
253
-
254
-		$connection->beginTransaction();
255
-		$sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
256
-		$step = 0;
257
-		foreach ($sqls as $sql) {
258
-			$this->emit($sql, $step++, count($sqls));
259
-			$connection->query($sql);
260
-		}
261
-		$connection->commit();
262
-	}
263
-
264
-	/**
265
-	 * @param string $sourceName
266
-	 * @param string $targetName
267
-	 */
268
-	protected function copyTable($sourceName, $targetName) {
269
-		$quotedSource = $this->connection->quoteIdentifier($sourceName);
270
-		$quotedTarget = $this->connection->quoteIdentifier($targetName);
271
-
272
-		$this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
273
-		$this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
274
-	}
275
-
276
-	/**
277
-	 * @param string $name
278
-	 */
279
-	protected function dropTable($name) {
280
-		$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
281
-	}
282
-
283
-	/**
284
-	 * @param $statement
285
-	 * @return string
286
-	 */
287
-	protected function convertStatementToScript($statement) {
288
-		$script = $statement . ';';
289
-		$script .= PHP_EOL;
290
-		$script .= PHP_EOL;
291
-		return $script;
292
-	}
293
-
294
-	protected function getFilterExpression() {
295
-		return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
296
-	}
297
-
298
-	protected function emit($sql, $step, $max) {
299
-		if ($this->noEmit) {
300
-			return;
301
-		}
302
-		if(is_null($this->dispatcher)) {
303
-			return;
304
-		}
305
-		$this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max]));
306
-	}
307
-
308
-	private function emitCheckStep($tableName, $step, $max) {
309
-		if(is_null($this->dispatcher)) {
310
-			return;
311
-		}
312
-		$this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max]));
313
-	}
46
+    /** @var \Doctrine\DBAL\Connection */
47
+    protected $connection;
48
+
49
+    /** @var ISecureRandom */
50
+    private $random;
51
+
52
+    /** @var IConfig */
53
+    protected $config;
54
+
55
+    /** @var EventDispatcher  */
56
+    private $dispatcher;
57
+
58
+    /** @var bool */
59
+    private $noEmit = false;
60
+
61
+    /**
62
+     * @param \Doctrine\DBAL\Connection|Connection $connection
63
+     * @param ISecureRandom $random
64
+     * @param IConfig $config
65
+     * @param EventDispatcher $dispatcher
66
+     */
67
+    public function __construct(\Doctrine\DBAL\Connection $connection,
68
+                                ISecureRandom $random,
69
+                                IConfig $config,
70
+                                EventDispatcher $dispatcher = null) {
71
+        $this->connection = $connection;
72
+        $this->random = $random;
73
+        $this->config = $config;
74
+        $this->dispatcher = $dispatcher;
75
+    }
76
+
77
+    /**
78
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
79
+     */
80
+    public function migrate(Schema $targetSchema) {
81
+        $this->noEmit = true;
82
+        $this->applySchema($targetSchema);
83
+    }
84
+
85
+    /**
86
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
87
+     * @return string
88
+     */
89
+    public function generateChangeScript(Schema $targetSchema) {
90
+        $schemaDiff = $this->getDiff($targetSchema, $this->connection);
91
+
92
+        $script = '';
93
+        $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
94
+        foreach ($sqls as $sql) {
95
+            $script .= $this->convertStatementToScript($sql);
96
+        }
97
+
98
+        return $script;
99
+    }
100
+
101
+    /**
102
+     * @param Schema $targetSchema
103
+     * @throws \OC\DB\MigrationException
104
+     */
105
+    public function checkMigrate(Schema $targetSchema) {
106
+        $this->noEmit = true;
107
+        /**@var \Doctrine\DBAL\Schema\Table[] $tables */
108
+        $tables = $targetSchema->getTables();
109
+        $filterExpression = $this->getFilterExpression();
110
+        $this->connection->getConfiguration()->
111
+            setFilterSchemaAssetsExpression($filterExpression);
112
+        $existingTables = $this->connection->getSchemaManager()->listTableNames();
113
+
114
+        $step = 0;
115
+        foreach ($tables as $table) {
116
+            if (strpos($table->getName(), '.')) {
117
+                list(, $tableName) = explode('.', $table->getName());
118
+            } else {
119
+                $tableName = $table->getName();
120
+            }
121
+            $this->emitCheckStep($tableName, $step++, count($tables));
122
+            // don't need to check for new tables
123
+            if (array_search($tableName, $existingTables) !== false) {
124
+                $this->checkTableMigrate($table);
125
+            }
126
+        }
127
+    }
128
+
129
+    /**
130
+     * Create a unique name for the temporary table
131
+     *
132
+     * @param string $name
133
+     * @return string
134
+     */
135
+    protected function generateTemporaryTableName($name) {
136
+        return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
137
+    }
138
+
139
+    /**
140
+     * Check the migration of a table on a copy so we can detect errors before messing with the real table
141
+     *
142
+     * @param \Doctrine\DBAL\Schema\Table $table
143
+     * @throws \OC\DB\MigrationException
144
+     */
145
+    protected function checkTableMigrate(Table $table) {
146
+        $name = $table->getName();
147
+        $tmpName = $this->generateTemporaryTableName($name);
148
+
149
+        $this->copyTable($name, $tmpName);
150
+
151
+        //create the migration schema for the temporary table
152
+        $tmpTable = $this->renameTableSchema($table, $tmpName);
153
+        $schemaConfig = new SchemaConfig();
154
+        $schemaConfig->setName($this->connection->getDatabase());
155
+        $schema = new Schema(array($tmpTable), array(), $schemaConfig);
156
+
157
+        try {
158
+            $this->applySchema($schema);
159
+            $this->dropTable($tmpName);
160
+        } catch (DBALException $e) {
161
+            // pgsql needs to commit it's failed transaction before doing anything else
162
+            if ($this->connection->isTransactionActive()) {
163
+                $this->connection->commit();
164
+            }
165
+            $this->dropTable($tmpName);
166
+            throw new MigrationException($table->getName(), $e->getMessage());
167
+        }
168
+    }
169
+
170
+    /**
171
+     * @param \Doctrine\DBAL\Schema\Table $table
172
+     * @param string $newName
173
+     * @return \Doctrine\DBAL\Schema\Table
174
+     */
175
+    protected function renameTableSchema(Table $table, $newName) {
176
+        /**
177
+         * @var \Doctrine\DBAL\Schema\Index[] $indexes
178
+         */
179
+        $indexes = $table->getIndexes();
180
+        $newIndexes = array();
181
+        foreach ($indexes as $index) {
182
+            if ($index->isPrimary()) {
183
+                // do not rename primary key
184
+                $indexName = $index->getName();
185
+            } else {
186
+                // avoid conflicts in index names
187
+                $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
188
+            }
189
+            $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
190
+        }
191
+
192
+        // foreign keys are not supported so we just set it to an empty array
193
+        return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions());
194
+    }
195
+
196
+    public function createSchema() {
197
+        $filterExpression = $this->getFilterExpression();
198
+        $this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
199
+        return $this->connection->getSchemaManager()->createSchema();
200
+    }
201
+
202
+    /**
203
+     * @param Schema $targetSchema
204
+     * @param \Doctrine\DBAL\Connection $connection
205
+     * @return \Doctrine\DBAL\Schema\SchemaDiff
206
+     * @throws DBALException
207
+     */
208
+    protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
209
+        // adjust varchar columns with a length higher then getVarcharMaxLength to clob
210
+        foreach ($targetSchema->getTables() as $table) {
211
+            foreach ($table->getColumns() as $column) {
212
+                if ($column->getType() instanceof StringType) {
213
+                    if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
214
+                        $column->setType(Type::getType('text'));
215
+                        $column->setLength(null);
216
+                    }
217
+                }
218
+            }
219
+        }
220
+
221
+        $filterExpression = $this->getFilterExpression();
222
+        $this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
223
+        $sourceSchema = $connection->getSchemaManager()->createSchema();
224
+
225
+        // remove tables we don't know about
226
+        /** @var $table \Doctrine\DBAL\Schema\Table */
227
+        foreach ($sourceSchema->getTables() as $table) {
228
+            if (!$targetSchema->hasTable($table->getName())) {
229
+                $sourceSchema->dropTable($table->getName());
230
+            }
231
+        }
232
+        // remove sequences we don't know about
233
+        foreach ($sourceSchema->getSequences() as $table) {
234
+            if (!$targetSchema->hasSequence($table->getName())) {
235
+                $sourceSchema->dropSequence($table->getName());
236
+            }
237
+        }
238
+
239
+        $comparator = new Comparator();
240
+        return $comparator->compare($sourceSchema, $targetSchema);
241
+    }
242
+
243
+    /**
244
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
245
+     * @param \Doctrine\DBAL\Connection $connection
246
+     */
247
+    protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
248
+        if (is_null($connection)) {
249
+            $connection = $this->connection;
250
+        }
251
+
252
+        $schemaDiff = $this->getDiff($targetSchema, $connection);
253
+
254
+        $connection->beginTransaction();
255
+        $sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
256
+        $step = 0;
257
+        foreach ($sqls as $sql) {
258
+            $this->emit($sql, $step++, count($sqls));
259
+            $connection->query($sql);
260
+        }
261
+        $connection->commit();
262
+    }
263
+
264
+    /**
265
+     * @param string $sourceName
266
+     * @param string $targetName
267
+     */
268
+    protected function copyTable($sourceName, $targetName) {
269
+        $quotedSource = $this->connection->quoteIdentifier($sourceName);
270
+        $quotedTarget = $this->connection->quoteIdentifier($targetName);
271
+
272
+        $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
273
+        $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
274
+    }
275
+
276
+    /**
277
+     * @param string $name
278
+     */
279
+    protected function dropTable($name) {
280
+        $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
281
+    }
282
+
283
+    /**
284
+     * @param $statement
285
+     * @return string
286
+     */
287
+    protected function convertStatementToScript($statement) {
288
+        $script = $statement . ';';
289
+        $script .= PHP_EOL;
290
+        $script .= PHP_EOL;
291
+        return $script;
292
+    }
293
+
294
+    protected function getFilterExpression() {
295
+        return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
296
+    }
297
+
298
+    protected function emit($sql, $step, $max) {
299
+        if ($this->noEmit) {
300
+            return;
301
+        }
302
+        if(is_null($this->dispatcher)) {
303
+            return;
304
+        }
305
+        $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max]));
306
+    }
307
+
308
+    private function emitCheckStep($tableName, $step, $max) {
309
+        if(is_null($this->dispatcher)) {
310
+            return;
311
+        }
312
+        $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max]));
313
+    }
314 314
 }
Please login to merge, or discard this patch.
lib/private/DB/Connection.php 1 patch
Indentation   +400 added lines, -400 removed lines patch added patch discarded remove patch
@@ -42,404 +42,404 @@
 block discarded – undo
42 42
 use OCP\PreConditionNotMetException;
43 43
 
44 44
 class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
45
-	/**
46
-	 * @var string $tablePrefix
47
-	 */
48
-	protected $tablePrefix;
49
-
50
-	/**
51
-	 * @var \OC\DB\Adapter $adapter
52
-	 */
53
-	protected $adapter;
54
-
55
-	protected $lockedTable = null;
56
-
57
-	public function connect() {
58
-		try {
59
-			return parent::connect();
60
-		} catch (DBALException $e) {
61
-			// throw a new exception to prevent leaking info from the stacktrace
62
-			throw new DBALException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
63
-		}
64
-	}
65
-
66
-	/**
67
-	 * Returns a QueryBuilder for the connection.
68
-	 *
69
-	 * @return \OCP\DB\QueryBuilder\IQueryBuilder
70
-	 */
71
-	public function getQueryBuilder() {
72
-		return new QueryBuilder(
73
-			$this,
74
-			\OC::$server->getSystemConfig(),
75
-			\OC::$server->getLogger()
76
-		);
77
-	}
78
-
79
-	/**
80
-	 * Gets the QueryBuilder for the connection.
81
-	 *
82
-	 * @return \Doctrine\DBAL\Query\QueryBuilder
83
-	 * @deprecated please use $this->getQueryBuilder() instead
84
-	 */
85
-	public function createQueryBuilder() {
86
-		$backtrace = $this->getCallerBacktrace();
87
-		\OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
88
-		return parent::createQueryBuilder();
89
-	}
90
-
91
-	/**
92
-	 * Gets the ExpressionBuilder for the connection.
93
-	 *
94
-	 * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
95
-	 * @deprecated please use $this->getQueryBuilder()->expr() instead
96
-	 */
97
-	public function getExpressionBuilder() {
98
-		$backtrace = $this->getCallerBacktrace();
99
-		\OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
100
-		return parent::getExpressionBuilder();
101
-	}
102
-
103
-	/**
104
-	 * Get the file and line that called the method where `getCallerBacktrace()` was used
105
-	 *
106
-	 * @return string
107
-	 */
108
-	protected function getCallerBacktrace() {
109
-		$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
110
-
111
-		// 0 is the method where we use `getCallerBacktrace`
112
-		// 1 is the target method which uses the method we want to log
113
-		if (isset($traces[1])) {
114
-			return $traces[1]['file'] . ':' . $traces[1]['line'];
115
-		}
116
-
117
-		return '';
118
-	}
119
-
120
-	/**
121
-	 * @return string
122
-	 */
123
-	public function getPrefix() {
124
-		return $this->tablePrefix;
125
-	}
126
-
127
-	/**
128
-	 * Initializes a new instance of the Connection class.
129
-	 *
130
-	 * @param array $params  The connection parameters.
131
-	 * @param \Doctrine\DBAL\Driver $driver
132
-	 * @param \Doctrine\DBAL\Configuration $config
133
-	 * @param \Doctrine\Common\EventManager $eventManager
134
-	 * @throws \Exception
135
-	 */
136
-	public function __construct(array $params, Driver $driver, Configuration $config = null,
137
-		EventManager $eventManager = null)
138
-	{
139
-		if (!isset($params['adapter'])) {
140
-			throw new \Exception('adapter not set');
141
-		}
142
-		if (!isset($params['tablePrefix'])) {
143
-			throw new \Exception('tablePrefix not set');
144
-		}
145
-		parent::__construct($params, $driver, $config, $eventManager);
146
-		$this->adapter = new $params['adapter']($this);
147
-		$this->tablePrefix = $params['tablePrefix'];
148
-
149
-		parent::setTransactionIsolation(parent::TRANSACTION_READ_COMMITTED);
150
-	}
151
-
152
-	/**
153
-	 * Prepares an SQL statement.
154
-	 *
155
-	 * @param string $statement The SQL statement to prepare.
156
-	 * @param int $limit
157
-	 * @param int $offset
158
-	 * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
159
-	 */
160
-	public function prepare( $statement, $limit=null, $offset=null ) {
161
-		if ($limit === -1) {
162
-			$limit = null;
163
-		}
164
-		if (!is_null($limit)) {
165
-			$platform = $this->getDatabasePlatform();
166
-			$statement = $platform->modifyLimitQuery($statement, $limit, $offset);
167
-		}
168
-		$statement = $this->replaceTablePrefix($statement);
169
-		$statement = $this->adapter->fixupStatement($statement);
170
-
171
-		return parent::prepare($statement);
172
-	}
173
-
174
-	/**
175
-	 * Executes an, optionally parametrized, SQL query.
176
-	 *
177
-	 * If the query is parametrized, a prepared statement is used.
178
-	 * If an SQLLogger is configured, the execution is logged.
179
-	 *
180
-	 * @param string                                      $query  The SQL query to execute.
181
-	 * @param array                                       $params The parameters to bind to the query, if any.
182
-	 * @param array                                       $types  The types the previous parameters are in.
183
-	 * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp    The query cache profile, optional.
184
-	 *
185
-	 * @return \Doctrine\DBAL\Driver\Statement The executed statement.
186
-	 *
187
-	 * @throws \Doctrine\DBAL\DBALException
188
-	 */
189
-	public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
190
-	{
191
-		$query = $this->replaceTablePrefix($query);
192
-		$query = $this->adapter->fixupStatement($query);
193
-		return parent::executeQuery($query, $params, $types, $qcp);
194
-	}
195
-
196
-	/**
197
-	 * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
198
-	 * and returns the number of affected rows.
199
-	 *
200
-	 * This method supports PDO binding types as well as DBAL mapping types.
201
-	 *
202
-	 * @param string $query  The SQL query.
203
-	 * @param array  $params The query parameters.
204
-	 * @param array  $types  The parameter types.
205
-	 *
206
-	 * @return integer The number of affected rows.
207
-	 *
208
-	 * @throws \Doctrine\DBAL\DBALException
209
-	 */
210
-	public function executeUpdate($query, array $params = array(), array $types = array())
211
-	{
212
-		$query = $this->replaceTablePrefix($query);
213
-		$query = $this->adapter->fixupStatement($query);
214
-		return parent::executeUpdate($query, $params, $types);
215
-	}
216
-
217
-	/**
218
-	 * Returns the ID of the last inserted row, or the last value from a sequence object,
219
-	 * depending on the underlying driver.
220
-	 *
221
-	 * Note: This method may not return a meaningful or consistent result across different drivers,
222
-	 * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
223
-	 * columns or sequences.
224
-	 *
225
-	 * @param string $seqName Name of the sequence object from which the ID should be returned.
226
-	 * @return string A string representation of the last inserted ID.
227
-	 */
228
-	public function lastInsertId($seqName = null) {
229
-		if ($seqName) {
230
-			$seqName = $this->replaceTablePrefix($seqName);
231
-		}
232
-		return $this->adapter->lastInsertId($seqName);
233
-	}
234
-
235
-	// internal use
236
-	public function realLastInsertId($seqName = null) {
237
-		return parent::lastInsertId($seqName);
238
-	}
239
-
240
-	/**
241
-	 * Insert a row if the matching row does not exists.
242
-	 *
243
-	 * @param string $table The table name (will replace *PREFIX* with the actual prefix)
244
-	 * @param array $input data that should be inserted into the table  (column name => value)
245
-	 * @param array|null $compare List of values that should be checked for "if not exists"
246
-	 *				If this is null or an empty array, all keys of $input will be compared
247
-	 *				Please note: text fields (clob) must not be used in the compare array
248
-	 * @return int number of inserted rows
249
-	 * @throws \Doctrine\DBAL\DBALException
250
-	 */
251
-	public function insertIfNotExist($table, $input, array $compare = null) {
252
-		return $this->adapter->insertIfNotExist($table, $input, $compare);
253
-	}
254
-
255
-	private function getType($value) {
256
-		if (is_bool($value)) {
257
-			return IQueryBuilder::PARAM_BOOL;
258
-		} else if (is_int($value)) {
259
-			return IQueryBuilder::PARAM_INT;
260
-		} else {
261
-			return IQueryBuilder::PARAM_STR;
262
-		}
263
-	}
264
-
265
-	/**
266
-	 * Insert or update a row value
267
-	 *
268
-	 * @param string $table
269
-	 * @param array $keys (column name => value)
270
-	 * @param array $values (column name => value)
271
-	 * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
272
-	 * @return int number of new rows
273
-	 * @throws \Doctrine\DBAL\DBALException
274
-	 * @throws PreConditionNotMetException
275
-	 */
276
-	public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
277
-		try {
278
-			$insertQb = $this->getQueryBuilder();
279
-			$insertQb->insert($table)
280
-				->values(
281
-					array_map(function($value) use ($insertQb) {
282
-						return $insertQb->createNamedParameter($value, $this->getType($value));
283
-					}, array_merge($keys, $values))
284
-				);
285
-			return $insertQb->execute();
286
-		} catch (ConstraintViolationException $e) {
287
-			// value already exists, try update
288
-			$updateQb = $this->getQueryBuilder();
289
-			$updateQb->update($table);
290
-			foreach ($values as $name => $value) {
291
-				$updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
292
-			}
293
-			$where = $updateQb->expr()->andX();
294
-			$whereValues = array_merge($keys, $updatePreconditionValues);
295
-			foreach ($whereValues as $name => $value) {
296
-				$where->add($updateQb->expr()->eq(
297
-					$name,
298
-					$updateQb->createNamedParameter($value, $this->getType($value)),
299
-					$this->getType($value)
300
-				));
301
-			}
302
-			$updateQb->where($where);
303
-			$affected = $updateQb->execute();
304
-
305
-			if ($affected === 0 && !empty($updatePreconditionValues)) {
306
-				throw new PreConditionNotMetException();
307
-			}
308
-
309
-			return 0;
310
-		}
311
-	}
312
-
313
-	/**
314
-	 * Create an exclusive read+write lock on a table
315
-	 *
316
-	 * @param string $tableName
317
-	 * @throws \BadMethodCallException When trying to acquire a second lock
318
-	 * @since 9.1.0
319
-	 */
320
-	public function lockTable($tableName) {
321
-		if ($this->lockedTable !== null) {
322
-			throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
323
-		}
324
-
325
-		$tableName = $this->tablePrefix . $tableName;
326
-		$this->lockedTable = $tableName;
327
-		$this->adapter->lockTable($tableName);
328
-	}
329
-
330
-	/**
331
-	 * Release a previous acquired lock again
332
-	 *
333
-	 * @since 9.1.0
334
-	 */
335
-	public function unlockTable() {
336
-		$this->adapter->unlockTable();
337
-		$this->lockedTable = null;
338
-	}
339
-
340
-	/**
341
-	 * returns the error code and message as a string for logging
342
-	 * works with DoctrineException
343
-	 * @return string
344
-	 */
345
-	public function getError() {
346
-		$msg = $this->errorCode() . ': ';
347
-		$errorInfo = $this->errorInfo();
348
-		if (is_array($errorInfo)) {
349
-			$msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
350
-			$msg .= 'Driver Code = '.$errorInfo[1] . ', ';
351
-			$msg .= 'Driver Message = '.$errorInfo[2];
352
-		}
353
-		return $msg;
354
-	}
355
-
356
-	/**
357
-	 * Drop a table from the database if it exists
358
-	 *
359
-	 * @param string $table table name without the prefix
360
-	 */
361
-	public function dropTable($table) {
362
-		$table = $this->tablePrefix . trim($table);
363
-		$schema = $this->getSchemaManager();
364
-		if($schema->tablesExist(array($table))) {
365
-			$schema->dropTable($table);
366
-		}
367
-	}
368
-
369
-	/**
370
-	 * Check if a table exists
371
-	 *
372
-	 * @param string $table table name without the prefix
373
-	 * @return bool
374
-	 */
375
-	public function tableExists($table){
376
-		$table = $this->tablePrefix . trim($table);
377
-		$schema = $this->getSchemaManager();
378
-		return $schema->tablesExist(array($table));
379
-	}
380
-
381
-	// internal use
382
-	/**
383
-	 * @param string $statement
384
-	 * @return string
385
-	 */
386
-	protected function replaceTablePrefix($statement) {
387
-		return str_replace( '*PREFIX*', $this->tablePrefix, $statement );
388
-	}
389
-
390
-	/**
391
-	 * Check if a transaction is active
392
-	 *
393
-	 * @return bool
394
-	 * @since 8.2.0
395
-	 */
396
-	public function inTransaction() {
397
-		return $this->getTransactionNestingLevel() > 0;
398
-	}
399
-
400
-	/**
401
-	 * Espace a parameter to be used in a LIKE query
402
-	 *
403
-	 * @param string $param
404
-	 * @return string
405
-	 */
406
-	public function escapeLikeParameter($param) {
407
-		return addcslashes($param, '\\_%');
408
-	}
409
-
410
-	/**
411
-	 * Check whether or not the current database support 4byte wide unicode
412
-	 *
413
-	 * @return bool
414
-	 * @since 11.0.0
415
-	 */
416
-	public function supports4ByteText() {
417
-		if (!$this->getDatabasePlatform() instanceof MySqlPlatform) {
418
-			return true;
419
-		}
420
-		return $this->getParams()['charset'] === 'utf8mb4';
421
-	}
422
-
423
-
424
-	/**
425
-	 * Create the schema of the connected database
426
-	 *
427
-	 * @return Schema
428
-	 */
429
-	public function createSchema() {
430
-		$schemaManager = new MDB2SchemaManager($this);
431
-		$migrator = $schemaManager->getMigrator();
432
-		return $migrator->createSchema();
433
-	}
434
-
435
-	/**
436
-	 * Migrate the database to the given schema
437
-	 *
438
-	 * @param Schema $toSchema
439
-	 */
440
-	public function migrateToSchema(Schema $toSchema) {
441
-		$schemaManager = new MDB2SchemaManager($this);
442
-		$migrator = $schemaManager->getMigrator();
443
-		$migrator->migrate($toSchema);
444
-	}
45
+    /**
46
+     * @var string $tablePrefix
47
+     */
48
+    protected $tablePrefix;
49
+
50
+    /**
51
+     * @var \OC\DB\Adapter $adapter
52
+     */
53
+    protected $adapter;
54
+
55
+    protected $lockedTable = null;
56
+
57
+    public function connect() {
58
+        try {
59
+            return parent::connect();
60
+        } catch (DBALException $e) {
61
+            // throw a new exception to prevent leaking info from the stacktrace
62
+            throw new DBALException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
63
+        }
64
+    }
65
+
66
+    /**
67
+     * Returns a QueryBuilder for the connection.
68
+     *
69
+     * @return \OCP\DB\QueryBuilder\IQueryBuilder
70
+     */
71
+    public function getQueryBuilder() {
72
+        return new QueryBuilder(
73
+            $this,
74
+            \OC::$server->getSystemConfig(),
75
+            \OC::$server->getLogger()
76
+        );
77
+    }
78
+
79
+    /**
80
+     * Gets the QueryBuilder for the connection.
81
+     *
82
+     * @return \Doctrine\DBAL\Query\QueryBuilder
83
+     * @deprecated please use $this->getQueryBuilder() instead
84
+     */
85
+    public function createQueryBuilder() {
86
+        $backtrace = $this->getCallerBacktrace();
87
+        \OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
88
+        return parent::createQueryBuilder();
89
+    }
90
+
91
+    /**
92
+     * Gets the ExpressionBuilder for the connection.
93
+     *
94
+     * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
95
+     * @deprecated please use $this->getQueryBuilder()->expr() instead
96
+     */
97
+    public function getExpressionBuilder() {
98
+        $backtrace = $this->getCallerBacktrace();
99
+        \OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
100
+        return parent::getExpressionBuilder();
101
+    }
102
+
103
+    /**
104
+     * Get the file and line that called the method where `getCallerBacktrace()` was used
105
+     *
106
+     * @return string
107
+     */
108
+    protected function getCallerBacktrace() {
109
+        $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
110
+
111
+        // 0 is the method where we use `getCallerBacktrace`
112
+        // 1 is the target method which uses the method we want to log
113
+        if (isset($traces[1])) {
114
+            return $traces[1]['file'] . ':' . $traces[1]['line'];
115
+        }
116
+
117
+        return '';
118
+    }
119
+
120
+    /**
121
+     * @return string
122
+     */
123
+    public function getPrefix() {
124
+        return $this->tablePrefix;
125
+    }
126
+
127
+    /**
128
+     * Initializes a new instance of the Connection class.
129
+     *
130
+     * @param array $params  The connection parameters.
131
+     * @param \Doctrine\DBAL\Driver $driver
132
+     * @param \Doctrine\DBAL\Configuration $config
133
+     * @param \Doctrine\Common\EventManager $eventManager
134
+     * @throws \Exception
135
+     */
136
+    public function __construct(array $params, Driver $driver, Configuration $config = null,
137
+        EventManager $eventManager = null)
138
+    {
139
+        if (!isset($params['adapter'])) {
140
+            throw new \Exception('adapter not set');
141
+        }
142
+        if (!isset($params['tablePrefix'])) {
143
+            throw new \Exception('tablePrefix not set');
144
+        }
145
+        parent::__construct($params, $driver, $config, $eventManager);
146
+        $this->adapter = new $params['adapter']($this);
147
+        $this->tablePrefix = $params['tablePrefix'];
148
+
149
+        parent::setTransactionIsolation(parent::TRANSACTION_READ_COMMITTED);
150
+    }
151
+
152
+    /**
153
+     * Prepares an SQL statement.
154
+     *
155
+     * @param string $statement The SQL statement to prepare.
156
+     * @param int $limit
157
+     * @param int $offset
158
+     * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
159
+     */
160
+    public function prepare( $statement, $limit=null, $offset=null ) {
161
+        if ($limit === -1) {
162
+            $limit = null;
163
+        }
164
+        if (!is_null($limit)) {
165
+            $platform = $this->getDatabasePlatform();
166
+            $statement = $platform->modifyLimitQuery($statement, $limit, $offset);
167
+        }
168
+        $statement = $this->replaceTablePrefix($statement);
169
+        $statement = $this->adapter->fixupStatement($statement);
170
+
171
+        return parent::prepare($statement);
172
+    }
173
+
174
+    /**
175
+     * Executes an, optionally parametrized, SQL query.
176
+     *
177
+     * If the query is parametrized, a prepared statement is used.
178
+     * If an SQLLogger is configured, the execution is logged.
179
+     *
180
+     * @param string                                      $query  The SQL query to execute.
181
+     * @param array                                       $params The parameters to bind to the query, if any.
182
+     * @param array                                       $types  The types the previous parameters are in.
183
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp    The query cache profile, optional.
184
+     *
185
+     * @return \Doctrine\DBAL\Driver\Statement The executed statement.
186
+     *
187
+     * @throws \Doctrine\DBAL\DBALException
188
+     */
189
+    public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
190
+    {
191
+        $query = $this->replaceTablePrefix($query);
192
+        $query = $this->adapter->fixupStatement($query);
193
+        return parent::executeQuery($query, $params, $types, $qcp);
194
+    }
195
+
196
+    /**
197
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
198
+     * and returns the number of affected rows.
199
+     *
200
+     * This method supports PDO binding types as well as DBAL mapping types.
201
+     *
202
+     * @param string $query  The SQL query.
203
+     * @param array  $params The query parameters.
204
+     * @param array  $types  The parameter types.
205
+     *
206
+     * @return integer The number of affected rows.
207
+     *
208
+     * @throws \Doctrine\DBAL\DBALException
209
+     */
210
+    public function executeUpdate($query, array $params = array(), array $types = array())
211
+    {
212
+        $query = $this->replaceTablePrefix($query);
213
+        $query = $this->adapter->fixupStatement($query);
214
+        return parent::executeUpdate($query, $params, $types);
215
+    }
216
+
217
+    /**
218
+     * Returns the ID of the last inserted row, or the last value from a sequence object,
219
+     * depending on the underlying driver.
220
+     *
221
+     * Note: This method may not return a meaningful or consistent result across different drivers,
222
+     * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
223
+     * columns or sequences.
224
+     *
225
+     * @param string $seqName Name of the sequence object from which the ID should be returned.
226
+     * @return string A string representation of the last inserted ID.
227
+     */
228
+    public function lastInsertId($seqName = null) {
229
+        if ($seqName) {
230
+            $seqName = $this->replaceTablePrefix($seqName);
231
+        }
232
+        return $this->adapter->lastInsertId($seqName);
233
+    }
234
+
235
+    // internal use
236
+    public function realLastInsertId($seqName = null) {
237
+        return parent::lastInsertId($seqName);
238
+    }
239
+
240
+    /**
241
+     * Insert a row if the matching row does not exists.
242
+     *
243
+     * @param string $table The table name (will replace *PREFIX* with the actual prefix)
244
+     * @param array $input data that should be inserted into the table  (column name => value)
245
+     * @param array|null $compare List of values that should be checked for "if not exists"
246
+     *				If this is null or an empty array, all keys of $input will be compared
247
+     *				Please note: text fields (clob) must not be used in the compare array
248
+     * @return int number of inserted rows
249
+     * @throws \Doctrine\DBAL\DBALException
250
+     */
251
+    public function insertIfNotExist($table, $input, array $compare = null) {
252
+        return $this->adapter->insertIfNotExist($table, $input, $compare);
253
+    }
254
+
255
+    private function getType($value) {
256
+        if (is_bool($value)) {
257
+            return IQueryBuilder::PARAM_BOOL;
258
+        } else if (is_int($value)) {
259
+            return IQueryBuilder::PARAM_INT;
260
+        } else {
261
+            return IQueryBuilder::PARAM_STR;
262
+        }
263
+    }
264
+
265
+    /**
266
+     * Insert or update a row value
267
+     *
268
+     * @param string $table
269
+     * @param array $keys (column name => value)
270
+     * @param array $values (column name => value)
271
+     * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
272
+     * @return int number of new rows
273
+     * @throws \Doctrine\DBAL\DBALException
274
+     * @throws PreConditionNotMetException
275
+     */
276
+    public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
277
+        try {
278
+            $insertQb = $this->getQueryBuilder();
279
+            $insertQb->insert($table)
280
+                ->values(
281
+                    array_map(function($value) use ($insertQb) {
282
+                        return $insertQb->createNamedParameter($value, $this->getType($value));
283
+                    }, array_merge($keys, $values))
284
+                );
285
+            return $insertQb->execute();
286
+        } catch (ConstraintViolationException $e) {
287
+            // value already exists, try update
288
+            $updateQb = $this->getQueryBuilder();
289
+            $updateQb->update($table);
290
+            foreach ($values as $name => $value) {
291
+                $updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
292
+            }
293
+            $where = $updateQb->expr()->andX();
294
+            $whereValues = array_merge($keys, $updatePreconditionValues);
295
+            foreach ($whereValues as $name => $value) {
296
+                $where->add($updateQb->expr()->eq(
297
+                    $name,
298
+                    $updateQb->createNamedParameter($value, $this->getType($value)),
299
+                    $this->getType($value)
300
+                ));
301
+            }
302
+            $updateQb->where($where);
303
+            $affected = $updateQb->execute();
304
+
305
+            if ($affected === 0 && !empty($updatePreconditionValues)) {
306
+                throw new PreConditionNotMetException();
307
+            }
308
+
309
+            return 0;
310
+        }
311
+    }
312
+
313
+    /**
314
+     * Create an exclusive read+write lock on a table
315
+     *
316
+     * @param string $tableName
317
+     * @throws \BadMethodCallException When trying to acquire a second lock
318
+     * @since 9.1.0
319
+     */
320
+    public function lockTable($tableName) {
321
+        if ($this->lockedTable !== null) {
322
+            throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
323
+        }
324
+
325
+        $tableName = $this->tablePrefix . $tableName;
326
+        $this->lockedTable = $tableName;
327
+        $this->adapter->lockTable($tableName);
328
+    }
329
+
330
+    /**
331
+     * Release a previous acquired lock again
332
+     *
333
+     * @since 9.1.0
334
+     */
335
+    public function unlockTable() {
336
+        $this->adapter->unlockTable();
337
+        $this->lockedTable = null;
338
+    }
339
+
340
+    /**
341
+     * returns the error code and message as a string for logging
342
+     * works with DoctrineException
343
+     * @return string
344
+     */
345
+    public function getError() {
346
+        $msg = $this->errorCode() . ': ';
347
+        $errorInfo = $this->errorInfo();
348
+        if (is_array($errorInfo)) {
349
+            $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
350
+            $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
351
+            $msg .= 'Driver Message = '.$errorInfo[2];
352
+        }
353
+        return $msg;
354
+    }
355
+
356
+    /**
357
+     * Drop a table from the database if it exists
358
+     *
359
+     * @param string $table table name without the prefix
360
+     */
361
+    public function dropTable($table) {
362
+        $table = $this->tablePrefix . trim($table);
363
+        $schema = $this->getSchemaManager();
364
+        if($schema->tablesExist(array($table))) {
365
+            $schema->dropTable($table);
366
+        }
367
+    }
368
+
369
+    /**
370
+     * Check if a table exists
371
+     *
372
+     * @param string $table table name without the prefix
373
+     * @return bool
374
+     */
375
+    public function tableExists($table){
376
+        $table = $this->tablePrefix . trim($table);
377
+        $schema = $this->getSchemaManager();
378
+        return $schema->tablesExist(array($table));
379
+    }
380
+
381
+    // internal use
382
+    /**
383
+     * @param string $statement
384
+     * @return string
385
+     */
386
+    protected function replaceTablePrefix($statement) {
387
+        return str_replace( '*PREFIX*', $this->tablePrefix, $statement );
388
+    }
389
+
390
+    /**
391
+     * Check if a transaction is active
392
+     *
393
+     * @return bool
394
+     * @since 8.2.0
395
+     */
396
+    public function inTransaction() {
397
+        return $this->getTransactionNestingLevel() > 0;
398
+    }
399
+
400
+    /**
401
+     * Espace a parameter to be used in a LIKE query
402
+     *
403
+     * @param string $param
404
+     * @return string
405
+     */
406
+    public function escapeLikeParameter($param) {
407
+        return addcslashes($param, '\\_%');
408
+    }
409
+
410
+    /**
411
+     * Check whether or not the current database support 4byte wide unicode
412
+     *
413
+     * @return bool
414
+     * @since 11.0.0
415
+     */
416
+    public function supports4ByteText() {
417
+        if (!$this->getDatabasePlatform() instanceof MySqlPlatform) {
418
+            return true;
419
+        }
420
+        return $this->getParams()['charset'] === 'utf8mb4';
421
+    }
422
+
423
+
424
+    /**
425
+     * Create the schema of the connected database
426
+     *
427
+     * @return Schema
428
+     */
429
+    public function createSchema() {
430
+        $schemaManager = new MDB2SchemaManager($this);
431
+        $migrator = $schemaManager->getMigrator();
432
+        return $migrator->createSchema();
433
+    }
434
+
435
+    /**
436
+     * Migrate the database to the given schema
437
+     *
438
+     * @param Schema $toSchema
439
+     */
440
+    public function migrateToSchema(Schema $toSchema) {
441
+        $schemaManager = new MDB2SchemaManager($this);
442
+        $migrator = $schemaManager->getMigrator();
443
+        $migrator->migrate($toSchema);
444
+    }
445 445
 }
Please login to merge, or discard this patch.