PageRenderTime 86ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Database.php

https://gitlab.com/Kewai/base
PHP | 423 lines | 340 code | 43 blank | 40 comment | 20 complexity | eb614c3f2a96afc59f871ae980a692ef MD5 | raw file
  1. <?php
  2. namespace Core;
  3. use \PDO;
  4. class Database {
  5. private static $_instance;
  6. protected $host;
  7. protected $userDB;
  8. protected $passwordDB;
  9. protected $nameDB;
  10. protected $db;
  11. protected $where = [];
  12. protected $bind = [];
  13. protected $orWhere = [];
  14. protected $order = [];
  15. protected $class;
  16. protected $one = FALSE;
  17. protected $type;
  18. protected $backState;
  19. protected $joinType = [];
  20. protected $joinLink = [];
  21. protected $joinNum = -1;
  22. /**
  23. * @param $host
  24. * @param $userDB
  25. * @param $passwordDB
  26. * @param $nameDB
  27. */
  28. public function __construct($host, $userDB, $passwordDB, $nameDB) {
  29. $this->host = $host;
  30. $this->userDB = $userDB;
  31. $this->passwordDB = $passwordDB;
  32. $this->nameDB = $nameDB;
  33. $this->unique = uniqid();
  34. self::$_instance = $this;
  35. }
  36. public static function getInstance() {
  37. return self::$_instance;
  38. }
  39. /**
  40. * Do the connection to mysql server
  41. * @return PDO
  42. */
  43. private function connect() {
  44. if($this->db === null) {
  45. try {
  46. $db = new PDO('mysql:dbname='.$this->nameDB.';$host='.$this->host, $this->userDB, $this->passwordDB);
  47. $db->exec("SET NAMES 'UTF8'");
  48. $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  49. $this->db = $db;
  50. } catch (\PDOException $e ) {
  51. die($e->getMessage());
  52. }
  53. }
  54. return $this->db;
  55. }
  56. /**
  57. * prepare and execute the query
  58. * @param $query
  59. * @internal param params $bind if we used conditions
  60. * @return array
  61. */
  62. private function prepare($query) {
  63. $method = $this->backState;
  64. try {
  65. $sql = $this->connect()->prepare($query);
  66. $sql->execute($this->bind);
  67. if($this->type == 'VIEW') {
  68. $sql->setFetchMode(PDO::FETCH_CLASS, $this->class);
  69. if($this->one == TRUE) {
  70. if(is_null($method)) {
  71. $results = $sql->fetch();
  72. if($results == false){
  73. $results = null;
  74. }
  75. } else {
  76. $result = $sql->fetch();
  77. if($result != false){
  78. $results = $result->$method();
  79. } else {
  80. $results = null;
  81. }
  82. }
  83. } else {
  84. if(is_null($method)) {
  85. $results = $sql->fetchAll();
  86. } else {
  87. $result = $sql->fetchAll();
  88. foreach($result as $data) {
  89. $results[] = $data->$method();
  90. }
  91. }
  92. }
  93. } elseif($this->type == 'INSERT') {
  94. $results = $this->connect()->lastInsertId();
  95. } elseif($this-> type == 'UP_DEL') {
  96. $results = $sql->rowCount();
  97. }
  98. } catch (\PDOException $e) {
  99. $results = $e->getMessage();
  100. }
  101. // KILL CONDITIONS
  102. $this->reset();
  103. $sql->closeCursor();
  104. return $results;
  105. }
  106. /**
  107. * Insert method
  108. * @param $table string
  109. * @param array
  110. * @return array
  111. */
  112. public function insert($table, $data = []) {
  113. $fields = implode(', ', array_keys($data));
  114. $values = implode(', :', array_keys($data));
  115. $sql = "INSERT INTO " . $table ." (" . $fields . ") VALUES (:" . $values . ")";
  116. $this->type = 'INSERT';
  117. $this->bind = $data;
  118. return $this->prepare($sql);
  119. }
  120. /**
  121. * @param $table string
  122. * @param array|as $data as $k => $v
  123. * @return array
  124. */
  125. public function update($table, $data = []) {
  126. $field = null;
  127. foreach($data as $k => $v) {
  128. $field .= $k . ' = ';
  129. if(is_array($v)) {
  130. $field .= $k . ' ' . $v['I'] . ', ';
  131. unset($data[$k]);
  132. } else {
  133. $field .= '?, ';
  134. }
  135. }
  136. $fields = substr($field, 0, -2);
  137. $values = array_values($data);
  138. $sql = "UPDATE " . $table . " SET " . $fields;
  139. if($this->where) {
  140. $sql .= ' WHERE ';
  141. $sql .= implode(' AND ', $this->where);
  142. }
  143. $this->type = 'UP_DEL';
  144. $this->bind = array_merge($values, $this->bind);
  145. return $this->prepare($sql);
  146. }
  147. /**
  148. * @param $table
  149. * @return array
  150. */
  151. public function delete($table) {
  152. $sql = "DELETE FROM " . $table . " WHERE " . implode(' AND ', $this->where);
  153. $this->type = 'UP_DEL';
  154. return $this->prepare($sql);
  155. }
  156. /**
  157. * Build the query and send it to $this->prepare()
  158. * @param $table
  159. * @param string $columns
  160. * @param null $limit
  161. * @param bool $join
  162. * @return array
  163. */
  164. public function get($table, $columns = '*', $limit = null, $join = false) {
  165. $this->class = '\\App\\Entity\\' . $table. 'Entity';
  166. $columns = is_array($columns) ? implode(', ', $columns) : $columns;
  167. $sql = "SELECT " . $columns . " FROM " . $table;
  168. if($join == true) {
  169. $sql .= $this->buildJointure();
  170. }
  171. if($this->where) {
  172. $sql .= ' WHERE ';
  173. $sql .= implode(' AND ', $this->where);
  174. } elseif($this->orWhere) {
  175. $sql .= ' WHERE ';
  176. $sql .= implode(' OR ', $this->orWhere);
  177. }
  178. if($this->order) {
  179. $sql .= ' ORDER BY ';
  180. $sql .= implode(', ', $this->order);
  181. }
  182. $sql .= $this->limit($limit);
  183. $this->type = 'VIEW';
  184. return $this->prepare($sql, $this->bind);
  185. }
  186. /**
  187. * put $this->one TRUE and keep it with get() method
  188. * @param $table
  189. * @param string $columns
  190. * @param null $limit
  191. * @param bool $join
  192. * @return array
  193. */
  194. public function getOne($table, $columns = '*', $limit = null, $join = false) {
  195. $this->one = TRUE;
  196. return $this->get($table, $columns, $limit, $join);
  197. }
  198. /**
  199. * instance a method to sent result from prepare to $tableEntity
  200. * @param $method
  201. * @return $this
  202. */
  203. public function backState($method) {
  204. $this->backState = $method;
  205. return $this;
  206. }
  207. /**
  208. * @param $col
  209. * @param $value
  210. * @param string $operator
  211. * @return $this
  212. */
  213. public function where($col, $value, $operator = '=') {
  214. $this->where[] = $col . ' ' . $operator . ' ?';
  215. $this->bind[] = $value;
  216. return $this;
  217. }
  218. /**
  219. * @param $col
  220. * @param $value
  221. * @param string $operator
  222. * @return $this
  223. */
  224. public function orWhere($col, $value, $operator = '=') {
  225. $this->orWhere[] = $col . ' ' . $operator . ' ?';
  226. $this->bind[] = $value;
  227. return $this;
  228. }
  229. /**
  230. * Build an order by
  231. * @param $column
  232. * @param $order
  233. */
  234. public function orderBy($column, $order) {
  235. $orderAllowed = ['ASC', 'DESC'];
  236. if(!in_array(strtoupper($order), $orderAllowed)) {
  237. die('Only ASC and DESC are allowed.');
  238. }
  239. $this->order[] = $column . ' ' . $order;
  240. }
  241. /**
  242. * Build limit for the query
  243. * @param $limit
  244. * @return null|string
  245. */
  246. private function limit($limit) {
  247. if (!isset ($limit))
  248. return null;
  249. if(is_array($limit)) {
  250. return $sql = ' LIMIT ' . $limit[0] . ', ' . $limit[1];
  251. } else {
  252. return $sql = ' LIMIT ' . $limit;
  253. }
  254. }
  255. // Function Aggregate
  256. /**
  257. * Count()
  258. * @param $table
  259. * @param $column
  260. * @return array
  261. */
  262. public function count($table, $column = '*') {
  263. $instruction = 'COUNT(' . $column .') as cnt';
  264. return $this->getOne($table, $instruction, null);
  265. }
  266. /**
  267. * MIN()
  268. * @param $table
  269. * @param $column
  270. * @return array
  271. */
  272. public function min($table, $column) {
  273. $instruction = 'MIN(' . $column .') as min';
  274. return $this->getOne($table, $instruction, null);
  275. }
  276. /**
  277. * MAX()
  278. * @param $table
  279. * @param $column
  280. * @return array
  281. */
  282. public function max($table, $column) {
  283. $instruction = 'MAX(' . $column .') as max';
  284. return $this->getOne($table, $instruction, null);
  285. }
  286. /**
  287. * SUM()
  288. * @param $table
  289. * @param $column
  290. * @return array
  291. */
  292. public function sum($table, $column) {
  293. $instruction = 'SUM(' . $column .') as sum';
  294. return $this->getOne($table, $instruction, null);
  295. }
  296. /**
  297. * method to increment a column I as Increment
  298. * @param string $num
  299. * @return array
  300. */
  301. public function inc($num = '1') {
  302. return ["I" => "+" . (int)$num];
  303. }
  304. /**
  305. * method to de-increment a column I as Increment
  306. * @param string $num
  307. * @return array
  308. */
  309. public function dec($num = '1') {
  310. return ["I" => "-" . (int)$num];
  311. }
  312. /**
  313. * Reset params for a new query
  314. */
  315. private function reset() {
  316. $this->where = [];
  317. $this->bind = [];
  318. $this->order = [];
  319. $this->class = null;
  320. $this->type = null;
  321. $this->one = FALSE;
  322. $this->backState = null;
  323. $this->joinType = [];
  324. $this->joinLink = null;
  325. $this->joinNum = -1;
  326. }
  327. public function join($type, $table) {
  328. $this->joinNum++;
  329. $this->joinType[] = ' ' . strtoupper($type) . ' JOIN ' . $table;
  330. }
  331. public function joinOn($condition) {
  332. $this->joinLink[$this->joinNum][] = $condition;
  333. }
  334. private function buildJointure() {
  335. var_dump($this->joinLink);
  336. $build = null;
  337. foreach ($this->joinType as $k => $v) {
  338. $build .= $v . ' ON ';
  339. $i = $k;
  340. var_dump($i);
  341. var_dump($this->joinLink[$i]);
  342. $build .= implode(' AND ', $this->joinLink[$i]);
  343. }
  344. return $build;
  345. }
  346. }