blob: 8078e2bf68c9dc75520cccf833255ce48702a46a [file] [log] [blame]
Andrey Andreev24276a32012-01-08 02:44:38 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
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 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * Database Utility Class
30 *
31 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050032 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000033 * @link http://codeigniter.com/user_guide/database/
34 */
Timothy Warren833d5042012-03-19 16:12:03 -040035abstract class CI_DB_utility extends CI_DB_forge {
Derek Allard2067d1a2008-11-13 22:59:24 +000036
Andrey Andreev24276a32012-01-08 02:44:38 +020037 public $db;
Derek Allard2067d1a2008-11-13 22:59:24 +000038
Andrey Andreevb457a402012-04-09 16:11:56 +030039 // Platform specific SQL strings
40 // Just setting those defaults to FALSE as they are mostly MySQL-specific
41 protected $_optimize_table = FALSE;
42 protected $_repair_table = FALSE;
43
Andrey Andreev5fd3ae82012-10-24 14:55:35 +030044 /**
45 * Constructor
46 *
47 * @return void
48 */
Andrey Andreev24276a32012-01-08 02:44:38 +020049 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000050 {
51 // Assign the main database object to $this->db
52 $CI =& get_instance();
53 $this->db =& $CI->db;
Andrey Andreev24276a32012-01-08 02:44:38 +020054 log_message('debug', 'Database Utility Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000055 }
56
57 // --------------------------------------------------------------------
58
59 /**
60 * List databases
61 *
Andrey Andreevb457a402012-04-09 16:11:56 +030062 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +000063 */
Andrey Andreev24276a32012-01-08 02:44:38 +020064 public function list_databases()
Barry Mienydd671972010-10-04 16:33:58 +020065 {
Derek Allard2067d1a2008-11-13 22:59:24 +000066 // Is there a cached result?
Andrey Andreev5d281762012-06-11 22:05:40 +030067 if (isset($this->db->data_cache['db_names']))
Derek Allard2067d1a2008-11-13 22:59:24 +000068 {
Andrey Andreev5d281762012-06-11 22:05:40 +030069 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000070 }
Andrey Andreevb457a402012-04-09 16:11:56 +030071 elseif ($this->_list_databases === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000072 {
Andrey Andreevb457a402012-04-09 16:11:56 +030073 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000074 }
Barry Mienydd671972010-10-04 16:33:58 +020075
Andrey Andreev5d281762012-06-11 22:05:40 +030076 $this->db->data_cache['db_names'] = array();
Andrey Andreevb457a402012-04-09 16:11:56 +030077
78 $query = $this->db->query($this->_list_databases);
79 if ($query === FALSE)
80 {
Andrey Andreev5d281762012-06-11 22:05:40 +030081 return $this->db->data_cache['db_names'];
Andrey Andreevb457a402012-04-09 16:11:56 +030082 }
83
84 for ($i = 0, $c = count($query); $i < $c; $i++)
85 {
Andrey Andreev5d281762012-06-11 22:05:40 +030086 $this->db->data_cache['db_names'] = current($query[$i]);
Andrey Andreevb457a402012-04-09 16:11:56 +030087 }
88
Andrey Andreev5d281762012-06-11 22:05:40 +030089 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000090 }
91
92 // --------------------------------------------------------------------
93
94 /**
Derek Allarde7f03252010-02-04 16:47:01 +000095 * Determine if a particular database exists
96 *
Derek Allarde7f03252010-02-04 16:47:01 +000097 * @param string
Andrey Andreevb457a402012-04-09 16:11:56 +030098 * @return bool
Derek Allarde7f03252010-02-04 16:47:01 +000099 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200100 public function database_exists($database_name)
Derek Allard62396232010-02-04 17:45:47 +0000101 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300102 return in_array($database_name, $this->list_databases());
Derek Allarde7f03252010-02-04 16:47:01 +0000103 }
104
105 // --------------------------------------------------------------------
106
107 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000108 * Optimize Table
109 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000110 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300111 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000112 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200113 public function optimize_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300115 if ($this->_optimize_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000116 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300117 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000118 }
Barry Mienydd671972010-10-04 16:33:58 +0200119
Andrey Andreevb457a402012-04-09 16:11:56 +0300120 $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
121 if ($query !== FALSE)
122 {
123 $query = $query->result_array();
124 return current($res);
125 }
Barry Mienydd671972010-10-04 16:33:58 +0200126
Andrey Andreevb457a402012-04-09 16:11:56 +0300127 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000128 }
129
130 // --------------------------------------------------------------------
131
132 /**
133 * Optimize Database
134 *
Andrey Andreevb457a402012-04-09 16:11:56 +0300135 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200137 public function optimize_database()
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300139 if ($this->_optimize_table === FALSE)
140 {
141 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
142 }
143
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 $result = array();
145 foreach ($this->db->list_tables() as $table_name)
146 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300147 $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
148 if (is_bool($res))
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300150 return $res;
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 }
Barry Mienydd671972010-10-04 16:33:58 +0200152
Derek Allard2067d1a2008-11-13 22:59:24 +0000153 // Build the result array...
Andrey Andreevb457a402012-04-09 16:11:56 +0300154 $res = $res->result_array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 $res = current($res);
156 $key = str_replace($this->db->database.'.', '', current($res));
157 $keys = array_keys($res);
158 unset($res[$keys[0]]);
Barry Mienydd671972010-10-04 16:33:58 +0200159
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 $result[$key] = $res;
161 }
162
163 return $result;
164 }
165
166 // --------------------------------------------------------------------
167
168 /**
169 * Repair Table
170 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300172 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000173 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200174 public function repair_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300176 if ($this->_repair_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300178 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 }
Barry Mienydd671972010-10-04 16:33:58 +0200180
Andrey Andreevb457a402012-04-09 16:11:56 +0300181 $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
182 if (is_bool($query))
183 {
184 return $query;
185 }
Barry Mienydd671972010-10-04 16:33:58 +0200186
Andrey Andreevb457a402012-04-09 16:11:56 +0300187 $query = $query->result_array();
188 return current($query);
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 }
Barry Mienydd671972010-10-04 16:33:58 +0200190
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 // --------------------------------------------------------------------
192
193 /**
194 * Generate CSV from a query result object
195 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 * @param object The query result object
197 * @param string The delimiter - comma by default
198 * @param string The newline character - \n by default
199 * @param string The enclosure - double quote by default
200 * @return string
201 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200202 public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 {
Derek Jones47874132009-02-10 17:32:15 +0000204 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 {
206 show_error('You must submit a valid result object');
Barry Mienydd671972010-10-04 16:33:58 +0200207 }
208
Derek Allard2067d1a2008-11-13 22:59:24 +0000209 $out = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 // First generate the headings from the table column names
211 foreach ($query->list_fields() as $name)
212 {
213 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
214 }
Barry Mienydd671972010-10-04 16:33:58 +0200215
Andrey Andreev24276a32012-01-08 02:44:38 +0200216 $out = rtrim($out).$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200217
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 // Next blast through the result array and build out the rows
Andrey Andreevd06acd82012-05-25 00:29:09 +0300219 while ($row = $query->unbuffered_row('array'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 {
221 foreach ($row as $item)
222 {
Barry Mienydd671972010-10-04 16:33:58 +0200223 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200225 $out = rtrim($out).$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 }
227
228 return $out;
229 }
Barry Mienydd671972010-10-04 16:33:58 +0200230
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 // --------------------------------------------------------------------
232
233 /**
234 * Generate XML data from a query result object
235 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 * @param object The query result object
237 * @param array Any preferences
238 * @return string
239 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200240 public function xml_from_result($query, $params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000241 {
Pascal Kriete69b1fcc2009-08-24 16:42:52 +0000242 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 {
244 show_error('You must submit a valid result object');
245 }
Barry Mienydd671972010-10-04 16:33:58 +0200246
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 // Set our default values
248 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
249 {
250 if ( ! isset($params[$key]))
251 {
252 $params[$key] = $val;
253 }
254 }
Barry Mienydd671972010-10-04 16:33:58 +0200255
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 // Create variables for convenience
257 extract($params);
Barry Mienydd671972010-10-04 16:33:58 +0200258
Derek Allard2067d1a2008-11-13 22:59:24 +0000259 // Load the xml helper
260 $CI =& get_instance();
261 $CI->load->helper('xml');
262
263 // Generate the result
Andrey Andreevb457a402012-04-09 16:11:56 +0300264 $xml = '<'.$root.'>'.$newline;
Andrey Andreevd06acd82012-05-25 00:29:09 +0300265 while ($row = $query->unbuffered_row())
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300267 $xml .= $tab.'<'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 foreach ($row as $key => $val)
269 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300270 $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 }
Andrey Andreevb457a402012-04-09 16:11:56 +0300272 $xml .= $tab.'</'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000273 }
Barry Mienydd671972010-10-04 16:33:58 +0200274
Andrey Andreevb457a402012-04-09 16:11:56 +0300275 return $xml.'</'.$root.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 }
277
278 // --------------------------------------------------------------------
279
280 /**
281 * Database Backup
282 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300283 * @param array $params = array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 * @return void
285 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200286 public function backup($params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 {
288 // If the parameters have not been submitted as an
289 // array then we know that it is simply the table
290 // name, which is a valid short cut.
291 if (is_string($params))
292 {
293 $params = array('tables' => $params);
294 }
Barry Mienydd671972010-10-04 16:33:58 +0200295
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 // Set up our default preferences
299 $prefs = array(
Andrey Andreev24276a32012-01-08 02:44:38 +0200300 'tables' => array(),
301 'ignore' => array(),
302 'filename' => '',
303 'format' => 'gzip', // gzip, zip, txt
304 'add_drop' => TRUE,
305 'add_insert' => TRUE,
306 'newline' => "\n"
307 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000308
309 // Did the user submit any preferences? If so set them....
310 if (count($params) > 0)
311 {
312 foreach ($prefs as $key => $val)
313 {
314 if (isset($params[$key]))
315 {
316 $prefs[$key] = $params[$key];
317 }
318 }
319 }
320
Barry Mienydd671972010-10-04 16:33:58 +0200321 // Are we backing up a complete database or individual tables?
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 // If no table names were submitted we'll fetch the entire table list
Andrey Andreev24276a32012-01-08 02:44:38 +0200323 if (count($prefs['tables']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 {
325 $prefs['tables'] = $this->db->list_tables();
326 }
Barry Mienydd671972010-10-04 16:33:58 +0200327
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 // Validate the format
329 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
330 {
331 $prefs['format'] = 'txt';
332 }
333
Andrey Andreev24276a32012-01-08 02:44:38 +0200334 // Is the encoder supported? If not, we'll either issue an
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 // error or use plain text depending on the debug settings
Andrey Andreevb457a402012-04-09 16:11:56 +0300336 if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
337 OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 {
339 if ($this->db->db_debug)
340 {
341 return $this->db->display_error('db_unsuported_compression');
342 }
Barry Mienydd671972010-10-04 16:33:58 +0200343
Derek Allard2067d1a2008-11-13 22:59:24 +0000344 $prefs['format'] = 'txt';
345 }
346
Barry Mienydd671972010-10-04 16:33:58 +0200347 // Was a Zip file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200348 if ($prefs['format'] === 'zip')
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200350 // Set the filename if not provided (only needed with Zip files)
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100351 if ($prefs['filename'] === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200353 $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
354 .date('Y-m-d_H-i', time()).'.sql';
Derek Allard2067d1a2008-11-13 22:59:24 +0000355 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200356 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000357 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200358 // If they included the .zip file extension we'll remove it
359 if (preg_match('|.+?\.zip$|', $prefs['filename']))
360 {
361 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
362 }
363
364 // Tack on the ".sql" file extension if needed
365 if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
366 {
367 $prefs['filename'] .= '.sql';
368 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 }
370
371 // Load the Zip class and output it
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 $CI =& get_instance();
373 $CI->load->library('zip');
Barry Mienydd671972010-10-04 16:33:58 +0200374 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
Derek Allard2067d1a2008-11-13 22:59:24 +0000375 return $CI->zip->get_zip();
376 }
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100377 elseif ($prefs['format'] === 'txt') // Was a text file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200378 {
379 return $this->_backup($prefs);
380 }
381 elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
382 {
383 return gzencode($this->_backup($prefs));
384 }
Barry Mienydd671972010-10-04 16:33:58 +0200385
Andrey Andreev24276a32012-01-08 02:44:38 +0200386 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 }
388
389}
390
Derek Allard2067d1a2008-11-13 22:59:24 +0000391/* End of file DB_utility.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400392/* Location: ./system/database/DB_utility.php */