Completed
Branch feature/pre-split (76ded7)
by Anton
03:22
created

Driver::nowExpression()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
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\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
     * Associated cache store, if any.
47
     *
48
     * @var StoreInterface
49
     */
50
    protected $cacheStore = null;
51
52
    /**
53
     * @var FactoryInterface
54
     */
55
    protected $factory = null;
56
57
    /**
58
     * @param string           $name
59
     * @param array            $options
60
     * @param FactoryInterface $factory Required to build instances of query builders and compilers.
61
     * @param StoreInterface   $store   Cache store associated with driver (optional).
62
     */
63
    public function __construct(
64
        string $name,
65
        array $options,
66
        FactoryInterface $factory,
67
        StoreInterface $store = null
68
    ) {
69
        parent::__construct($name, $options);
70
71
        $this->factory = $factory;
72
        $this->cacheStore = $store;
73
    }
74
75
    /**
76
     * Set cache store to be used by driver.
77
     *
78
     * @param StoreInterface $store
79
     *
80
     * @return self|$this
81
     */
82
    public function setStore(StoreInterface $store): Driver
83
    {
84
        $this->cacheStore = $store;
85
86
        return $this;
87
    }
88
89
    /**
90
     * Execute statement or fetch result from cache and return cached query iterator.
91
     *
92
     * @param string         $query
93
     * @param array          $parameters Parameters to be binded into query.
94
     * @param int            $lifetime   Cache lifetime in seconds.
95
     * @param string         $key        Cache key to be used to store query result.
96
     * @param StoreInterface $store      Cache store to store result in, if null default store will
97
     *                                   be used.
98
     *
99
     * @return CachedResult
100
     *
101
     * @throws DriverException
102
     * @throws QueryException
103
     */
104
    public function cachedQuery(
105
        string $query,
106
        array $parameters = [],
107
        int $lifetime,
108
        string $key = '',
109
        StoreInterface $store = null
110
    ) {
111
        if (empty($store)) {
112
            if (empty($this->cacheStore)) {
113
                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...
114
            }
115
116
            $store = $this->cacheStore;
117
        }
118
119
        if (empty($key)) {
120
            //Trying to build unique query id based on provided options and environment.
121
            $key = md5(serialize([$query, $parameters, $this->getName()]));
122
        }
123
124
        $data = $store->remember($key, $lifetime, function () use ($query, $parameters) {
125
            return $this->query($query, $parameters)->fetchAll();
126
        });
127
128
        return new CachedResult($data, $parameters, $query, $key, $store);
129
    }
130
131
    /**
132
     * Check if table exists.
133
     *
134
     * @param string $name
135
     *
136
     * @return bool
137
     */
138
    abstract public function hasTable(string $name): bool;
139
140
    /**
141
     * Clean (truncate) specified driver table.
142
     *
143
     * @param string $table Table name with prefix included.
144
     */
145
    abstract public function truncateData(string $table);
146
147
    /**
148
     * Get every available table name as array.
149
     *
150
     * @return array
151
     */
152
    abstract public function tableNames(): array;
153
154
    /**
155
     * Get Driver specific AbstractTable implementation.
156
     *
157
     * @param string $table  Table name without prefix included.
158
     * @param string $prefix Database specific table prefix, this parameter is not required,
159
     *                       but if provided all
160
     *                       foreign keys will be created using it.
161
     *
162
     * @return AbstractTable
163
     */
164
    public function tableSchema(string $table, string $prefix = ''): AbstractTable
165
    {
166
        return $this->factory->make(
167
            static::TABLE_SCHEMA_CLASS,
168
            ['driver' => $this, 'name' => $table, 'prefix' => $prefix]
169
        );
170
    }
171
172
    /**
173
     * Get instance of Driver specific QueryCompiler.
174
     *
175
     * @param string $prefix Database specific table prefix, used to quote table names and build
176
     *                       aliases.
177
     *
178
     * @return QueryCompiler
179
     */
180
    public function queryCompiler(string $prefix = ''): QueryCompiler
181
    {
182
        return $this->factory->make(
183
            static::QUERY_COMPILER,
184
            ['driver' => $this, 'quoter' => new Quoter($this, $prefix)]
185
        );
186
    }
187
188
    /**
189
     * Get InsertQuery builder with driver specific query compiler.
190
     *
191
     * @param string $prefix     Database specific table prefix, used to quote table names and build
192
     *                           aliases.
193
     * @param array  $parameters Initial builder parameters.
194
     *
195
     * @return InsertQuery
196
     */
197 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...
198
    {
199
        return $this->factory->make(
200
            InsertQuery::class,
201
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
202
        );
203
    }
204
205
    /**
206
     * Get SelectQuery builder with driver specific query compiler.
207
     *
208
     * @param string $prefix     Database specific table prefix, used to quote table names and build
209
     *                           aliases.
210
     * @param array  $parameters Initial builder parameters.
211
     *
212
     * @return SelectQuery
213
     */
214 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...
215
    {
216
        return $this->factory->make(
217
            SelectQuery::class,
218
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
219
        );
220
    }
221
222
    /**
223
     * Get DeleteQuery builder with driver specific query compiler.
224
     *
225
     * @param string $prefix     Database specific table prefix, used to quote table names and build
226
     *                           aliases.
227
     * @param array  $parameters Initial builder parameters.
228
     *
229
     * @return DeleteQuery
230
     */
231 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...
232
    {
233
234
        return $this->factory->make(
235
            DeleteQuery::class,
236
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
237
        );
238
    }
239
240
    /**
241
     * Get UpdateQuery builder with driver specific query compiler.
242
     *
243
     * @param string $prefix     Database specific table prefix, used to quote table names and build
244
     *                           aliases.
245
     * @param array  $parameters Initial builder parameters.
246
     *
247
     * @return UpdateQuery
248
     */
249 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...
250
    {
251
        return $this->factory->make(
252
            UpdateQuery::class,
253
            ['driver' => $this, 'compiler' => $this->queryCompiler($prefix)] + $parameters
254
        );
255
    }
256
}
257