blob: d2d99ccea92874647308350875b20b079c58587a [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
Derek Jonesf4a4bd82011-10-20 12:18:42 -05003 * CodeIgniter
Derek Allard2067d1a2008-11-13 22:59:24 +00004 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev24276a32012-01-08 02:44:38 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev24276a32012-01-08 02:44:38 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
Andrey Andreevd947eba2012-04-09 14:58:28 +030030 * Database Forge Class
Derek Allard2067d1a2008-11-13 22:59:24 +000031 *
32 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050033 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000034 * @link http://codeigniter.com/user_guide/database/
35 */
Timothy Warren833d5042012-03-19 16:12:03 -040036abstract class CI_DB_forge {
Derek Allard2067d1a2008-11-13 22:59:24 +000037
Andrey Andreevae85eb42012-11-02 01:42:31 +020038 /**
39 * Fields data
40 *
41 * @var array
42 */
Andrey Andreev24276a32012-01-08 02:44:38 +020043 public $fields = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020044
45 /**
46 * Keys data
47 *
48 * @var array
49 */
Andrey Andreev24276a32012-01-08 02:44:38 +020050 public $keys = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020051
52 /**
53 * Primary Keys data
54 *
55 * @var array
56 */
Andrey Andreev24276a32012-01-08 02:44:38 +020057 public $primary_keys = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020058
59 /**
60 * Database character set
61 *
62 * @var string
63 */
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030064 public $db_char_set = '';
Derek Allard2067d1a2008-11-13 22:59:24 +000065
Andrey Andreevae85eb42012-11-02 01:42:31 +020066 // --------------------------------------------------------------------
67
68 /**
69 * CREATE DATABASE statement
70 *
71 * @var string
72 */
Andrey Andreevd947eba2012-04-09 14:58:28 +030073 protected $_create_database = 'CREATE DATABASE %s';
Andrey Andreevae85eb42012-11-02 01:42:31 +020074
75 /**
76 * DROP DATABASE statement
77 *
78 * @var string
79 */
Andrey Andreevd947eba2012-04-09 14:58:28 +030080 protected $_drop_database = 'DROP DATABASE %s';
Andrey Andreevae85eb42012-11-02 01:42:31 +020081
82 /**
83 * DROP TABLE statement
84 *
85 * @var string
86 */
Andrey Andreevd947eba2012-04-09 14:58:28 +030087 protected $_drop_table = 'DROP TABLE IF EXISTS %s';
Andrey Andreevae85eb42012-11-02 01:42:31 +020088
89 /**
90 * RENAME TABLE statement
91 *
92 * @var string
93 */
Andrey Andreevd947eba2012-04-09 14:58:28 +030094 protected $_rename_table = 'ALTER TABLE %s RENAME TO %s';
95
Andrey Andreevae85eb42012-11-02 01:42:31 +020096 // --------------------------------------------------------------------
97
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030098 /**
99 * Constructor
100 *
101 * @return void
102 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200103 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 {
105 // Assign the main database object to $this->db
106 $CI =& get_instance();
107 $this->db =& $CI->db;
Andrey Andreev24276a32012-01-08 02:44:38 +0200108 log_message('debug', 'Database Forge Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 }
110
111 // --------------------------------------------------------------------
112
113 /**
114 * Create database
115 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000116 * @param string the database name
117 * @return bool
118 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200119 public function create_database($db_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000120 {
Andrey Andreevd947eba2012-04-09 14:58:28 +0300121 if ($this->_create_database === FALSE)
122 {
123 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
124 }
125 elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat)))
126 {
127 return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
128 }
129
Andrey Andreev5d281762012-06-11 22:05:40 +0300130 if ( ! empty($this->db->data_cache['db_names']))
131 {
132 $this->db->data_cache['db_names'][] = $db_name;
133 }
134
Andrey Andreevd947eba2012-04-09 14:58:28 +0300135 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 }
137
138 // --------------------------------------------------------------------
139
140 /**
141 * Drop database
142 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000143 * @param string the database name
144 * @return bool
145 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200146 public function drop_database($db_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100148 if ($db_name === '')
Andrey Andreevd947eba2012-04-09 14:58:28 +0300149 {
150 show_error('A table name is required for that operation.');
151 return FALSE;
152 }
153 elseif ($this->_drop_database === FALSE)
154 {
155 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
156 }
157 elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name)))
158 {
159 return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
160 }
161
Andrey Andreev5d281762012-06-11 22:05:40 +0300162 if ( ! empty($this->db->data_cache['db_names']))
163 {
164 $key = array_search(strtolower($db_name), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
165 if ($key !== FALSE)
166 {
167 unset($this->db->data_cache['db_names'][$key]);
168 }
169 }
170
Andrey Andreevd947eba2012-04-09 14:58:28 +0300171 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 }
173
174 // --------------------------------------------------------------------
175
176 /**
177 * Add Key
178 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 * @param string key
180 * @param string type
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000181 * @return object
Derek Allard2067d1a2008-11-13 22:59:24 +0000182 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000183 public function add_key($key = '', $primary = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 {
185 if (is_array($key))
186 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500187 foreach ($key as $one)
Derek Allard2067d1a2008-11-13 22:59:24 +0000188 {
189 $this->add_key($one, $primary);
190 }
Barry Mienydd671972010-10-04 16:33:58 +0200191
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 return;
193 }
Barry Mienydd671972010-10-04 16:33:58 +0200194
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100195 if ($key === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 {
197 show_error('Key information is required for that operation.');
198 }
Barry Mienydd671972010-10-04 16:33:58 +0200199
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 if ($primary === TRUE)
201 {
202 $this->primary_keys[] = $key;
203 }
204 else
205 {
206 $this->keys[] = $key;
207 }
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000208
209 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 }
211
212 // --------------------------------------------------------------------
213
214 /**
215 * Add Field
216 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000217 * @param string collation
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000218 * @return object
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000220 public function add_field($field = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000221 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100222 if ($field === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 {
224 show_error('Field information is required.');
225 }
Barry Mienydd671972010-10-04 16:33:58 +0200226
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 if (is_string($field))
228 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200229 if ($field === 'id')
Derek Allard2067d1a2008-11-13 22:59:24 +0000230 {
231 $this->add_field(array(
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000232 'id' => array(
233 'type' => 'INT',
234 'constraint' => 9,
235 'auto_increment' => TRUE
236 )
237 ));
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 $this->add_key('id', TRUE);
239 }
240 else
241 {
242 if (strpos($field, ' ') === FALSE)
243 {
244 show_error('Field information is required for that operation.');
245 }
Barry Mienydd671972010-10-04 16:33:58 +0200246
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 $this->fields[] = $field;
248 }
249 }
Barry Mienydd671972010-10-04 16:33:58 +0200250
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 if (is_array($field))
252 {
253 $this->fields = array_merge($this->fields, $field);
254 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200255
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000256 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 }
258
259 // --------------------------------------------------------------------
260
261 /**
262 * Create Table
263 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300264 * @param string $table = ''
265 * @param bool $if_not_exists = FALSE
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 * @return bool
267 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000268 public function create_table($table = '', $if_not_exists = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +0200269 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100270 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 {
272 show_error('A table name is required for that operation.');
273 }
Barry Mienydd671972010-10-04 16:33:58 +0200274
Andrey Andreev24276a32012-01-08 02:44:38 +0200275 if (count($this->fields) === 0)
Barry Mienydd671972010-10-04 16:33:58 +0200276 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 show_error('Field information is required.');
278 }
279
280 $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 $this->_reset();
Andrey Andreev5d281762012-06-11 22:05:40 +0300282
283 if (is_bool($sql))
284 {
285 return $sql;
286 }
287
288 if (($result = $this->db->query($sql)) !== FALSE && ! empty($this->db->data_cache['table_names']))
289 {
Phil Sturgeonf68db392012-06-14 17:14:11 -0500290 $this->db->data_cache['table_names'][] = $this->db->dbprefix.$table;
Andrey Andreev5d281762012-06-11 22:05:40 +0300291 }
292
293 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000294 }
295
296 // --------------------------------------------------------------------
297
298 /**
299 * Drop Table
300 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 * @param string the table name
302 * @return bool
303 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000304 public function drop_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100306 if ($table_name === '')
Andrey Andreevd947eba2012-04-09 14:58:28 +0300307 {
308 return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE;
309 }
310 elseif ($this->_drop_table === FALSE)
311 {
312 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
313 }
314
Andrey Andreev5d281762012-06-11 22:05:40 +0300315 $result = $this->db->query(sprintf($this->_drop_table, $this->db->escape_identifiers($this->db->dbprefix.$table_name)));
316
317 // Update table list cache
318 if ($result && ! empty($this->db->data_cache['table_names']))
319 {
320 $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE);
321 if ($key !== FALSE)
322 {
323 unset($this->db->data_cache['table_names'][$key]);
324 }
325 }
326
327 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 }
329
330 // --------------------------------------------------------------------
331
332 /**
333 * Rename Table
334 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 * @param string the old table name
336 * @param string the new table name
337 * @return bool
338 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000339 public function rename_table($table_name, $new_table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100341 if ($table_name === '' OR $new_table_name === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 show_error('A table name is required for that operation.');
Andrey Andreevd947eba2012-04-09 14:58:28 +0300344 return FALSE;
345 }
346 elseif ($this->_rename_table === FALSE)
347 {
348 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 }
Barry Mienydd671972010-10-04 16:33:58 +0200350
Andrey Andreev5d281762012-06-11 22:05:40 +0300351 $result = $this->db->query(sprintf($this->_rename_table,
Andrey Andreevd947eba2012-04-09 14:58:28 +0300352 $this->db->escape_identifiers($this->db->dbprefix.$table_name),
353 $this->db->escape_identifiers($this->db->dbprefix.$new_table_name))
354 );
Andrey Andreev5d281762012-06-11 22:05:40 +0300355
356 if ($result && ! empty($this->db->data_cache['table_names']))
357 {
358 $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE);
359 if ($key !== FALSE)
360 {
361 $this->db->data_cache['table_names'][$key] = $this->db->dbprefix.$new_table_name;
362 }
363 }
364
365 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000366 }
367
368 // --------------------------------------------------------------------
369
370 /**
371 * Column Add
372 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000373 * @param string the table name
374 * @param string the column name
375 * @param string the column definition
376 * @return bool
377 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000378 public function add_column($table = '', $field = array(), $after_field = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000379 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100380 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 {
382 show_error('A table name is required for that operation.');
383 }
384
385 // add field info into field array, but we can only do one at a time
Robin Sowell8a54ef22009-03-04 14:49:53 +0000386 // so we cycle through
Andrey Andreev24276a32012-01-08 02:44:38 +0200387 foreach (array_keys($field) as $k)
Barry Mienydd671972010-10-04 16:33:58 +0200388 {
389 $this->add_field(array($k => $field[$k]));
Robin Sowell8a54ef22009-03-04 14:49:53 +0000390
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100391 if (count($this->fields) === 0)
Barry Mienydd671972010-10-04 16:33:58 +0200392 {
Robin Sowell8a54ef22009-03-04 14:49:53 +0000393 show_error('Field information is required.');
394 }
Barry Mienydd671972010-10-04 16:33:58 +0200395
Robin Sowell8a54ef22009-03-04 14:49:53 +0000396 $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);
Robin Sowell8a54ef22009-03-04 14:49:53 +0000397 $this->_reset();
Barry Mienydd671972010-10-04 16:33:58 +0200398
Robin Sowell8a54ef22009-03-04 14:49:53 +0000399 if ($this->db->query($sql) === FALSE)
400 {
401 return FALSE;
402 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 }
Barry Mienydd671972010-10-04 16:33:58 +0200404
Robin Sowell8a54ef22009-03-04 14:49:53 +0000405 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 }
407
408 // --------------------------------------------------------------------
409
410 /**
411 * Column Drop
412 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000413 * @param string the table name
414 * @param string the column name
415 * @return bool
416 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000417 public function drop_column($table = '', $column_name = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000418 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100419 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000420 {
421 show_error('A table name is required for that operation.');
422 }
423
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100424 if ($column_name === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000425 {
426 show_error('A column name is required for that operation.');
427 }
428
Andrey Andreev24276a32012-01-08 02:44:38 +0200429 return $this->db->query($this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name));
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 }
431
432 // --------------------------------------------------------------------
433
434 /**
435 * Column Modify
436 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300437 * @param string $table = ''
438 * @param string $field = array() column definition
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 * @return bool
440 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000441 public function modify_column($table = '', $field = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100443 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 {
445 show_error('A table name is required for that operation.');
446 }
447
448 // add field info into field array, but we can only do one at a time
Robin Sowell8a54ef22009-03-04 14:49:53 +0000449 // so we cycle through
Andrey Andreev24276a32012-01-08 02:44:38 +0200450 foreach (array_keys($field) as $k)
Robin Sowell8a54ef22009-03-04 14:49:53 +0000451 {
Phil Sturgeona58ecae2010-12-15 10:32:10 +0000452 // If no name provided, use the current name
453 if ( ! isset($field[$k]['name']))
454 {
455 $field[$k]['name'] = $k;
456 }
457
Robin Sowell8a54ef22009-03-04 14:49:53 +0000458 $this->add_field(array($k => $field[$k]));
Andrey Andreev24276a32012-01-08 02:44:38 +0200459 if (count($this->fields) === 0)
Barry Mienydd671972010-10-04 16:33:58 +0200460 {
Robin Sowell8a54ef22009-03-04 14:49:53 +0000461 show_error('Field information is required.');
462 }
Barry Mienydd671972010-10-04 16:33:58 +0200463
Robin Sowell8a54ef22009-03-04 14:49:53 +0000464 $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);
Robin Sowell8a54ef22009-03-04 14:49:53 +0000465 $this->_reset();
Barry Mienydd671972010-10-04 16:33:58 +0200466
Robin Sowell8a54ef22009-03-04 14:49:53 +0000467 if ($this->db->query($sql) === FALSE)
468 {
469 return FALSE;
470 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000471 }
Barry Mienydd671972010-10-04 16:33:58 +0200472
Robin Sowell8a54ef22009-03-04 14:49:53 +0000473 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 }
475
476 // --------------------------------------------------------------------
477
478 /**
479 * Reset
480 *
481 * Resets table creation vars
482 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 * @return void
484 */
Phil Sturgeona7de97e2011-12-31 18:41:08 +0000485 protected function _reset()
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200487 $this->fields = $this->keys = $this->primary_keys = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000488 }
489
490}
491
492/* End of file DB_forge.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400493/* Location: ./system/database/DB_forge.php */