DoctrineConfigSchemaCreateCommand   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 19
c 1
b 0
f 1
lcom 1
cbo 6
dl 0
loc 116
ccs 23
cts 23
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 8 1
A execute() 0 6 1
A getConnection() 0 17 3
D parseDatabaseUrl() 0 51 14
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
1 ignored issue
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
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