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