CommonSqlQueries::isCachedSql()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * Contains CommonSqlQueries class.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2014-2017 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @copyright 2014-2017 Michael Cummings
32
 * @license   LGPL-3.0+
33
 * @author    Michael Cummings <[email protected]>
34
 */
35
namespace Yapeal\Sql;
36
37
use Yapeal\FileSystem\SafeFileHandlingTrait;
38
39
/**
40
 * Class CommonSqlQueries
41
 *
42
 * @method string getAccountCorporationIDsExcludingCorporationKeys()
43
 * @method string getActiveApis()
44
 * @method string getActiveMailBodiesWithOwnerID(int $ownerID)
45
 * @method string getActiveRegisteredAccountStatus(int $mask)
46
 * @method string getActiveRegisteredCharacters(int $mask)
47
 * @method string getActiveRegisteredCorporations(int $mask)
48
 * @method string getActiveRegisteredKeys()
49
 * @method string getActiveStarbaseTowers(int $mask, int $ownerID)
50
 * @method string getApiLock(int $hash)
51
 * @method string getApiLockRelease(int $hash)
52
 * @method string getCachedUntilExpires(int $accountKey, string $apiName, int $ownerID)
53
 * @method string getDeleteFromStarbaseDetailTables(string $tableName, int $ownerID, int $starbaseID)
54
 * @method string getDeleteFromTable(string $tableName)
55
 * @method string getDeleteFromTableWithKeyID(string $tableName, int $keyID)
56
 * @method string getDeleteFromTableWithOwnerID(string $tableName, int $ownerID)
57
 * @method string getDropSchema()
58
 * @method string getInitialization()
59
 * @method string getInsert(string $tableName, array $columnNameList, int $rowCount)
60
 * @method string getLatestYapealSchemaVersion()
61
 * @method string getMemberCorporationIDsExcludingAccountCorporations()
62
 * @method string getSchemaNames()
63
 * @method string getSelect(string $tableName, array $columnNameList, array $where)
64
 * @method string getUpsert(string $tableName, array $columnNameList, int $rowCount)
65
 */
