mysql_innodb.php 11 KB

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