Skip to content
This repository was archived by the owner on Aug 15, 2023. It is now read-only.

Commit 9d051a3

Browse files
author
Stefano Kowalke
committed
[FEATURE] Add dry run to the db compare
This implements the template method pattern. Resolves #49
1 parent 3359e9c commit 9d051a3

File tree

7 files changed

+500
-214
lines changed

7 files changed

+500
-214
lines changed

Classes/Command/DatabaseApiCommandController.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ class DatabaseApiCommandController extends CommandController {
4040
* Leave the argument 'actions' empty or use "help" to see the available ones
4141
*
4242
* @param string $actions List of actions which will be executed
43+
* @param bool $dry
4344
*/
44-
public function databaseCompareCommand($actions = '') {
45+
public function databaseCompareCommand($actions = '', $dry = FALSE) {
4546
$service = $this->getService();
4647

4748
if ($actions === 'help' || strlen($actions) === 0) {
@@ -52,12 +53,25 @@ public function databaseCompareCommand($actions = '') {
5253
$this->quit();
5354
}
5455

55-
$result = $service->databaseCompare($actions);
56-
if (empty($result)) {
57-
$this->outputLine('DB has been compared');
56+
$result = $service->databaseCompare($actions, $dry);
57+
58+
if ($dry) {
59+
$this->outputLine('DB compare would execute the following queries:');
60+
foreach($result as $key => $set) {
61+
$this->outputLine(sprintf('### Action: %s ###', $key));
62+
$this->outputLine('===================================');
63+
foreach($set as $line) {
64+
$this->outputLine($line);
65+
}
66+
$this->outputLine(LF);
67+
}
5868
} else {
59-
$this->outputLine('DB could not be compared, Error(s): %s', array(LF . implode(LF, $result)));
60-
$this->quit();
69+
if (empty($result)) {
70+
$this->outputLine('DB has been compared');
71+
} else {
72+
$this->outputLine('DB could not be compared, Error(s): %s', array(LF . implode(LF, $result)));
73+
$this->quit();
74+
}
6175
}
6276
}
6377

Classes/Service/DatabaseApiService.php

Lines changed: 19 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,11 @@
3636
* @package Etobi\CoreAPI\Service\SiteApiService
3737
*/
3838
class DatabaseApiService {
39-
const ACTION_UPDATE_CLEAR_TABLE = 1;
40-
const ACTION_UPDATE_ADD = 2;
41-
const ACTION_UPDATE_CHANGE = 3;
42-
const ACTION_UPDATE_CREATE_TABLE = 4;
43-
const ACTION_REMOVE_CHANGE = 5;
44-
const ACTION_REMOVE_DROP = 6;
45-
const ACTION_REMOVE_CHANGE_TABLE = 7;
46-
const ACTION_REMOVE_DROP_TABLE = 8;
39+
40+
/**
41+
* @var \Etobi\CoreAPI\Service\DatabaseComparator $comparator
42+
*/
43+
protected $comparator = NULL;
4744

4845
/**
4946
* @var \TYPO3\CMS\Install\Service\SqlSchemaMigrationService $schemaMigrationService Instance of SQL handler
@@ -76,104 +73,26 @@ public function injectSchemaMigrationService(\TYPO3\CMS\Install\Service\SqlSchem
7673
/**
7774
* Database compare.
7875
*
79-
* @param string $actions comma separated list of IDs
76+
* @param string $actions comma separated list of IDs
77+
* @param boolean $dry
8078
*
81-
* @throws InvalidArgumentException
79+
* @throws \InvalidArgumentException
8280
* @return array
8381
*/
84-
public function databaseCompare($actions) {
85-
$errors = array();
86-
87-
$test = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\ClassReflection', 'Etobi\\CoreAPI\\Service\\DatabaseApiService');
88-
$availableActions = array_flip($test->getConstants());
89-
90-
if (empty($actions)) {
91-
throw new InvalidArgumentException('No compare modes defined');
92-
}
93-
94-
$allowedActions = array();
95-
$actionSplit = $this->trimExplode($actions);
96-
foreach ($actionSplit as $split) {
97-
if (!isset($availableActions[$split])) {
98-
throw new InvalidArgumentException(sprintf('Action "%s" is not available!', $split));
99-
}
100-
$allowedActions[$split] = 1;
101-
}
102-
103-
$tblFileContent = '';
104-
105-
foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) {
106-
if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) {
107-
$extensionSqlContent = $this->getUrl($loadedExtConf['ext_tables.sql']);
108-
$tblFileContent .= LF . LF . LF . LF . $extensionSqlContent;
109-
}
82+
public function databaseCompare($actions, $dry) {
83+
if ($dry) {
84+
$this->comparator = $this->objectManager->get('Etobi\\CoreAPI\\Service\\DatabaseCompareDry');
85+
} else {
86+
$this->comparator = $this->objectManager->get('Etobi\\CoreAPI\\Service\\DatabaseCompareReal');
11087
}
11188

112-
if (is_callable('TYPO3\\CMS\\Core\\Cache\\Cache::getDatabaseTableDefinitions')) {
113-
$tblFileContent .= $this->getDatabaseTableDefinitionsFromCache();
89+
try {
90+
$result = $this->comparator->databaseCompare($actions);
91+
} catch (\Exception $e) {
92+
throw new \InvalidArgumentException($e->getMessage());
11493
}
11594

116-
if (class_exists('TYPO3\\CMS\\Core\\Category\\CategoryRegistry')) {
117-
$tblFileContent .= $this->getCategoryRegistry()->getDatabaseTableDefinitions();
118-
}
119-
120-
if ($tblFileContent) {
121-
$fileContent = implode(LF, $this->schemaMigrationService->getStatementArray($tblFileContent, 1, '^CREATE TABLE '));
122-
$fieldDefinitionsFromFile = $this->schemaMigrationService->getFieldDefinitions_fileContent($fileContent);
123-
124-
$fieldDefinitionsFromDb = $this->schemaMigrationService->getFieldDefinitions_database();
125-
126-
$diff = $this->schemaMigrationService->getDatabaseExtra($fieldDefinitionsFromFile, $fieldDefinitionsFromDb);
127-
$updateStatements = $this->schemaMigrationService->getUpdateSuggestions($diff);
128-
129-
$diff = $this->schemaMigrationService->getDatabaseExtra($fieldDefinitionsFromDb, $fieldDefinitionsFromFile);
130-
$removeStatements = $this->schemaMigrationService->getUpdateSuggestions($diff, 'remove');
131-
132-
$allowedRequestKeys = $this->getRequestKeys($updateStatements, $removeStatements);
133-
$results = array();
134-
135-
if ($allowedActions[self::ACTION_UPDATE_CLEAR_TABLE] == 1) {
136-
$results[] = $this->schemaMigrationService->performUpdateQueries($updateStatements['clear_table'], $allowedRequestKeys);
137-
}
138-
139-
if ($allowedActions[self::ACTION_UPDATE_ADD] == 1) {
140-
$results[] = $this->schemaMigrationService->performUpdateQueries($updateStatements['add'], $allowedRequestKeys);
141-
}
142-
143-
if ($allowedActions[self::ACTION_UPDATE_CHANGE] == 1) {
144-
$results[] = $this->schemaMigrationService->performUpdateQueries($updateStatements['change'], $allowedRequestKeys);
145-
}
146-
147-
if ($allowedActions[self::ACTION_REMOVE_CHANGE] == 1) {
148-
$results[] = $this->schemaMigrationService->performUpdateQueries($removeStatements['change'], $allowedRequestKeys);
149-
}
150-
151-
if ($allowedActions[self::ACTION_REMOVE_DROP] == 1) {
152-
$results[] = $this->schemaMigrationService->performUpdateQueries($removeStatements['drop'], $allowedRequestKeys);
153-
}
154-
155-
if ($allowedActions[self::ACTION_UPDATE_CREATE_TABLE] == 1) {
156-
$results[] = $this->schemaMigrationService->performUpdateQueries($updateStatements['create_table'], $allowedRequestKeys);
157-
}
158-
159-
if ($allowedActions[self::ACTION_REMOVE_CHANGE_TABLE] == 1) {
160-
$results[] = $this->schemaMigrationService->performUpdateQueries($removeStatements['change_table'], $allowedRequestKeys);
161-
}
162-
163-
if ($allowedActions[self::ACTION_REMOVE_DROP_TABLE] == 1) {
164-
$results[] = $this->schemaMigrationService->performUpdateQueries($removeStatements['drop_table'], $allowedRequestKeys);
165-
}
166-
167-
foreach ($results as $resultSet) {
168-
if (is_array($resultSet)) {
169-
foreach ($resultSet as $key => $errorMessage) {
170-
$errors[$key] = $errorMessage;
171-
}
172-
}
173-
}
174-
}
175-
176-
return $errors;
95+
return $result;
17796
}
17897

17998
/**
@@ -182,7 +101,7 @@ public function databaseCompare($actions) {
182101
* @return array
183102
*/
184103
public function databaseCompareAvailableActions() {
185-
$availableActions = array_flip($this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\ClassReflection', 'Etobi\\CoreAPI\\Service\\DatabaseApiService')->getConstants());
104+
$availableActions = array_flip($this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\ClassReflection', 'Etobi\\CoreAPI\\Service\\DatabaseComparator')->getConstants());
186105

187106
foreach ($availableActions as $number => $action) {
188107
if (!$this->isFirstPartOfString($action, 'ACTION_')) {
@@ -192,80 +111,6 @@ public function databaseCompareAvailableActions() {
192111
return $availableActions;
193112
}
194113

195-
/**
196-
* Get all request keys, even for those requests which are not used.
197-
*
198-
* @param array $update
199-
* @param array $remove
200-
*
201-
* @return array
202-
*/
203-
protected function getRequestKeys(array $update, array $remove) {
204-
$tmpKeys = array();
205-
206-
$updateActions = array('clear_table', 'add', 'change', 'create_table');
207-
$removeActions = array('change', 'drop', 'change_table', 'drop_table');
208-
209-
foreach ($updateActions as $updateAction) {
210-
if (isset($update[$updateAction]) && is_array($update[$updateAction])) {
211-
$tmpKeys[] = array_keys($update[$updateAction]);
212-
}
213-
}
214-
215-
foreach ($removeActions as $removeAction) {
216-
if (isset($remove[$removeAction]) && is_array($remove[$removeAction])) {
217-
$tmpKeys[] = array_keys($remove[$removeAction]);
218-
}
219-
}
220-
221-
$finalKeys = array();
222-
foreach ($tmpKeys as $keys) {
223-
foreach ($keys as $key) {
224-
$finalKeys[$key] = TRUE;
225-
}
226-
}
227-
return $finalKeys;
228-
}
229-
230-
/**
231-
* Wrapper around GeneralUtility::trimExplode
232-
*
233-
* @param string $values The values to explode
234-
*
235-
* @return array
236-
*/
237-
protected function trimExplode($values) {
238-
return GeneralUtility::trimExplode(',', $values);
239-
}
240-
241-
/**
242-
* Wrapper around GeneralUtility::getUrl()
243-
* @param $url
244-
*
245-
* @return mixed
246-
*/
247-
protected function getUrl($url) {
248-
return GeneralUtility::getUrl($url);
249-
}
250-
251-
/**
252-
* Wrapper around Cache::getDatabaseTableDefinitions()
253-
*
254-
* @return string
255-
*/
256-
protected function getDatabaseTableDefinitionsFromCache() {
257-
return Cache::getDatabaseTableDefinitions();
258-
}
259-
260-
/**
261-
* Wrapper around \TYPO3\CMS\Core\Category\CategoryRegistry::getInstance()
262-
*
263-
* @return \TYPO3\CMS\Core\Category\CategoryRegistry
264-
*/
265-
protected function getCategoryRegistry() {
266-
return \TYPO3\CMS\Core\Category\CategoryRegistry::getInstance();
267-
}
268-
269114
/**
270115
* Wrapper around GeneralUtility::isFirstPartOfStr()
271116
*
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
namespace Etobi\CoreAPI\Service;
4+
5+
/**
6+
* This file is part of the TYPO3 CMS project.
7+
*
8+
* It is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU General Public License, either version 2
10+
* of the License, or any later version.
11+
*
12+
* For the full copyright and license information, please read the
13+
* LICENSE.txt file that was distributed with this source code.
14+
*
15+
* The TYPO3 project - inspiring people to share!
16+
*/
17+
use InvalidArgumentException;
18+
use TYPO3\CMS\Core\Cache\Cache;
19+
use TYPO3\CMS\Core\Utility\GeneralUtility;
20+
21+
/**
22+
* Class DatabaseCompareAbstract
23+
*
24+
* @package Etobi\CoreAPI\Service
25+
* @author Stefano Kowalke <[email protected]>
26+
*/
27+
abstract class DatabaseComparator {
28+
const ACTION_UPDATE_CLEAR_TABLE = 1;
29+
const ACTION_UPDATE_ADD = 2;
30+
const ACTION_UPDATE_CHANGE = 3;
31+
const ACTION_UPDATE_CREATE_TABLE = 4;
32+
const ACTION_REMOVE_CHANGE = 5;
33+
const ACTION_REMOVE_DROP = 6;
34+
const ACTION_REMOVE_CHANGE_TABLE = 7;
35+
const ACTION_REMOVE_DROP_TABLE = 8;
36+
37+
/**
38+
* @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
39+
*/
40+
protected $objectManager;
41+
42+
/**
43+
* Inject the ObjectManager
44+
*
45+
* @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
46+
*/
47+
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager) {
48+
$this->objectManager = $objectManager;
49+
}
50+
51+
/**
52+
* @param $actions
53+
*
54+
* @return mixed
55+
*/
56+
public final function databaseCompare($actions) {
57+
return $this->compare($actions);
58+
}
59+
60+
protected abstract function compare($action);
61+
62+
/**
63+
* Wrapper around GeneralUtility::trimExplode
64+
*
65+
* @param string $values The values to explode
66+
*
67+
* @return array
68+
*/
69+
protected function trimExplode($values) {
70+
return GeneralUtility::trimExplode(',', $values);
71+
}
72+
73+
/**
74+
* Wrapper around GeneralUtility::getUrl()
75+
* @param $url
76+
*
77+
* @return mixed
78+
*/
79+
protected function getUrl($url) {
80+
return GeneralUtility::getUrl($url);
81+
}
82+
83+
/**
84+
* Wrapper around Cache::getDatabaseTableDefinitions()
85+
*
86+
* @return string
87+
*/
88+
protected function getDatabaseTableDefinitionsFromCache() {
89+
return Cache::getDatabaseTableDefinitions();
90+
}
91+
92+
/**
93+
* Wrapper around \TYPO3\CMS\Core\Category\CategoryRegistry::getInstance()
94+
*
95+
* @return \TYPO3\CMS\Core\Category\CategoryRegistry
96+
*/
97+
protected function getCategoryRegistry() {
98+
return \TYPO3\CMS\Core\Category\CategoryRegistry::getInstance();
99+
}
100+
101+
/**
102+
* Checks the given actions against the defined and allowed actions
103+
*
104+
* @param $actions
105+
* @param array $allowedActions
106+
*
107+
* @throws InvalidArgumentException
108+
*/
109+
protected function checkAvailableActions($actions, array &$allowedActions = array()) {
110+
$classReflection = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\ClassReflection', 'Etobi\\CoreAPI\\Service\\DatabaseComparator');
111+
$availableActions = array_flip($classReflection->getConstants());
112+
113+
if (empty($actions)) {
114+
throw new InvalidArgumentException('No compare modes defined');
115+
}
116+
117+
$actionSplit = $this->trimExplode($actions);
118+
foreach ($actionSplit as $split) {
119+
if (!isset($availableActions[$split])) {
120+
throw new InvalidArgumentException(sprintf('Action "%s" is not available!', $split));
121+
}
122+
$allowedActions[$split] = 1;
123+
}
124+
}
125+
}
126+

0 commit comments

Comments
 (0)