blob: 6a3b40779b5c6f7c1049d342551d677f2a1915bd [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 Andreev24276a32012-01-08 02:44:38 +020044 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000045 {
46 // Assign the main database object to $this->db
47 $CI =& get_instance();
48 $this->db =& $CI->db;
Andrey Andreev24276a32012-01-08 02:44:38 +020049 log_message('debug', 'Database Utility Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000050 }
51
52 // --------------------------------------------------------------------
53
54 /**
55 * List databases
56 *
Andrey Andreevb457a402012-04-09 16:11:56 +030057 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +000058 */
Andrey Andreev24276a32012-01-08 02:44:38 +020059 public function list_databases()
Barry Mienydd671972010-10-04 16:33:58 +020060 {
Derek Allard2067d1a2008-11-13 22:59:24 +000061 // Is there a cached result?
Andrey Andreev5d281762012-06-11 22:05:40 +030062 if (isset($this->db->data_cache['db_names']))
Derek Allard2067d1a2008-11-13 22:59:24 +000063 {
Andrey Andreev5d281762012-06-11 22:05:40 +030064 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000065 }
Andrey Andreevb457a402012-04-09 16:11:56 +030066 elseif ($this->_list_databases === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000067 {
Andrey Andreevb457a402012-04-09 16:11:56 +030068 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000069 }
Barry Mienydd671972010-10-04 16:33:58 +020070
Andrey Andreev5d281762012-06-11 22:05:40 +030071 $this->db->data_cache['db_names'] = array();
Andrey Andreevb457a402012-04-09 16:11:56 +030072
73 $query = $this->db->query($this->_list_databases);
74 if ($query === FALSE)
75 {
Andrey Andreev5d281762012-06-11 22:05:40 +030076 return $this->db->data_cache['db_names'];
Andrey Andreevb457a402012-04-09 16:11:56 +030077 }
78
79 for ($i = 0, $c = count($query); $i < $c; $i++)
80 {
Andrey Andreev5d281762012-06-11 22:05:40 +030081 $this->db->data_cache['db_names'] = current($query[$i]);
Andrey Andreevb457a402012-04-09 16:11:56 +030082 }
83
Andrey Andreev5d281762012-06-11 22:05:40 +030084 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000085 }
86
87 // --------------------------------------------------------------------
88
89 /**
Derek Allarde7f03252010-02-04 16:47:01 +000090 * Determine if a particular database exists
91 *
Derek Allarde7f03252010-02-04 16:47:01 +000092 * @param string
Andrey Andreevb457a402012-04-09 16:11:56 +030093 * @return bool
Derek Allarde7f03252010-02-04 16:47:01 +000094 */
Andrey Andreev24276a32012-01-08 02:44:38 +020095 public function database_exists($database_name)
Derek Allard62396232010-02-04 17:45:47 +000096 {
Andrey Andreevb457a402012-04-09 16:11:56 +030097 return in_array($database_name, $this->list_databases());
Derek Allarde7f03252010-02-04 16:47:01 +000098 }
99
100 // --------------------------------------------------------------------
101
102 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000103 * Optimize Table
104 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000105 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300106 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000107 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200108 public function optimize_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300110 if ($this->_optimize_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300112 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 }
Barry Mienydd671972010-10-04 16:33:58 +0200114
Andrey Andreevb457a402012-04-09 16:11:56 +0300115 $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
116 if ($query !== FALSE)
117 {
118 $query = $query->result_array();
119 return current($res);
120 }
Barry Mienydd671972010-10-04 16:33:58 +0200121
Andrey Andreevb457a402012-04-09 16:11:56 +0300122 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000123 }
124
125 // --------------------------------------------------------------------
126
127 /**
128 * Optimize Database
129 *
Andrey Andreevb457a402012-04-09 16:11:56 +0300130 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200132 public function optimize_database()
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300134 if ($this->_optimize_table === FALSE)
135 {
136 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
137 }
138
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 $result = array();
140 foreach ($this->db->list_tables() as $table_name)
141 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300142 $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
143 if (is_bool($res))
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300145 return $res;
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 }
Barry Mienydd671972010-10-04 16:33:58 +0200147
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 // Build the result array...
Andrey Andreevb457a402012-04-09 16:11:56 +0300149 $res = $res->result_array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 $res = current($res);
151 $key = str_replace($this->db->database.'.', '', current($res));
152 $keys = array_keys($res);
153 unset($res[$keys[0]]);
Barry Mienydd671972010-10-04 16:33:58 +0200154
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 $result[$key] = $res;
156 }
157
158 return $result;
159 }
160
161 // --------------------------------------------------------------------
162
163 /**
164 * Repair Table
165 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300167 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000168 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200169 public function repair_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000170 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300171 if ($this->_repair_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300173 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000174 }
Barry Mienydd671972010-10-04 16:33:58 +0200175
Andrey Andreevb457a402012-04-09 16:11:56 +0300176 $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
177 if (is_bool($query))
178 {
179 return $query;
180 }
Barry Mienydd671972010-10-04 16:33:58 +0200181
Andrey Andreevb457a402012-04-09 16:11:56 +0300182 $query = $query->result_array();
183 return current($query);
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 }
Barry Mienydd671972010-10-04 16:33:58 +0200185
Derek Allard2067d1a2008-11-13 22:59:24 +0000186 // --------------------------------------------------------------------
187
188 /**
189 * Generate CSV from a query result object
190 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 * @param object The query result object
192 * @param string The delimiter - comma by default
193 * @param string The newline character - \n by default
194 * @param string The enclosure - double quote by default
195 * @return string
196 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200197 public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 {
Derek Jones47874132009-02-10 17:32:15 +0000199 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 {
201 show_error('You must submit a valid result object');
Barry Mienydd671972010-10-04 16:33:58 +0200202 }
203
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 $out = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 // First generate the headings from the table column names
206 foreach ($query->list_fields() as $name)
207 {
208 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
209 }
Barry Mienydd671972010-10-04 16:33:58 +0200210
Andrey Andreev24276a32012-01-08 02:44:38 +0200211 $out = rtrim($out).$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200212
Derek Allard2067d1a2008-11-13 22:59:24 +0000213 // Next blast through the result array and build out the rows
Andrey Andreevd06acd82012-05-25 00:29:09 +0300214 while ($row = $query->unbuffered_row('array'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 {
216 foreach ($row as $item)
217 {
Barry Mienydd671972010-10-04 16:33:58 +0200218 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200220 $out = rtrim($out).$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000221 }
222
223 return $out;
224 }
Barry Mienydd671972010-10-04 16:33:58 +0200225
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 // --------------------------------------------------------------------
227
228 /**
229 * Generate XML data from a query result object
230 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 * @param object The query result object
232 * @param array Any preferences
233 * @return string
234 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200235 public function xml_from_result($query, $params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
Pascal Kriete69b1fcc2009-08-24 16:42:52 +0000237 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 {
239 show_error('You must submit a valid result object');
240 }
Barry Mienydd671972010-10-04 16:33:58 +0200241
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 // Set our default values
243 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
244 {
245 if ( ! isset($params[$key]))
246 {
247 $params[$key] = $val;
248 }
249 }
Barry Mienydd671972010-10-04 16:33:58 +0200250
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 // Create variables for convenience
252 extract($params);
Barry Mienydd671972010-10-04 16:33:58 +0200253
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 // Load the xml helper
255 $CI =& get_instance();
256 $CI->load->helper('xml');
257
258 // Generate the result
Andrey Andreevb457a402012-04-09 16:11:56 +0300259 $xml = '<'.$root.'>'.$newline;
Andrey Andreevd06acd82012-05-25 00:29:09 +0300260 while ($row = $query->unbuffered_row())
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300262 $xml .= $tab.'<'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 foreach ($row as $key => $val)
264 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300265 $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
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 }
Barry Mienydd671972010-10-04 16:33:58 +0200269
Andrey Andreevb457a402012-04-09 16:11:56 +0300270 return $xml.'</'.$root.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 }
272
273 // --------------------------------------------------------------------
274
275 /**
276 * Database Backup
277 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000278 * @return void
279 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200280 public function backup($params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 {
282 // If the parameters have not been submitted as an
283 // array then we know that it is simply the table
284 // name, which is a valid short cut.
285 if (is_string($params))
286 {
287 $params = array('tables' => $params);
288 }
Barry Mienydd671972010-10-04 16:33:58 +0200289
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200291
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 // Set up our default preferences
293 $prefs = array(
Andrey Andreev24276a32012-01-08 02:44:38 +0200294 'tables' => array(),
295 'ignore' => array(),
296 'filename' => '',
297 'format' => 'gzip', // gzip, zip, txt
298 'add_drop' => TRUE,
299 'add_insert' => TRUE,
300 'newline' => "\n"
301 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000302
303 // Did the user submit any preferences? If so set them....
304 if (count($params) > 0)
305 {
306 foreach ($prefs as $key => $val)
307 {
308 if (isset($params[$key]))
309 {
310 $prefs[$key] = $params[$key];
311 }
312 }
313 }
314
Barry Mienydd671972010-10-04 16:33:58 +0200315 // Are we backing up a complete database or individual tables?
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 // If no table names were submitted we'll fetch the entire table list
Andrey Andreev24276a32012-01-08 02:44:38 +0200317 if (count($prefs['tables']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
319 $prefs['tables'] = $this->db->list_tables();
320 }
Barry Mienydd671972010-10-04 16:33:58 +0200321
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 // Validate the format
323 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
324 {
325 $prefs['format'] = 'txt';
326 }
327
Andrey Andreev24276a32012-01-08 02:44:38 +0200328 // Is the encoder supported? If not, we'll either issue an
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 // error or use plain text depending on the debug settings
Andrey Andreevb457a402012-04-09 16:11:56 +0300330 if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
331 OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 {
333 if ($this->db->db_debug)
334 {
335 return $this->db->display_error('db_unsuported_compression');
336 }
Barry Mienydd671972010-10-04 16:33:58 +0200337
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 $prefs['format'] = 'txt';
339 }
340
Barry Mienydd671972010-10-04 16:33:58 +0200341 // Was a Zip file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200342 if ($prefs['format'] === 'zip')
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200344 // Set the filename if not provided (only needed with Zip files)
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100345 if ($prefs['filename'] === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200347 $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
348 .date('Y-m-d_H-i', time()).'.sql';
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200350 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000351 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200352 // If they included the .zip file extension we'll remove it
353 if (preg_match('|.+?\.zip$|', $prefs['filename']))
354 {
355 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
356 }
357
358 // Tack on the ".sql" file extension if needed
359 if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
360 {
361 $prefs['filename'] .= '.sql';
362 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000363 }
364
365 // Load the Zip class and output it
Derek Allard2067d1a2008-11-13 22:59:24 +0000366 $CI =& get_instance();
367 $CI->load->library('zip');
Barry Mienydd671972010-10-04 16:33:58 +0200368 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 return $CI->zip->get_zip();
370 }
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100371 elseif ($prefs['format'] === 'txt') // Was a text file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200372 {
373 return $this->_backup($prefs);
374 }
375 elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
376 {
377 return gzencode($this->_backup($prefs));
378 }
Barry Mienydd671972010-10-04 16:33:58 +0200379
Andrey Andreev24276a32012-01-08 02:44:38 +0200380 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 }
382
383}
384
Derek Allard2067d1a2008-11-13 22:59:24 +0000385/* End of file DB_utility.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400386/* Location: ./system/database/DB_utility.php */