Completed
Branch feature/pre-split (f8e7b8)
by Anton
04:02
created

Driver::tableSchema()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 12
rs 9.4285
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\Entities;
10
11
use Spiral\Cache\StoreInterface;
12
use Spiral\Core\FactoryInterface;
13
use Spiral\Database\Builders\DeleteQuery;
14
use Spiral\Database\Builders\InsertQuery;
15
use Spiral\Database\Builders\SelectQuery;
16
use Spiral\Database\Builders\UpdateQuery;
17
use Spiral\Database\Entities\Prototypes\PDODriver;
18
use Spiral\Database\Entities\Query\CachedResult;
19
use Spiral\Database\Exceptions\DriverException;
20
use Spiral\Database\Exceptions\QueryException;
21
use Spiral\Database\Schemas\Prototypes\AbstractTable;
22
23
/**
24
 * Driver abstraction is responsible for DBMS specific set of functions and used by Databases to
25
 * hide implementation specific functionality. Extends PDODriver and adds ability to create driver
26
 * specific query builders and schemas (basically operates like a factory).
27
 */
28
abstract class Driver extends PDODriver
29
{
30
    /**
31
     * Schema table class.
32
     */
33
    const TABLE_SCHEMA_CLASS = '';
34
35
    /**
36
     * Commander used to execute commands. :).
37
     */
38
    const COMMANDER = '';
39
40
    /**
41
     * Query compiler class.
42
     */
43
    const QUERY_COMPILER = '';
44
45
    /**
46
     * Default datetime value.
47
     */
48
    const DEFAULT_DATETIME = '1970-01-01 00:00:00';
49
50
    /**
51
     * Default timestamp expression.
52
     */
53
    const TIMESTAMP_NOW = 'DRIVER_SPECIFIC_NOW_EXPRESSION';
54
55
    /**
56
     * Associated cache store, if any.
57
     *
58
     * @var StoreInterface
59
     */
60
    protected $cacheStore = null;
61
62
    /**
63
     * @var FactoryInterface
64
     */
65
    protected $factory = null;
66
67
    /**
68
     * @param string           $name
69
     * @param array            $options
70
     * @param FactoryInterface $factory Required to build instances of query builders and compilers.
71
     * @param StoreInterface   $store   Cache store associated with driver (optional).
72
     */
73
    public function __construct(
74
        string $name,
75
        array $options,
76
        FactoryInterface $factory,
77
        StoreInterface $store = null
78
    ) {
79
        parent::__construct($name, $options);
80
81
        $this->factory = $factory;
82
        $this->cacheStore = $store;
83
    }
84
85
    /**
86
     * Set cache store to be used by driver.
87
     *
88
     * @param StoreInterface $store
89
     *
90
     * @return self|$this
91
     */
92
    public function setStore(StoreInterface $store): Driver
93
    {
94
        $this->cacheStore = $store;
95
96
        return $this;
97
    }
98
99
    /**
100
     * Execute statement or fetch result from cache and return cached query iterator.
101
     *
102
     * @param string         $query
103
     * @param array          $parameters Parameters to be binded into query.
104
     * @param int            $lifetime   Cache lifetime in seconds.
105
     * @param string         $key        Cache key to be used to store query result.
106
     * @param StoreInterface $store      Cache store to store result in, if null default store will
107
     *                                   be used.
108
     *
109
     * @return CachedResult
110
     *
111
     * @throws DriverException
112
     * @throws QueryException
113
     */
114
    public function cachedQuery(
115
        string $query,
116
        array $parameters = [],
117
        int $lifetime,
118
        string $key = '',
119
        StoreInterface $store = null
120
    ) {
121
        if (empty($store)) {
122
            if (empty($this->cacheStore)) {
123
                throw new DriverException("StoreInterface is missing");
0 ignored issues
show
Unused Code introduced by
The call to DriverException::__construct() has too many arguments starting with 'StoreInterface is missing'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
124
            }
125
126
            $store = $this->cacheStore;
127
        }
128
129
        if (empty($key)) {
130
            //Trying to build unique query id based on provided options and environment.
131
            $key = md5(serialize([$query, $parameters, $this->getName()]));
132
        }
133
134
        $data = $store->remember($key, $lifetime, function () use ($query, $parameters) {
135
            return $this->query($query, $parameters)->fetchAll();
136
        });
137
138
        return new CachedResult($data, $parameters, $query, $key, $store);
139
    }
140
141
    /**
142
     * Current timestamp expression value.
143
     *
144
     * @return string
145
     */
146
    public function nowExpression(): string
147
    {
148
        return static::TIMESTAMP_NOW;
149
    }
150
151
    /**
152
     * Check if table exists.
153
     *
154
     * @param string $name
155
     *
156
     * @return bool
157
     */
158
    abstract public function hasTable(string $name): bool;
159
160
    /**
161
     * Clean (truncate) specified driver table.
162
     *
163
     * @param string $table Table name with prefix included.
164
     */
165
    abstract public function truncateData(string $table);
166
167
    /**
168
     * Get every available table name as array.
169
     *
170
     * @return array
171
     */
172
    abstract public function tableNames(): array;
173
174
    /**
175
     * Get Driver specific AbstractTable implementation.
176
     *
177
     * @param string $table  Table name without prefix included.
178
     * @param string $prefix Database specific table prefix, this parameter is not required,
179
     *                       but if provided all
180
     *                       foreign keys will be created using it.
181
     *
182
     * @return AbstractTable
183
     */
184
    public function tableSchema(string $table, string $prefix = ''): AbstractTable
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $prefix is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
185
    {
186
//        return $this->factory->make(
1 ignored issue
show
Unused Code Comprehensibility introduced by
54% 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...
187
//            static::SCHEMA_TABLE,
188
//            [
189
//                'driver'    => $this,
190
//                'name'      => $table,
191
//                'prefix'    => $prefix,
192
//                'commander' => $this->factory->make(static::COMMANDER, ['driver' => $this]),
193
//            ]
194
//        );
195
    }
196
197
    /**
198
     * Get instance of Driver specific QueryCompiler.
199
     *
200
     * @param string $prefix Database specific table prefix, used to quote table names and build
201
     *                       aliases.
202
     *
203
     * @return QueryCompiler
204
     */
205
    public function queryCompiler(string $prefix = ''): QueryCompiler
206
    {
207
        return $this->factory->make(
208
            static::QUERY_COMPILER,
209
            ['driver' => $this, 'quoter' => new Quoter($this, $prefix)]
210
        );
211
    }
212
213
    /**
214
     * Get InsertQuery builder with driver specific query compiler.
215
     *
216
     * @param string $prefix     Database specific table prefix, used to quote table names and build
217
     *                           aliases.
218
     * @param array  $parameters Initial builder parameters.
219
     *
220
     * @return InsertQuery
221
     */
222 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...
223
    {
224
        return $this->factory->make(
225
            InsertQuery::class,
226
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
227
        );
228
    }
229
230
    /**
231
     * Get SelectQuery builder with driver specific query compiler.
232
     *
233
     * @param string $prefix     Database specific table prefix, used to quote table names and build
234
     *                           aliases.
235
     * @param array  $parameters Initial builder parameters.
236
     *
237
     * @return SelectQuery
238
     */
239 View Code Duplication
    public function selectBuilder(string $prefix, array $parameters = []): SelectQuery
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...
240
    {
241
        return $this->factory->make(
242
            SelectQuery::class,
243
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
244
        );
245
    }
246
247
    /**
248
     * Get DeleteQuery builder with driver specific query compiler.
249
     *
250
     * @param string $prefix     Database specific table prefix, used to quote table names and build
251
     *                           aliases.
252
     * @param array  $parameters Initial builder parameters.
253
     *
254
     * @return DeleteQuery
255
     */
256 View Code Duplication
    public function deleteBuilder(string $prefix, array $parameters = []): DeleteQuery
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...
257
    {
258
259
        return $this->factory->make(
260
            DeleteQuery::class,
261
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
262
        );
263
    }
264
265
    /**
266
     * Get UpdateQuery builder with driver specific query compiler.
267
     *
268
     * @param string $prefix     Database specific table prefix, used to quote table names and build
269
     *                           aliases.
270
     * @param array  $parameters Initial builder parameters.
271
     *
272
     * @return UpdateQuery
273
     */
274 View Code Duplication
    public function updateBuilder(string $prefix, array $parameters = []): UpdateQuery
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...
275
    {
276
        return $this->factory->make(
277
            UpdateQuery::class,
278
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
279
        );
280
    }
281
}
282