1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Gendoria\CruftFlake\Command; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\DBALException; |
6
|
|
|
use Doctrine\DBAL\DriverManager; |
7
|
|
|
use Gendoria\CruftFlake\Config\DoctrineConfig; |
8
|
|
|
use Symfony\Component\Console\Command\Command; |
9
|
|
|
use Symfony\Component\Console\Helper\QuestionHelper; |
10
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
11
|
|
|
use Symfony\Component\Console\Input\InputOption; |
12
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
13
|
|
|
use Symfony\Component\Console\Question\Question; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Command to create doctrine configuration schema. |
17
|
|
|
* |
18
|
|
|
* @author Tomasz Struczyński <[email protected]> |
19
|
|
|
*/ |
20
|
|
|
class DoctrineConfigSchemaCreateCommand extends Command |
21
|
|
|
{ |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* List of URL schemes from a database URL and their mappings to driver. |
25
|
|
|
*/ |
26
|
|
|
private static $driverSchemeAliases = array( |
27
|
|
|
'db2' => 'ibm_db2', |
28
|
|
|
'mssql' => 'pdo_sqlsrv', |
29
|
|
|
'mysql' => 'pdo_mysql', |
30
|
|
|
'mysql2' => 'pdo_mysql', // Amazon RDS, for some weird reason |
31
|
|
|
'postgres' => 'pdo_pgsql', |
32
|
|
|
'postgresql' => 'pdo_pgsql', |
33
|
|
|
'pgsql' => 'pdo_pgsql', |
34
|
|
|
'sqlite' => 'pdo_sqlite', |
35
|
|
|
'sqlite3' => 'pdo_sqlite', |
36
|
|
|
); |
37
|
|
|
|
38
|
3 |
|
protected function configure() |
39
|
|
|
{ |
40
|
3 |
|
$this->setName('cruftflake:doctrine:schema-create') |
41
|
3 |
|
->setDescription('Create Doctrine Config schema') |
42
|
3 |
|
->addOption('dsn', null, InputOption::VALUE_REQUIRED, 'Connection DSN') |
43
|
3 |
|
->addOption('table', null, InputOption::VALUE_REQUIRED, 'Doctrine table name', DoctrineConfig::DEFAULT_TABLE_NAME) |
44
|
|
|
; |
45
|
3 |
|
} |
46
|
|
|
|
47
|
3 |
|
protected function execute(InputInterface $input, OutputInterface $output) |
48
|
|
|
{ |
49
|
3 |
|
$connection = $this->getConnection($input, $output); |
50
|
3 |
|
DoctrineConfig::createTable($connection, $input->getOption('table')); |
51
|
3 |
|
$output->writeln('<info>Success</info>'); |
52
|
3 |
|
} |
53
|
|
|
|
54
|
3 |
|
private function getConnection(InputInterface $input, OutputInterface $output) |
55
|
|
|
{ |
56
|
|
|
/* @var $helper QuestionHelper */ |
57
|
3 |
|
$helper = $this->getHelper('question'); |
58
|
3 |
|
if ($input->getOption('dsn')) { |
59
|
1 |
|
return DriverManager::getConnection($this->parseDatabaseUrl(array( |
60
|
1 |
|
'url' => $input->getOption('dsn'), |
61
|
1 |
|
))); |
62
|
|
|
} |
63
|
2 |
|
$qDsn = new Question("DSN: "); |
64
|
2 |
|
while (!$dsn = $helper->ask($input, $output, $qDsn)) { |
65
|
1 |
|
$output->writeln('<error>Please, enter a valid DSN</error>'); |
66
|
1 |
|
} |
67
|
2 |
|
return DriverManager::getConnection($this->parseDatabaseUrl(array( |
68
|
|
|
'url' => $dsn |
69
|
2 |
|
))); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Extracts parts from a database URL, if present, and returns an |
74
|
|
|
* updated list of parameters. |
75
|
|
|
* |
76
|
|
|
* @codeCoverageIgnore |
77
|
|
|
* @param array $params The list of parameters. |
78
|
|
|
* |
79
|
|
|
* @return array A modified list of parameters with info from a database |
80
|
|
|
* URL extracted into indidivual parameter parts. |
81
|
|
|
* |
82
|
|
|
*/ |
83
|
|
|
private static function parseDatabaseUrl(array $params) |
84
|
|
|
{ |
85
|
|
|
if (!isset($params['url'])) { |
86
|
|
|
return $params; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
// (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid |
|
|
|
|
90
|
|
|
$url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $params['url']); |
91
|
|
|
|
92
|
|
|
$url = parse_url($url); |
93
|
|
|
|
94
|
|
|
if ($url === false) { |
95
|
|
|
throw new DBALException('Malformed parameter "url".'); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
if (isset($url['scheme'])) { |
99
|
|
|
$params['driver'] = str_replace('-', '_', $url['scheme']); // URL schemes must not contain underscores, but dashes are ok |
100
|
|
|
if (isset(self::$driverSchemeAliases[$params['driver']])) { |
101
|
|
|
$params['driver'] = self::$driverSchemeAliases[$params['driver']]; // use alias like "postgres", else we just let checkParams decide later if the driver exists (for literal "pdo-pgsql" etc) |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
if (isset($url['host'])) { |
106
|
|
|
$params['host'] = $url['host']; |
107
|
|
|
} |
108
|
|
|
if (isset($url['port'])) { |
109
|
|
|
$params['port'] = $url['port']; |
110
|
|
|
} |
111
|
|
|
if (isset($url['user'])) { |
112
|
|
|
$params['user'] = $url['user']; |
113
|
|
|
} |
114
|
|
|
if (isset($url['pass'])) { |
115
|
|
|
$params['password'] = $url['pass']; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
if (isset($url['path'])) { |
119
|
|
|
if (!isset($url['scheme']) || (strpos($url['scheme'], 'sqlite') !== false && $url['path'] == ':memory:')) { |
120
|
|
|
$params['dbname'] = $url['path']; // if the URL was just "sqlite::memory:", which parses to scheme and path only |
121
|
|
|
} else { |
122
|
|
|
$params['dbname'] = substr($url['path'], 1); // strip the leading slash from the URL |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
if (isset($url['query'])) { |
127
|
|
|
$query = array(); |
128
|
|
|
parse_str($url['query'], $query); // simply ingest query as extra params, e.g. charset or sslmode |
129
|
|
|
$params = array_merge($params, $query); // parse_str wipes existing array elements |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return $params; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
} |
136
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.