PageRenderTime 70ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/include/database.php

https://gitlab.com/LibreTitan/Panther
PHP | 306 lines | 243 code | 52 blank | 11 comment | 24 complexity | d034696e2e922302a9fdcd29bf939716 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (C) 2015 Panther (https://www.pantherforum.org)
  4. * based on code by FluxBB copyright (C) 2008-2012 FluxBB
  5. * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
  6. */
  7. if (!defined('PANTHER'))
  8. exit;
  9. class db extends PDO
  10. {
  11. private $saved_queries = array();
  12. private $num_queries = 0;
  13. public $prefix;
  14. public function __construct($config)
  15. {
  16. $this->prefix = panther_trim($config['prefix']);
  17. $opt = array(
  18. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  19. PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
  20. PDO::ATTR_EMULATE_PREPARES => false, // Prior to PHP 5.3.6, this was a security issue. We want actual prepared statements instead of "emulated" ones.
  21. PDO::ATTR_PERSISTENT => $config['p_connect'],
  22. );
  23. try
  24. {
  25. parent::__construct("mysql:host=".$config['host'].";dbname=".$config['db_name'].";charset=utf8", $config['username'], $config['password'], $opt);
  26. }
  27. catch (PDOException $e)
  28. {
  29. error($e->getMessage());
  30. }
  31. }
  32. public function select($table, $fields = '*', $parameters = array(), $where = '', $order_by = '')
  33. {
  34. $sql = "SELECT ".$fields." FROM ".$this->prefix.$table.((!empty($where)) ? " WHERE ".$where : '').((!empty($order_by)) ? " ORDER BY ".$order_by : '');
  35. return $this->run($sql, $parameters, 'select');
  36. }
  37. public function insert($table, $fields)
  38. {
  39. $parameters = array();
  40. $sql = "INSERT INTO ".$this->prefix.$table." (".implode(", ", array_keys($fields)).") VALUES (:".implode(", :", array_keys($fields)).")";
  41. foreach($fields as $column => $value)
  42. $parameters[':'.$column] = $value;
  43. return $this->run($sql, $parameters, 'insert');
  44. }
  45. public function update($table, $fields, $where = '', $parameters = array())
  46. {
  47. $i = 0;
  48. $sql = "UPDATE ".$this->prefix.$table." SET ";
  49. foreach ($fields as $column => $value)
  50. {
  51. $sql .= (($i > 0) ? ', ' : '').$column."=:".$column;
  52. $parameters[':'.$column] = $value;
  53. $i++;
  54. }
  55. $sql .= (!empty($where) ? ' WHERE '.$where : '');
  56. return $this->run($sql, $parameters, 'update');
  57. }
  58. public function delete($table, $where, $parameters = array())
  59. {
  60. $sql = "DELETE FROM ".$this->prefix.$table." WHERE ".$where;
  61. return $this->run($sql, $parameters, 'delete');
  62. }
  63. public function run($sql, $parameters = array(), $type = '')
  64. {
  65. global $panther_config;
  66. if ($panther_config['o_show_queries'] == '1')
  67. $q_start = microtime(true);
  68. $this->sql = panther_trim($sql);
  69. try
  70. {
  71. $ps = $this->prepare($this->sql);
  72. if ($ps->execute($parameters) !== false)
  73. {
  74. if ($panther_config['o_show_queries'] == '1')
  75. $this->saved_queries[] = array($this->sql, sprintf('%.5f', microtime(true) - $q_start));
  76. ++$this->num_queries;
  77. if (in_array($type, array('update', 'delete', 'insert')))
  78. return $ps->rowCount();
  79. else
  80. {
  81. $ps->setFetchMode(PDO::FETCH_ASSOC);
  82. return $ps;
  83. }
  84. }
  85. else
  86. error('Unable to execute query', $this->sql, $parameters);
  87. }
  88. catch (PDOException $e)
  89. {
  90. error($e->getMessage(), $this->sql, $parameters);
  91. }
  92. }
  93. public function start_transaction()
  94. {
  95. try
  96. {
  97. $this->beginTransaction();
  98. }
  99. catch(PDOException $e)
  100. {
  101. error($e->getMessage());
  102. }
  103. }
  104. public function end_transaction()
  105. {
  106. try
  107. {
  108. $this->commit();
  109. }
  110. catch(PDOException $e)
  111. {
  112. error($e->getMessage());
  113. }
  114. }
  115. public function free_result($ps)
  116. {
  117. try
  118. {
  119. $ps->closeCursor();
  120. }
  121. catch(PDOException $e)
  122. {
  123. error($e->getMessage());
  124. }
  125. return true; // If we get this far, then there is no error
  126. }
  127. public function get_num_queries()
  128. {
  129. return $this->num_queries;
  130. }
  131. public function get_saved_queries()
  132. {
  133. return $this->saved_queries;
  134. }
  135. public function get_version()
  136. {
  137. $sql = "SELECT VERSION()";
  138. $ps = $this->run($sql);
  139. return array(
  140. 'name' => 'MySQL',
  141. 'version' => preg_replace('%^([^-]+).*$%', '\\1', $ps->fetchColumn()),
  142. );
  143. }
  144. public function create_table($table_name, $schema)
  145. {
  146. if ($this->table_exists($table_name))
  147. return true;
  148. $query = 'CREATE TABLE '.$this->prefix.$table_name." (\n";
  149. // Go through every schema element and add it to the query
  150. foreach ($schema['FIELDS'] as $field_name => $field_data)
  151. {
  152. $query .= $field_name.' '.$field_data['datatype'];
  153. if (isset($field_data['collation']))
  154. $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation'];
  155. if (!$field_data['allow_null'])
  156. $query .= ' NOT NULL';
  157. if (isset($field_data['default']))
  158. $query .= ' DEFAULT '.$field_data['default'];
  159. $query .= ",\n";
  160. }
  161. // If we have a primary key, add it
  162. if (isset($schema['PRIMARY KEY']))
  163. $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n";
  164. // Add unique keys
  165. if (isset($schema['UNIQUE KEYS']))
  166. {
  167. foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields)
  168. $query .= 'UNIQUE KEY '.$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n";
  169. }
  170. // Add indexes
  171. if (isset($schema['INDEXES']))
  172. {
  173. foreach ($schema['INDEXES'] as $index_name => $index_fields)
  174. $query .= 'KEY '.$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n";
  175. }
  176. // We remove the last two characters (a newline and a comma) and add on the ending
  177. $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'InnoDB').' CHARACTER SET utf8';
  178. return $this->run($query);
  179. }
  180. public function rename_table($old_table, $new_table)
  181. {
  182. // If the new table exists and the old one doesn't, then we're happy
  183. if ($this->table_exists($new_table) && !$this->table_exists($old_table))
  184. return true;
  185. return $this->run('ALTER TABLE '.$this->prefix.$old_table.' RENAME TO '.$this->prefix.$new_table) ? true : false;
  186. }
  187. public function table_exists($table)
  188. {
  189. $sql = "SHOW TABLES LIKE '".$this->prefix.$table."'";
  190. return (($this->run($sql, array(), 'update')) ? true : false);
  191. }
  192. public function drop_table($table)
  193. {
  194. if (!$this->table_exists($table))
  195. return true;
  196. return $this->run('DROP TABLE '.$this->prefix.$table_name) ? true : false;
  197. }
  198. public function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null)
  199. {
  200. if (!$this->field_exists($table_name, $field_name))
  201. return true;
  202. $field_type = preg_replace(array_keys($this->datatypes), array_values($this->datatypes), $field_type);
  203. return $this->run('ALTER TABLE '.$this->prefix.$table_name.' MODIFY '.$field_name.' '.$field_type.($allow_null ? '' : ' NOT NULL').(!is_null($default_value) ? ' DEFAULT '.$default_value : '').(!is_null($after_field) ? ' AFTER '.$after_field : '')) ? true : false;
  204. }
  205. public function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null)
  206. {
  207. if ($this->field_exists($table_name, $field_name, $no_prefix))
  208. return true;
  209. $field_type = preg_replace(array_keys($this->datatypes), array_values($this->datatypes), $field_type);
  210. return $this->run('ALTER TABLE '.$this->prefix.$table_name.' ADD '.$field_name.' '.$field_type.($allow_null ? '' : ' NOT NULL').(!is_null($default_value) ? ' DEFAULT '.$default_value : '').(!is_null($after_field) ? ' AFTER '.$after_field : '')) ? true : false;
  211. }
  212. public function field_exists($table, $field)
  213. {
  214. $sql = "SHOW COLUMNS FROM ".$this->prefix.$table." LIKE '".$field."'";
  215. return (($this->run($sql, array(), 'update') > 0) ? true : false);
  216. }
  217. public function drop_field($table_name, $field_name)
  218. {
  219. if (!$this->field_exists($table_name, $field_name))
  220. return true;
  221. return $this->run('ALTER TABLE '.$this->prefix.$table_name.' DROP '.$field_name) ? true : false;
  222. }
  223. function index_exists($table_name, $index_name)
  224. {
  225. $exists = false;
  226. $ps = $this->run('SHOW INDEX FROM '.$this->prefix.$table_name);
  227. foreach ($ps as $cur_index)
  228. {
  229. if (strtolower($cur_index['Key_name']) == strtolower($this->prefix.$table_name.'_'.$index_name))
  230. {
  231. $exists = true;
  232. break;
  233. }
  234. }
  235. return $exists;
  236. }
  237. public function add_index($table_name, $index_name, $index_fields, $unique = false)
  238. {
  239. if ($this->index_exists($table_name, $index_name))
  240. return true;
  241. return $this->run('ALTER TABLE '.$this->prefix.$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.$this->prefix.$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false;
  242. }
  243. public function drop_index($table_name, $index_name)
  244. {
  245. if (!$this->index_exists($table_name, $index_name))
  246. return true;
  247. return $this->run('ALTER TABLE '.$this->prefix.$table_name.' DROP INDEX '.$this->prefix.$table_name.'_'.$index_name) ? true : false;
  248. }
  249. public function truncate_table($table_name)
  250. {
  251. return $this->run('TRUNCATE TABLE '.$this->prefix.$table_name) ? true : false;
  252. }
  253. }
  254. $db = new db($config);