Skip to content

Commit ffc3622

Browse files
author
Gaetano Giunta
committed
allow toek replacement in filenames for sql execution
1 parent c3887a4 commit ffc3622

File tree

5 files changed

+42
-11
lines changed

5 files changed

+42
-11
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ to a file and then execute it in parallel on all databases:
6868

6969
*NB* to share files between the host computer and the container, put them in the `shared` folder.
7070

71+
*NB* you can also execute different sql commands based on database type by saving them to separate files. The `sql:execute`
72+
command does replace some tokens in the values of the `--file` option. Eg:
73+
74+
php bin/console sql:execute --file='./shared/test_{dbtype}.sql'
75+
76+
will look for files `test_mariadb.sql`, `test_mssql.sql`, `test_mysql.sql`, `test_`
77+
7178
From within the worker container, you can also list all available databases:
7279

7380
php bin/console db3v4l:instance:list

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
- worker: improve sql execution cmd:
2-
+ allow it to pick a set of desired instances
32
+ allow it to pick an existing db/user
43
+ disallow execution of commands that are part of the db client instead of being sent to the server, such as eg. 'use db'
54
- ok for mysql? (to be tested)

WHATSNEW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Version 0.5
33

44
- New: added Microsoft SQL Server 2017 and 2017
55

6+
- New: added the possibility to run sql commands against a subset of all available databases
7+
8+
- New: when running `db3v4l:sql:execute --file`, it is now possible to use placeholder tokens in the path/name of the
9+
sql file to execute. This allows to run a different set of commands based on the database type.
10+
Accepted tokens are at the moment `{dbtype}` and `{instancename}` (including the curly braces)
11+
612
- Fixed: allow possibility of settings custom configs for the new PostgreSQL versions added in release 0.4
713

814

app/config/services.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ parameters:
77

88
db3v4l.database_instances:
99
# Same format as the connection options used by doctrine
10+
# Please use the 'database type' as initial part of the name, followed by an underscore
1011
mariadb_5_5:
1112
host: mariadb_5_5
1213
port: 3306

app/src/Command/SqlExecute.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protected function configure()
1717
$this
1818
->setDescription('Executes an SQL command in parallel on all configured database instances, creating a dedicated temporary database (and user)')
1919
->addOption('sql', null, InputOption::VALUE_REQUIRED, 'The sql command(s) string to execute')
20-
->addOption('file', null, InputOption::VALUE_REQUIRED, 'A file with sql commands to execute')
20+
->addOption('file', null, InputOption::VALUE_REQUIRED, "A file with sql commands to execute. The tokens '{dbtype}' and '{instancename}' will be replaced with actual values")
2121
->addCommonOptions()
2222
;
2323
}
@@ -114,13 +114,18 @@ protected function executeSQL(array $dbConnectionSpecs, $sql, $file = null, $for
114114
/** @var Process[] $processes */
115115
$processes = [];
116116
$executors = [];
117-
foreach ($dbConnectionSpecs as $dbName => $dbConnectionSpec) {
117+
$filePattern = $file;
118+
foreach ($dbConnectionSpecs as $instanceName => $dbConnectionSpec) {
118119

119120
$executor = $this->executorFactory->createForkedExecutor($dbConnectionSpec);
120121

121122
if ($sql != null) {
122123
$process = $executor->getExecuteCommandProcess($sql);
123124
} else {
125+
$file = $this->replaceDBSpecTokens($filePattern, $instanceName, $dbConnectionSpec);
126+
if (!is_file($file)) {
127+
throw new \RuntimeException("Can not find sql file for execution: '$file'");
128+
}
124129
$process = $executor->getExecuteFileProcess($file);
125130
}
126131

@@ -130,8 +135,8 @@ protected function executeSQL(array $dbConnectionSpecs, $sql, $file = null, $for
130135

131136
$process->setTimeout($timeout);
132137

133-
$executors[$dbName] = $executor;
134-
$processes[$dbName] = $process;
138+
$executors[$instanceName] = $executor;
139+
$processes[$instanceName] = $process;
135140
}
136141

137142
if ($format === 'text') {
@@ -143,22 +148,22 @@ protected function executeSQL(array $dbConnectionSpecs, $sql, $file = null, $for
143148
$succeeded = 0;
144149
$failed = 0;
145150
$results = array();
146-
foreach ($processes as $dbName => $process) {
147-
$results[$dbName] = array(
151+
foreach ($processes as $instanceName => $process) {
152+
$results[$instanceName] = array(
148153
'stdout' => rtrim($process->getOutput()),
149154
'stderr' => trim($process->getErrorOutput()),
150155
'exitcode' => $process->getExitCode()
151156
);
152157

153-
if ($executors[$dbName] instanceof TimedExecutor) {
154-
$timingData = $executors[$dbName]->getTimingData();
155-
$results[$dbName] = array_merge($results[$dbName], $timingData);
158+
if ($executors[$instanceName] instanceof TimedExecutor) {
159+
$timingData = $executors[$instanceName]->getTimingData();
160+
$results[$instanceName] = array_merge($results[$instanceName], $timingData);
156161
}
157162

158163
if ($process->isSuccessful()) {
159164
$succeeded++;
160165
} else {
161-
$this->writeErrorln("\n<error>Execution on database '$dbName' failed! Reason: " . $process->getErrorOutput() . "</error>\n", OutputInterface::VERBOSITY_NORMAL);
166+
$this->writeErrorln("\n<error>Execution on database '$instanceName' failed! Reason: " . $process->getErrorOutput() . "</error>\n", OutputInterface::VERBOSITY_NORMAL);
162167
$failed++;
163168
}
164169
}
@@ -207,4 +212,17 @@ public function onSubProcessOutput($type, $buffer, $processIndex, $process = nul
207212
}
208213
}
209214
}
215+
216+
/**
217+
* Replaces tokens
218+
* @param string $instanceName
219+
* @aparam string[] $dbConnectionSpec
220+
* @param $string
221+
* @return string
222+
*/
223+
protected function replaceDBSpecTokens($string, $instanceName, $dbConnectionSpec)
224+
{
225+
$dbType = explode('_', $instanceName, 2)[0];
226+
return str_replace(array('{dbtype}', '{instancename}'), array($dbType, $instanceName), $string);
227+
}
210228
}

0 commit comments

Comments
 (0)