DBAL::lastInsertedID()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/** @noinspection PhpComposerExtensionStubsInspection */
4
5
declare(strict_types=1);
6
7
namespace EngineWorks\DBAL\Sqlite;
8
9
use EngineWorks\DBAL\Abstracts\BaseDBAL;
10
use EngineWorks\DBAL\CommonTypes;
11
use EngineWorks\DBAL\Traits\MethodSqlLike;
12
use EngineWorks\DBAL\Traits\MethodSqlLimit;
13
use Exception;
14
use InvalidArgumentException;
15
use RuntimeException;
16
use SQLite3;
17
use SQLite3Result;
18
use Throwable;
19
20
class DBAL extends BaseDBAL
21
{
22
    use MethodSqlLike;
23
    use MethodSqlLimit;
24
25
    /**
26
     * Contains the connection resource for SQLite3
27
     * @var SQLite3|null
28
     */
29
    protected $sqlite = null;
30
31 76
    public function connect(): bool
32
    {
33
        // disconnect, this will reset object properties
34 76
        $this->disconnect();
35
        // create the sqlite3 object without error reporting
36 76
        $level = error_reporting(0);
37
        try {
38 76
            $defaultFlags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE;
39 76
            $this->sqlite = new SQLite3(
40 76
                (string) $this->settings->get('filename', ':memory:'),
41 76
                ($this->settings->exists('flags')) ? (int) $this->settings->get('flags') : $defaultFlags
42 76
            );
43 1
        } catch (Throwable $ex) {
44 1
            $this->logger->info('-- Connection fail');
45 1
            $this->logger->error('Cannot create SQLite3 object: ' . $ex->getMessage());
46 1
            return false;
47
        } finally {
48 76
            error_reporting($level);
49
        }
50
        // OK, we are connected
51 75
        $this->logger->info('-- Connection success');
52 75
        $enableExceptions = (bool) $this->settings->get('enable-exceptions', false);
53 75
        if ($enableExceptions) {
54
            $this->sqlite()->enableExceptions(true);
55
        }
56 75
        return true;
57
    }
58
59 79
    public function disconnect(): void
60
    {
61 79
        if ($this->isConnected()) {
62 75
            $this->logger->info('-- Disconnection');
63 75
            $this->sqlite()->close();
64
        }
65 79
        $this->transactionLevel = 0;
66 79
        $this->sqlite = null;
67
    }
68
69 99
    public function isConnected(): bool
70
    {
71 99
        return ($this->sqlite instanceof SQLite3);
72
    }
73
74
    public function lastInsertedID(): int
75
    {
76
        return $this->sqlite()->lastInsertRowID();
77
    }
78
79 80
    public function sqlString($variable): string
80
    {
81 80
        return str_replace(["\0", "'"], ['', "''"], (string) $variable);
82
    }
83
84
    /** @return Result|false */
85 61
    public function queryResult(string $query, array $overrideTypes = [])
86
    {
87
        /**
88
         * @scrutinizer ignore-unhandled
89
         * @noinspection PhpUsageOfSilenceOperatorInspection
90
         */
91 61
        $rslt = @$this->sqlite()->query($query);
92 61
        if ($rslt instanceof SQLite3Result) {
0 ignored issues
show
introduced by
$rslt is always a sub-type of SQLite3Result.
Loading history...
93 51
            return new Result($rslt, $overrideTypes);
94
        }
95 10
        return false;
96
    }
97
98 75
    protected function queryAffectedRows(string $query)
99
    {
100 75
        $this->logger->debug($query);
101
        try {
102 75
            $exec = $this->sqlite()->exec($query);
103 1
        } catch (Exception $ex) {
104 1
            $exec = false;
105 1
            $this->logger->info("-- Query fail with SQL: $query");
106 1
            $this->logger->error("FAIL: $query\nLast message:" . $ex->getMessage());
107
        }
108 75
        if (false !== $exec) {
109 75
            return max(0, $this->sqlite()->changes());
110
        }
111 1
        return false;
112
    }
113
114 1
    protected function getLastErrorMessage(): string
115
    {
116 1
        return '[' . $this->sqlite()->lastErrorCode() . '] ' . $this->sqlite()->lastErrorMsg();
117
    }
118
119 5
    public function sqlTableEscape(string $tableName, string $asTable = ''): string
120
    {
121 5
        return '"' . $tableName . '"' . (('' !== $asTable) ? ' AS ' . '"' . $asTable . '"' : '');
122
    }
123
124 4
    public function sqlFieldEscape(string $fieldName, string $asTable = ''): string
125
    {
126 4
        return '"' . $fieldName . '"' . (('' !== $asTable) ? ' AS ' . '"' . $asTable . '"' : '');
127
    }
128
129 1
    public function sqlConcatenate(...$strings): string
130
    {
131 1
        if ([] === $strings) {
132 1
            return $this->sqlQuote('', CommonTypes::TTEXT);
133
        }
134 1
        return implode(' || ', $strings);
135
    }
136
137 10
    public function sqlDatePart(string $part, string $expression): string
138
    {
139 10
        $format = $this->sqlDatePartFormat($part);
140 10
        return sprintf('STRFTIME(%s, %s)', $this->sqlQuote($format, self::TTEXT), $expression);
141
    }
142
143 10
    private function sqlDatePartFormat(string $part): string
144
    {
145 10
        switch (strtoupper($part)) {
146 10
            case 'YEAR':
147 1
                return '%Y';
148 9
            case 'MONTH':
149 1
                return '%m';
150 8
            case 'FDOM':
151 1
                return '%Y-%m-01';
152 7
            case 'FYM':
153 1
                return '%Y-%m';
154 6
            case 'FYMD':
155 1
                return '%Y-%m-%d';
156 5
            case 'DAY':
157 1
                return '%d';
158 4
            case 'HOUR':
159 1
                return '%H';
160 3
            case 'MINUTE':
161 1
                return '%M';
162 2
            case 'SECOND':
163 1
                return '%S';
164 1
            case 'FHMS':
165 1
                return '%H:%M:%S';
166
            default:
167
                throw new InvalidArgumentException("Date part $part is not valid");
168
        }
169
    }
170
171 1
    public function sqlIf(string $condition, string $truePart, string $falsePart): string
172
    {
173 1
        return 'CASE WHEN (' . $condition . ') THEN ' . $truePart . ' ELSE ' . $falsePart;
174
    }
175
176 4
    public function sqlLimit(string $query, int $requestedPage, int $recordsPerPage = 20): string
177
    {
178 4
        return $this->sqlLimitOffset($query, $requestedPage, $recordsPerPage);
179
    }
180
181 1
    public function sqlRandomFunc(): string
182
    {
183 1
        return 'random()';
184
    }
185
186 75
    private function sqlite(): SQLite3
187
    {
188 75
        if (null === $this->sqlite) {
189
            throw new RuntimeException('The current state of the connection is NULL');
190
        }
191 75
        return $this->sqlite;
192
    }
193
}
194