mysql.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. /**
  3. * Copyright (C) 2008-2012 FluxBB
  4. * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
  5. * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  6. */
  7. namespace ForkBB\Core\DB;
  8. // Make sure we have built in support for MySQL
  9. if (!function_exists('mysql_connect'))
  10. exit('This PHP environment doesn\'t have MySQL support built in. MySQL support is required if you want to use a MySQL database to run this forum. Consult the PHP documentation for further assistance.');
  11. class DBLayer
  12. {
  13. var $prefix;
  14. var $link_id;
  15. var $query_result;
  16. var $saved_queries = array();
  17. var $num_queries = 0;
  18. var $error_no = false;
  19. var $error_msg = 'Unknown';
  20. var $datatype_transformations = array(
  21. '%^SERIAL$%' => 'INT(10) UNSIGNED AUTO_INCREMENT'
  22. );
  23. function __construct($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect)
  24. {
  25. $this->prefix = $db_prefix;
  26. if ($p_connect)
  27. $this->link_id = @mysql_pconnect($db_host, $db_username, $db_password);
  28. else
  29. $this->link_id = @mysql_connect($db_host, $db_username, $db_password);
  30. if ($this->link_id)
  31. {
  32. if (!@mysql_select_db($db_name, $this->link_id))
  33. error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__);
  34. }
  35. else
  36. error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__);
  37. // Setup the client-server character set (UTF-8)
  38. if (!defined('FORUM_NO_SET_NAMES'))
  39. $this->set_names('utf8');
  40. return $this->link_id;
  41. }
  42. function start_transaction()
  43. {
  44. return;
  45. }
  46. function end_transaction()
  47. {
  48. return;
  49. }
  50. function query($sql, $unbuffered = false)
  51. {
  52. if (defined('PUN_SHOW_QUERIES'))
  53. $q_start = microtime(true);
  54. if ($unbuffered)
  55. $this->query_result = @mysql_unbuffered_query($sql, $this->link_id);
  56. else
  57. $this->query_result = @mysql_query($sql, $this->link_id);
  58. if ($this->query_result)
  59. {
  60. if (defined('PUN_SHOW_QUERIES'))
  61. $this->saved_queries[] = array($sql, sprintf('%.5f', microtime(true) - $q_start));
  62. ++$this->num_queries;
  63. return $this->query_result;
  64. }
  65. else
  66. {
  67. if (defined('PUN_SHOW_QUERIES'))
  68. $this->saved_queries[] = array($sql, 0);
  69. $this->error_no = @mysql_errno($this->link_id);
  70. $this->error_msg = @mysql_error($this->link_id);
  71. return false;
  72. }
  73. }
  74. function result($query_id = 0, $row = 0, $col = 0)
  75. {
  76. return ($query_id) ? @mysql_result($query_id, $row, $col) : false;
  77. }
  78. function fetch_assoc($query_id = 0)
  79. {
  80. return ($query_id) ? @mysql_fetch_assoc($query_id) : false;
  81. }
  82. function fetch_row($query_id = 0)
  83. {
  84. return ($query_id) ? @mysql_fetch_row($query_id) : false;
  85. }
  86. function num_rows($query_id = 0)
  87. {
  88. return ($query_id) ? @mysql_num_rows($query_id) : false;
  89. }
  90. function affected_rows()
  91. {
  92. return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false;
  93. }
  94. function insert_id()
  95. {
  96. return ($this->link_id) ? @mysql_insert_id($this->link_id) : false;
  97. }
  98. function get_num_queries()
  99. {
  100. return $this->num_queries;
  101. }
  102. function get_saved_queries()
  103. {
  104. return $this->saved_queries;
  105. }
  106. function free_result($query_id = false)
  107. {
  108. return ($query_id) ? @mysql_free_result($query_id) : false;
  109. }
  110. function escape($str)
  111. {
  112. if (is_array($str))
  113. return '';
  114. else if (function_exists('mysql_real_escape_string'))
  115. return mysql_real_escape_string($str, $this->link_id);
  116. else
  117. return mysql_escape_string($str);
  118. }
  119. function error()
  120. {
  121. $result['error_sql'] = @current(@end($this->saved_queries));
  122. $result['error_no'] = $this->error_no;
  123. $result['error_msg'] = $this->error_msg;
  124. return $result;
  125. }
  126. function close()
  127. {
  128. if ($this->link_id)
  129. {
  130. if (is_resource($this->query_result))
  131. @mysql_free_result($this->query_result);
  132. return @mysql_close($this->link_id);
  133. }
  134. else
  135. return false;
  136. }
  137. function get_names()
  138. {
  139. $result = $this->query('SHOW VARIABLES LIKE \'character_set_connection\'');
  140. return $this->result($result, 0, 1);
  141. }
  142. function set_names($names)
  143. {
  144. return $this->query('SET NAMES \''.$this->escape($names).'\'');
  145. }
  146. function get_version()
  147. {
  148. $result = $this->query('SELECT VERSION()');
  149. return array(
  150. 'name' => 'MySQL Standard',
  151. 'version' => preg_replace('%^([^-]+).*$%', '\\1', $this->result($result))
  152. );
  153. }
  154. function table_exists($table_name, $no_prefix = false)
  155. {
  156. $result = $this->query('SHOW TABLES LIKE \''.($no_prefix ? '' : $this->prefix).$this->escape($table_name).'\'');
  157. return $this->num_rows($result) > 0;
  158. }
  159. function field_exists($table_name, $field_name, $no_prefix = false)
  160. {
  161. $result = $this->query('SHOW COLUMNS FROM '.($no_prefix ? '' : $this->prefix).$table_name.' LIKE \''.$this->escape($field_name).'\'');
  162. return $this->num_rows($result) > 0;
  163. }
  164. function index_exists($table_name, $index_name, $no_prefix = false)
  165. {
  166. $exists = false;
  167. $result = $this->query('SHOW INDEX FROM '.($no_prefix ? '' : $this->prefix).$table_name);
  168. while ($cur_index = $this->fetch_assoc($result))
  169. {
  170. if (strtolower($cur_index['Key_name']) == strtolower(($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name))
  171. {
  172. $exists = true;
  173. break;
  174. }
  175. }
  176. return $exists;
  177. }
  178. function create_table($table_name, $schema, $no_prefix = false)
  179. {
  180. if ($this->table_exists($table_name, $no_prefix))
  181. return true;
  182. $query = 'CREATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name." (\n";
  183. // Go through every schema element and add it to the query
  184. foreach ($schema['FIELDS'] as $field_name => $field_data)
  185. {
  186. $field_data['datatype'] = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_data['datatype']);
  187. $query .= $field_name.' '.$field_data['datatype'];
  188. if (isset($field_data['collation']))
  189. $query .= 'CHARACTER SET utf8 COLLATE utf8_'.$field_data['collation'];
  190. if (!$field_data['allow_null'])
  191. $query .= ' NOT NULL';
  192. if (isset($field_data['default']))
  193. $query .= ' DEFAULT '.$field_data['default'];
  194. $query .= ",\n";
  195. }
  196. // If we have a primary key, add it
  197. if (isset($schema['PRIMARY KEY']))
  198. $query .= 'PRIMARY KEY ('.implode(',', $schema['PRIMARY KEY']).'),'."\n";
  199. // Add unique keys
  200. if (isset($schema['UNIQUE KEYS']))
  201. {
  202. foreach ($schema['UNIQUE KEYS'] as $key_name => $key_fields)
  203. $query .= 'UNIQUE KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$key_name.'('.implode(',', $key_fields).'),'."\n";
  204. }
  205. // Add indexes
  206. if (isset($schema['INDEXES']))
  207. {
  208. foreach ($schema['INDEXES'] as $index_name => $index_fields)
  209. $query .= 'KEY '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.'('.implode(',', $index_fields).'),'."\n";
  210. }
  211. // We remove the last two characters (a newline and a comma) and add on the ending
  212. $query = substr($query, 0, strlen($query) - 2)."\n".') ENGINE = '.(isset($schema['ENGINE']) ? $schema['ENGINE'] : 'MyISAM').' CHARACTER SET utf8';
  213. return $this->query($query) ? true : false;
  214. }
  215. function drop_table($table_name, $no_prefix = false)
  216. {
  217. if (!$this->table_exists($table_name, $no_prefix))
  218. return true;
  219. return $this->query('DROP TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false;
  220. }
  221. function rename_table($old_table, $new_table, $no_prefix = false)
  222. {
  223. // If the new table exists and the old one doesn't, then we're happy
  224. if ($this->table_exists($new_table, $no_prefix) && !$this->table_exists($old_table, $no_prefix))
  225. return true;
  226. return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$old_table.' RENAME TO '.($no_prefix ? '' : $this->prefix).$new_table) ? true : false;
  227. }
  228. function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false)
  229. {
  230. if ($this->field_exists($table_name, $field_name, $no_prefix))
  231. return true;
  232. $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type);
  233. if (!is_null($default_value) && !is_int($default_value) && !is_float($default_value))
  234. $default_value = '\''.$this->escape($default_value).'\'';
  235. return $this->query('ALTER TABLE '.($no_prefix ? '' : $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;
  236. }
  237. function alter_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null, $no_prefix = false)
  238. {
  239. if (!$this->field_exists($table_name, $field_name, $no_prefix))
  240. return true;
  241. $field_type = preg_replace(array_keys($this->datatype_transformations), array_values($this->datatype_transformations), $field_type);
  242. if (!is_null($default_value) && !is_int($default_value) && !is_float($default_value))
  243. $default_value = '\''.$this->escape($default_value).'\'';
  244. return $this->query('ALTER TABLE '.($no_prefix ? '' : $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;
  245. }
  246. function drop_field($table_name, $field_name, $no_prefix = false)
  247. {
  248. if (!$this->field_exists($table_name, $field_name, $no_prefix))
  249. return true;
  250. return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP '.$field_name) ? true : false;
  251. }
  252. function add_index($table_name, $index_name, $index_fields, $unique = false, $no_prefix = false)
  253. {
  254. if ($this->index_exists($table_name, $index_name, $no_prefix))
  255. return true;
  256. return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' ADD '.($unique ? 'UNIQUE ' : '').'INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name.' ('.implode(',', $index_fields).')') ? true : false;
  257. }
  258. function drop_index($table_name, $index_name, $no_prefix = false)
  259. {
  260. if (!$this->index_exists($table_name, $index_name, $no_prefix))
  261. return true;
  262. return $this->query('ALTER TABLE '.($no_prefix ? '' : $this->prefix).$table_name.' DROP INDEX '.($no_prefix ? '' : $this->prefix).$table_name.'_'.$index_name) ? true : false;
  263. }
  264. function truncate_table($table_name, $no_prefix = false)
  265. {
  266. return $this->query('TRUNCATE TABLE '.($no_prefix ? '' : $this->prefix).$table_name) ? true : false;
  267. }
  268. }