Completed
Branch feature/pre-split (d89158)
by Anton
04:43
created

PostgresDriver::getHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Database\Drivers\Postgres;
10
11
use Psr\Log\LoggerInterface;
12
use Spiral\Database\Builders\InsertQuery;
13
use Spiral\Database\DatabaseInterface;
14
use Spiral\Database\Entities\AbstractHandler;
15
use Spiral\Database\Entities\Driver;
16
use Spiral\Database\Exceptions\DriverException;
17
18
/**
19
 * Talks to postgres databases.
20
 */
21
class PostgresDriver extends Driver
22
{
23
    /**
24
     * Driver type.
25
     */
26
    const TYPE = DatabaseInterface::POSTGRES;
27
28
    /**
29
     * Driver schemas.
30
     */
31
    //const SCHEMA_TABLE = TableSchema::class;
32
33
    /**
34
     * Query compiler class.
35
     */
36
    const QUERY_COMPILER = PostgresCompiler::class;
37
38
    /**
39
     * Default timestamp expression.
40
     */
41
    const DATETIME_NOW = 'now()';
42
43
    /**
44
     * Cached list of primary keys associated with their table names. Used by InsertBuilder to
45
     * emulate last insert id.
46
     *
47
     * @var array
48
     */
49
    private $primaryKeys = [];
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function hasTable(string $name): bool
55
    {
56
        $query = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \'public\' AND "table_type" = \'BASE TABLE\' AND "table_name" = ?';
57
58
        return (bool)$this->query($query, [$name])->fetchColumn();
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function truncateData(string $table)
65
    {
66
        $this->statement("TRUNCATE TABLE {$this->identifier($table)}");
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function tableNames(): array
73
    {
74
        $query = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \'public\' AND "table_type" = \'BASE TABLE\'';
75
76
        $tables = [];
77
        foreach ($this->query($query) as $row) {
78
            $tables[] = $row['table_name'];
79
        }
80
81
        return $tables;
82
    }
83
84
    /**
85
     * Get singular primary key associated with desired table. Used to emulate last insert id.
86
     *
87
     * @param string $prefix Database prefix if any.
88
     * @param string $table  Fully specified table name, including postfix.
89
     *
90
     * @return string|null
91
     *
92
     * @throws DriverException
93
     */
94
    public function getPrimary(string $prefix, string $table): string
95
    {
96
        if (!empty($this->cacheStore) && empty($this->primaryKeys)) {
97
            $this->primaryKeys = (array)$this->cacheStore->get($this->getSource() . '/keys');
98
        }
99
100
        if (!empty($this->primaryKeys) && array_key_exists($table, $this->primaryKeys)) {
101
            return $this->primaryKeys[$table];
102
        }
103
104
        if (!$this->hasTable($prefix . $table)) {
105
            throw new DriverException(
106
                "Unable to fetch table primary key, no such table '{$prefix}{$table}' exists"
107
            );
108
        }
109
110
        $this->primaryKeys[$table] = $this->tableSchema($table, $prefix)->getPrimaryKeys();
111
        if (count($this->primaryKeys[$table]) === 1) {
112
            //We do support only single primary key
113
            $this->primaryKeys[$table] = $this->primaryKeys[$table][0];
114
        } else {
115
            $this->primaryKeys[$table] = null;
116
        }
117
118
        //Caching
119
        if (!empty($this->cacheStore)) {
120
            $this->cacheStore->forever($this->getSource() . '/keys', $this->primaryKeys);
121
        }
122
123
        return $this->primaryKeys[$table];
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     *
129
     * Postgres uses custom insert query builder in order to return value of inserted row.
130
     */
131 View Code Duplication
    public function insertBuilder(string $prefix, array $parameters = []): InsertQuery
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
    {
133
        return $this->factory->make(
134
            PostgresQuery::class,
135
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix),] + $parameters
136
        );
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    protected function createPDO(): \PDO
143
    {
144
        //Spiral is purely UTF-8
145
        $pdo = parent::createPDO();
146
        $pdo->exec("SET NAMES 'UTF-8'");
147
148
        return $pdo;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function getHandler(LoggerInterface $logger = null): AbstractHandler
155
    {
156
        //implement
157
    }
158
}
159