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