xref: /plugin/combo/ComboStrap/SqliteRequest.php (revision d899a2a62926ce6e7f78d85d882eb464caef0a95)
1c3437056SNickeau<?php
2c3437056SNickeau
3c3437056SNickeau
4c3437056SNickeaunamespace ComboStrap;
5c3437056SNickeau
6c3437056SNickeau
7c3437056SNickeauclass SqliteRequest
8c3437056SNickeau{
9*d899a2a6Sgerardnico    const UPSERT_REQUEST = "Upsert";
10*d899a2a6Sgerardnico    const SELECT_REQUEST = "Select";
11*d899a2a6Sgerardnico
12*d899a2a6Sgerardnico    /**
13*d899a2a6Sgerardnico     * delete, insert, update, query with parameters
14*d899a2a6Sgerardnico     */
15*d899a2a6Sgerardnico    const PARAMETRIZED_REQUEST = "Parametrized";
16*d899a2a6Sgerardnico    const STATEMENT_REQUEST = "Statement";
17c3437056SNickeau    /**
18c3437056SNickeau     * @var Sqlite
19c3437056SNickeau     */
20c3437056SNickeau    private $sqlite;
21c3437056SNickeau    /**
22c3437056SNickeau     * @var string
23c3437056SNickeau     */
24c3437056SNickeau    private $tableName;
25c3437056SNickeau    /**
26c3437056SNickeau     * @var array
27c3437056SNickeau     */
28c3437056SNickeau    private $data;
29c3437056SNickeau    /**
30c3437056SNickeau     * @var SqliteResult
31c3437056SNickeau     */
32c3437056SNickeau    private $result;
33c3437056SNickeau    /**
34c3437056SNickeau     * @var string
35c3437056SNickeau     */
36c3437056SNickeau    private $query;
37c3437056SNickeau
38*d899a2a6Sgerardnico    private \helper_plugin_sqlite $sqlitePlugin;
39*d899a2a6Sgerardnico
40c3437056SNickeau    /**
41c3437056SNickeau     * A statement that is not a query
42*d899a2a6Sgerardnico     * @var ?string
43c3437056SNickeau     */
44*d899a2a6Sgerardnico    private ?string $statement = null;
45*d899a2a6Sgerardnico    /**
46*d899a2a6Sgerardnico     * The SQL parameters
47*d899a2a6Sgerardnico     * @var array |null
48*d899a2a6Sgerardnico     */
49*d899a2a6Sgerardnico    private ?array $parameters = null;
50c3437056SNickeau
51c3437056SNickeau    /**
52c3437056SNickeau     * SqliteRequest constructor.
53c3437056SNickeau     * @param Sqlite $sqlite
54c3437056SNickeau     */
55c3437056SNickeau    public function __construct(Sqlite $sqlite)
56c3437056SNickeau    {
57c3437056SNickeau        $this->sqlite = $sqlite;
58c3437056SNickeau        $this->sqlitePlugin = $sqlite->getSqlitePlugin();
59c3437056SNickeau    }
60c3437056SNickeau
61c3437056SNickeau    public function setTableRow(string $tableName, array $data): SqliteRequest
62c3437056SNickeau    {
63c3437056SNickeau        $this->tableName = $tableName;
64c3437056SNickeau        $this->data = $data;
65c3437056SNickeau        return $this;
66c3437056SNickeau    }
67c3437056SNickeau
68c3437056SNickeau    /**
6904fd306cSNickeau     * @throws ExceptionCompile
70c3437056SNickeau     */
71c3437056SNickeau    public function execute(): SqliteResult
72c3437056SNickeau    {
73*d899a2a6Sgerardnico        $sqLiteAdapater = $this->sqlitePlugin->getAdapter();
74*d899a2a6Sgerardnico        $requestType = $this->getRequestType();
75*d899a2a6Sgerardnico        switch ($requestType) {
76*d899a2a6Sgerardnico            case self::UPSERT_REQUEST:
77*d899a2a6Sgerardnico                $statement = $this->getParametrizeReplaceQuery($this->tableName, $this->data);
78*d899a2a6Sgerardnico                $values = array_values($this->data);
79*d899a2a6Sgerardnico                $res = $this->executeParametrizedStatement($statement, $values);
80*d899a2a6Sgerardnico                $queryExecuted = "Upsert of table $this->tableName";
81*d899a2a6Sgerardnico                break;
82*d899a2a6Sgerardnico            case self::SELECT_REQUEST:
83c3437056SNickeau                $res = $this->sqlitePlugin->query($this->query);
8404fd306cSNickeau                $queryExecuted = $this->query;
85*d899a2a6Sgerardnico                break;
86*d899a2a6Sgerardnico            case self::PARAMETRIZED_REQUEST:
87*d899a2a6Sgerardnico                $res = $this->executeParametrizedStatement($this->statement, $this->parameters);
88*d899a2a6Sgerardnico                $queryExecuted = array_merge([$this->statement], $this->parameters);
89*d899a2a6Sgerardnico                break;
90*d899a2a6Sgerardnico            case self::STATEMENT_REQUEST:
91*d899a2a6Sgerardnico                if (!Sqlite::isJuneVersion($sqLiteAdapater)) {
92*d899a2a6Sgerardnico                    /** @noinspection PhpUndefinedMethodInspection */
93*d899a2a6Sgerardnico                    $res = $sqLiteAdapater->executeQuery($this->statement);
94*d899a2a6Sgerardnico                } else {
95*d899a2a6Sgerardnico                    $res = $sqLiteAdapater->query($this->statement);
96c3437056SNickeau                }
9704fd306cSNickeau                $queryExecuted = $this->statement;
98*d899a2a6Sgerardnico                break;
99*d899a2a6Sgerardnico            default:
100*d899a2a6Sgerardnico                throw new ExceptionCompile("The request type ($requestType) was not processed");
101c3437056SNickeau        }
102c3437056SNickeau
103*d899a2a6Sgerardnico
104c3437056SNickeau        if ($res === null) {
10504fd306cSNickeau            throw new ExceptionCompile("No Sql request was found to be executed");
106c3437056SNickeau        }
107c3437056SNickeau
108c3437056SNickeau        if ($res === false) {
109c3437056SNickeau            $message = $this->getErrorMessage();
11004fd306cSNickeau            throw new ExceptionCompile("Error in the $requestType. Message: {$message}");
11104fd306cSNickeau        }
11204fd306cSNickeau
113*d899a2a6Sgerardnico        if (!$res instanceof \PDOStatement) {
11404fd306cSNickeau            $message = $this->getErrorMessage();
11504fd306cSNickeau            throw new ExceptionCompile("Error in the request type `$requestType`. res is not a PDOStatement but as the value ($res). Message: {$message}, Query: {$queryExecuted}");
116c3437056SNickeau        }
117c3437056SNickeau
118c3437056SNickeau        $this->result = new SqliteResult($this, $res);
119c3437056SNickeau        return $this->result;
120c3437056SNickeau    }
121c3437056SNickeau
122*d899a2a6Sgerardnico    public
123*d899a2a6Sgerardnico    function getErrorMessage(): string
124c3437056SNickeau    {
125c3437056SNickeau        $adapter = $this->sqlitePlugin->getAdapter();
126c3437056SNickeau        if ($adapter === null) {
12704fd306cSNickeau            throw new ExceptionRuntimeInternal("The database adapter is null, no error info can be retrieved");
128c3437056SNickeau        }
129*d899a2a6Sgerardnico        if (!Sqlite::isJuneVersion($adapter)) {
130*d899a2a6Sgerardnico            /** @noinspection PhpUndefinedMethodInspection */
131c3437056SNickeau            $do = $adapter->getDb();
132*d899a2a6Sgerardnico        } else {
133*d899a2a6Sgerardnico            $do = $adapter->getPdo();
134*d899a2a6Sgerardnico        }
135c3437056SNickeau        if ($do === null) {
13604fd306cSNickeau            throw new ExceptionRuntimeInternal("The database object is null, it seems that the database connection has been closed. Are you in two differents execution context ?");
137c3437056SNickeau        }
138c3437056SNickeau        $errorInfo = $do->errorInfo();
139c3437056SNickeau        $message = "";
140c3437056SNickeau        $errorCode = $errorInfo[0];
141c3437056SNickeau        if ($errorCode === '0000') {
142c3437056SNickeau            $message = ("No rows were deleted or updated");
143c3437056SNickeau        }
144c3437056SNickeau        $errorInfoAsString = implode(", ", $errorInfo);
145c3437056SNickeau        return "$message. : {$errorInfoAsString}";
146c3437056SNickeau    }
147c3437056SNickeau
148*d899a2a6Sgerardnico    public
149*d899a2a6Sgerardnico    function getSqliteConnection(): Sqlite
150c3437056SNickeau    {
151c3437056SNickeau        return $this->sqlite;
152c3437056SNickeau    }
153c3437056SNickeau
154*d899a2a6Sgerardnico    public
155*d899a2a6Sgerardnico    function close()
156c3437056SNickeau    {
157c3437056SNickeau
158c3437056SNickeau        if ($this->result !== null) {
159c3437056SNickeau            $this->result->close();
160c3437056SNickeau            $this->result = null;
161c3437056SNickeau        }
162c3437056SNickeau
163c3437056SNickeau    }
164c3437056SNickeau
165*d899a2a6Sgerardnico    public
166*d899a2a6Sgerardnico    function setQuery(string $string): SqliteRequest
167c3437056SNickeau    {
168c3437056SNickeau        $this->query = $string;
169c3437056SNickeau        return $this;
170c3437056SNickeau    }
171c3437056SNickeau
172c3437056SNickeau    /**
173c3437056SNickeau     * @param string $executableSql
174c3437056SNickeau     * @param array $parameters
175c3437056SNickeau     * @return SqliteResult
176c3437056SNickeau     */
177*d899a2a6Sgerardnico    public
178*d899a2a6Sgerardnico    function setQueryParametrized(string $executableSql, array $parameters): SqliteRequest
179c3437056SNickeau    {
180*d899a2a6Sgerardnico        $this->statement = $executableSql;
181*d899a2a6Sgerardnico        $this->parameters = $parameters;
182c3437056SNickeau        return $this;
183c3437056SNickeau
184c3437056SNickeau    }
185c3437056SNickeau
186c3437056SNickeau    /**
187c3437056SNickeau     * @param string $statement
188c3437056SNickeau     * @return $this - a statement that will execute
189c3437056SNickeau     */
190*d899a2a6Sgerardnico    public
191*d899a2a6Sgerardnico    function setStatement(string $statement): SqliteRequest
192c3437056SNickeau    {
193c3437056SNickeau        $this->statement = $statement;
194c3437056SNickeau        return $this;
195c3437056SNickeau    }
196c3437056SNickeau
197*d899a2a6Sgerardnico    private
198*d899a2a6Sgerardnico    function getRequestType(): string
199*d899a2a6Sgerardnico    {
200*d899a2a6Sgerardnico        if ($this->data !== null && $this->tableName !== null) {
201*d899a2a6Sgerardnico
202*d899a2a6Sgerardnico            return self::UPSERT_REQUEST;
203*d899a2a6Sgerardnico
204*d899a2a6Sgerardnico        }
205*d899a2a6Sgerardnico
206*d899a2a6Sgerardnico        if ($this->query !== null) {
207*d899a2a6Sgerardnico
208*d899a2a6Sgerardnico            return self::SELECT_REQUEST;
209*d899a2a6Sgerardnico
210*d899a2a6Sgerardnico        }
211*d899a2a6Sgerardnico
212*d899a2a6Sgerardnico        if ($this->parameters !== null) {
213*d899a2a6Sgerardnico
214*d899a2a6Sgerardnico            return self::PARAMETRIZED_REQUEST;
215*d899a2a6Sgerardnico
216*d899a2a6Sgerardnico        }
217*d899a2a6Sgerardnico
218*d899a2a6Sgerardnico        return self::STATEMENT_REQUEST;
219*d899a2a6Sgerardnico
220*d899a2a6Sgerardnico    }
221*d899a2a6Sgerardnico
222*d899a2a6Sgerardnico    /**
223*d899a2a6Sgerardnico     * @param string $table
224*d899a2a6Sgerardnico     * @param array $data
225*d899a2a6Sgerardnico     * @return string - a replace parametrized query
226*d899a2a6Sgerardnico     */
227*d899a2a6Sgerardnico    private function getParametrizeReplaceQuery(string $table, array $data): string
228*d899a2a6Sgerardnico    {
229*d899a2a6Sgerardnico        $columns = array_map(function ($column) {
230*d899a2a6Sgerardnico            return '"' . $column . '"';
231*d899a2a6Sgerardnico        }, array_keys($data));
232*d899a2a6Sgerardnico        $placeholders = array_pad([], count($columns), '?');
233*d899a2a6Sgerardnico        /** @noinspection SqlResolve */
234*d899a2a6Sgerardnico        return 'REPLACE INTO "' . $table . '" (' . join(',', $columns) . ') VALUES (' . join(',',
235*d899a2a6Sgerardnico                $placeholders) . ')';
236*d899a2a6Sgerardnico    }
237*d899a2a6Sgerardnico
238*d899a2a6Sgerardnico    private function executeParametrizedStatement(string $statement, array $values): \PDOStatement
239*d899a2a6Sgerardnico    {
240*d899a2a6Sgerardnico        $sqLiteAdapater = $this->sqlitePlugin->getAdapter();
241*d899a2a6Sgerardnico        $queryParametrized = array_merge([$statement], $values);
242*d899a2a6Sgerardnico        if (!Sqlite::isJuneVersion($sqLiteAdapater)) {
243*d899a2a6Sgerardnico            /** @noinspection PhpParamsInspection */
244*d899a2a6Sgerardnico            return $sqLiteAdapater->query($queryParametrized);
245*d899a2a6Sgerardnico        }
246*d899a2a6Sgerardnico        $values = array_values($values);
247*d899a2a6Sgerardnico        return $sqLiteAdapater->query($statement, $values);
248*d899a2a6Sgerardnico    }
249*d899a2a6Sgerardnico
250c3437056SNickeau}
251