66
class CommonSqlQueries implements SqlQueriesInterface
67
{
68
    use SafeFileHandlingTrait;
69
    use SqlCleanupTrait;
70
    /**
71
     * @param array $sqlSubs
72
     *
73
     */
74
    public function __construct(array $sqlSubs)
75
    {
76
        $this->sqlSubs = $sqlSubs;
77
        $this->platform = $sqlSubs['{platform}'];
78
        $this->queriesDir = $sqlSubs['{dir}'] . 'Queries/';
79
    }
80
    /**
81
     * @param string $name
82
     * @param array  $arguments
83
     *
84
     * @return mixed
85
     * @throws \BadMethodCallException
86
     * @throws \DomainException
87
     * @throws \InvalidArgumentException
88
     * @throws \LogicException
89
     */
90
    public function __call(string $name, array $arguments = [])
91
    {
92
        $methodName = $name . ucfirst($this->platform);
93
        if (method_exists($this, $methodName)) {
94
            if (false !== $sql = call_user_func_array([$this, $methodName], $arguments)) {
95
                return $this->processSql($methodName, $sql, $arguments);
96
            }
97
        }
98
        if (false !== $result = $this->tryGet($name, $arguments)) {
99
            return $result;
100
        }
101
        $mess = 'Unknown method ' . $name;
102
        throw new \BadMethodCallException($mess);
103
    }
104
    /**
105
     * @param string $tableName
106
     * @param array  $columnNameList
107
     * @param int    $rowCount
108
     *
109
     * @return string
110
     * @throws \LogicException
111
     */
112
    protected function getInsertMysql(string $tableName, array $columnNameList, int $rowCount): string
113
    {
114
        $replacements = $this->getSqlSubs();
115
        $replacements['{tableName}'] = $tableName;
116
        $replacements['{columnNames}'] = implode('","', $columnNameList);
117
        $rowPrototype = '(' . implode(',', array_fill(0, count($columnNameList), '?')) . ')';
118
        $replacements['{rowset}'] = implode(',', array_fill(0, $rowCount, $rowPrototype));
119
        $sql = /** @lang text */
120
            'INSERT INTO "{schema}"."{tablePrefix}{tableName}" ("{columnNames}") VALUES {rowset}';
121
        return (string)str_replace(array_keys($replacements), array_values($replacements), $sql);
122
    }
123
    /**
124
     * @param string $tableName
125
     * @param array  $columnNameList
126
     * @param array  $where
127
     *
128
     * @return string
129
     * @throws \LogicException
130
     */
131
    protected function getSelectMysql(string $tableName, array $columnNameList, array $where): string
132
    {
133
        $replacements = $this->getSqlSubs();
134
        $replacements['{tableName}'] = $tableName;
135
        $replacements['{columnNames}'] = '"' . implode('","', $columnNameList) . '"';
136
        if (1 === count($columnNameList) && false !== strpos($columnNameList[0], '*')) {
137
            $replacements['{columnNames}'] = $columnNameList[0];
138
        }
139
        $wheres = [];
140
        foreach ($where as $key => $value) {
141
            $wheres[] = sprintf('"%s"=\'%s\'', $key, $value);
142
        }
143
        $replacements['{where}'] = implode(' AND ', $wheres);
144
        $sql = /** @lang text */
145
            'SELECT {columnNames} FROM "{schema}"."{tablePrefix}{tableName}" WHERE {where}';
146
        return (string)str_replace(array_keys($replacements), array_values($replacements), $sql);
147
    }
148
    /**
149
     * Returns a MySql version of an upsert query.
150
     *
151
     * @param string   $tableName
152
     * @param string[] $columnNameList
153
     * @param int      $rowCount
154
     *
155
     * @return string
156
     * @throws \LogicException
157
     */
158
    protected function getUpsertMysql(string $tableName, array $columnNameList, int $rowCount): string
159
    {
160
        $replacements = $this->getSqlSubs();
161
        $sql = $this->getInsertMysql($tableName, $columnNameList, $rowCount);
162
        $sql .= ' ON DUPLICATE KEY UPDATE {updates}';
163
        $updates = [];
164
        foreach ($columnNameList as $column) {
165
            $updates[] = sprintf('"%1$s"=VALUES("%1$s")', $column);
166
        }
167
        $replacements['{updates}'] = implode(',', $updates);
168
        return (string)str_replace(array_keys($replacements), array_values($replacements), $sql);
169
    }
170
    /**
171
     * @param string $fileName
172
     * @param string $sql
173
     */
174
    private function cacheSqlQuery(string $fileName, string $sql)
175
    {
176
        $this->sqlCache[$fileName] = $sql;
177
    }
178
    /**
179
     * @param string $fileName
180
     *
181
     * @return string
182
     */
183
    private function getCachedSql(string $fileName): string
184
    {
185
        return $this->sqlCache[$fileName];
186
    }
187
    /**
188
     * @return array
189
     * @throws \LogicException
190
     */
191
    private function getSqlSubs(): array
192
    {
193
        return $this->sqlSubs;
194
    }
195
    /**
196
     * @param string $fileName
197
     *
198
     * @return bool
199
     */
200
    private function isCachedSql(string $fileName): bool
201
    {
202
        return array_key_exists($fileName, $this->sqlCache);
203
    }
204
    /**
205
     * @param string $fileName
206
     *
207
     * @param string $sql
208
     * @param array  $arguments
209
     *
210
     * @return string
211
     * @throws \LogicException
212
     */
213
    private function processSql(string $fileName, string $sql, array $arguments): string
214
    {
215
        $sql = $this->getCleanedUpSql($sql, $this->getSqlSubs());
216
        if (0 !== count($arguments)) {
217
            $sql = vsprintf($sql, $arguments);
218
        } else {
219
            $this->cacheSqlQuery($fileName, $sql);
220
        }
221
        return $sql;
222
    }
223
    /**
224
     * @param string $name
225
     * @param array  $arguments
226
     *
227
     * @return string|false
228
     * @throws \LogicException
229
     */
230
    private function tryGet(string $name, array $arguments = [])
231
    {
232
        if (0 === strpos($name, 'get')) {
233
            $fileNames = explode(',',
234
                sprintf('%1$s%2$s.%3$s.sql,%1$s%2$s.sql', $this->queriesDir, $name, $this->platform));
235
            foreach ($fileNames as $fileName) {
236
                if ($this->isCachedSql($fileName)) {
237
                    return $this->getCachedSql($fileName);
238
                }
239
                if (false === $sql = $this->safeFileRead($fileName)) {
240
                    continue;
241
                }
242
                return $this->processSql($fileName, $sql, $arguments);
243
            }
244
        }
245
        return false;
246
    }
247
    /**
248
     * @var string $platform
249
     */
250
    private $platform;
251
    /**
252
     * @var string $queriesDir
253
     */
254
    private $queriesDir;
255
    /**
256
     * @var array sqlCache
257
     */
258
    private $sqlCache = [];
259
    /**
260
     * @var array $sqlSubs
261
     */
262
    private $sqlSubs;
263
}
264