blob: 587dfdc010e2cf567d2e9c5ff355bd84a73fadd4 [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;
38 public $data_cache = array();
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Andrey Andreevb457a402012-04-09 16:11:56 +030040 // Platform specific SQL strings
41 // Just setting those defaults to FALSE as they are mostly MySQL-specific
42 protected $_optimize_table = FALSE;
43 protected $_repair_table = FALSE;
44
Andrey Andreev24276a32012-01-08 02:44:38 +020045 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000046 {
47 // Assign the main database object to $this->db
48 $CI =& get_instance();
49 $this->db =& $CI->db;
Andrey Andreev24276a32012-01-08 02:44:38 +020050 log_message('debug', 'Database Utility Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000051 }
52
53 // --------------------------------------------------------------------
54
55 /**
56 * List databases
57 *
Andrey Andreevb457a402012-04-09 16:11:56 +030058 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +000059 */
Andrey Andreev24276a32012-01-08 02:44:38 +020060 public function list_databases()
Barry Mienydd671972010-10-04 16:33:58 +020061 {
Derek Allard2067d1a2008-11-13 22:59:24 +000062 // Is there a cached result?
63 if (isset($this->data_cache['db_names']))
64 {
65 return $this->data_cache['db_names'];
66 }
Andrey Andreevb457a402012-04-09 16:11:56 +030067 elseif ($this->_list_databases === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000068 {
Andrey Andreevb457a402012-04-09 16:11:56 +030069 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000070 }
Barry Mienydd671972010-10-04 16:33:58 +020071
Andrey Andreevb457a402012-04-09 16:11:56 +030072 $this->data_cache['db_names'] = array();
73
74 $query = $this->db->query($this->_list_databases);
75 if ($query === FALSE)
76 {
77 return $this->data_cache['db_names'];
78 }
79
80 for ($i = 0, $c = count($query); $i < $c; $i++)
81 {
82 $this->data_cache['db_names'] = current($query[$i]);
83 }
84
85 return $this->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000086 }
87
88 // --------------------------------------------------------------------
89
90 /**
Derek Allarde7f03252010-02-04 16:47:01 +000091 * Determine if a particular database exists
92 *
Derek Allarde7f03252010-02-04 16:47:01 +000093 * @param string
Andrey Andreevb457a402012-04-09 16:11:56 +030094 * @return bool
Derek Allarde7f03252010-02-04 16:47:01 +000095 */
Andrey Andreev24276a32012-01-08 02:44:38 +020096 public function database_exists($database_name)
Derek Allard62396232010-02-04 17:45:47 +000097 {
Andrey Andreevb457a402012-04-09 16:11:56 +030098 return in_array($database_name, $this->list_databases());
Derek Allarde7f03252010-02-04 16:47:01 +000099 }
100
101 // --------------------------------------------------------------------
102
103 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 * Optimize Table
105 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000106 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300107 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000108 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200109 public function optimize_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000110 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300111 if ($this->_optimize_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000112 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300113 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 }
Barry Mienydd671972010-10-04 16:33:58 +0200115
Andrey Andreevb457a402012-04-09 16:11:56 +0300116 $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
117 if ($query !== FALSE)
118 {
119 $query = $query->result_array();
120 return current($res);
121 }
Barry Mienydd671972010-10-04 16:33:58 +0200122
Andrey Andreevb457a402012-04-09 16:11:56 +0300123 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 }
125
126 // --------------------------------------------------------------------
127
128 /**
129 * Optimize Database
130 *
Andrey Andreevb457a402012-04-09 16:11:56 +0300131 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000132 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200133 public function optimize_database()
Derek Allard2067d1a2008-11-13 22:59:24 +0000134 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300135 if ($this->_optimize_table === FALSE)
136 {
137 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
138 }
139
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 $result = array();
141 foreach ($this->db->list_tables() as $table_name)
142 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300143 $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
144 if (is_bool($res))
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300146 return $res;
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 }
Barry Mienydd671972010-10-04 16:33:58 +0200148
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 // Build the result array...
Andrey Andreevb457a402012-04-09 16:11:56 +0300150 $res = $res->result_array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 $res = current($res);
152 $key = str_replace($this->db->database.'.', '', current($res));
153 $keys = array_keys($res);
154 unset($res[$keys[0]]);
Barry Mienydd671972010-10-04 16:33:58 +0200155
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 $result[$key] = $res;
157 }
158
159 return $result;
160 }
161
162 // --------------------------------------------------------------------
163
164 /**
165 * Repair Table
166 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300168 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200170 public function repair_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300172 if ($this->_repair_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000173 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300174 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 }
Barry Mienydd671972010-10-04 16:33:58 +0200176
Andrey Andreevb457a402012-04-09 16:11:56 +0300177 $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
178 if (is_bool($query))
179 {
180 return $query;
181 }
Barry Mienydd671972010-10-04 16:33:58 +0200182
Andrey Andreevb457a402012-04-09 16:11:56 +0300183 $query = $query->result_array();
184 return current($query);
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 }
Barry Mienydd671972010-10-04 16:33:58 +0200186
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 // --------------------------------------------------------------------
188
189 /**
190 * Generate CSV from a query result object
191 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 * @param object The query result object
193 * @param string The delimiter - comma by default
194 * @param string The newline character - \n by default
195 * @param string The enclosure - double quote by default
196 * @return string
197 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200198 public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 {
Derek Jones47874132009-02-10 17:32:15 +0000200 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 {
202 show_error('You must submit a valid result object');
Barry Mienydd671972010-10-04 16:33:58 +0200203 }
204
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 $out = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000206 // First generate the headings from the table column names
207 foreach ($query->list_fields() as $name)
208 {
209 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
210 }
Barry Mienydd671972010-10-04 16:33:58 +0200211
Andrey Andreev24276a32012-01-08 02:44:38 +0200212 $out = rtrim($out).$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200213
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 // Next blast through the result array and build out the rows
215 foreach ($query->result_array() as $row)
216 {
217 foreach ($row as $item)
218 {
Barry Mienydd671972010-10-04 16:33:58 +0200219 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200221 $out = rtrim($out).$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 }
223
224 return $out;
225 }
Barry Mienydd671972010-10-04 16:33:58 +0200226
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 // --------------------------------------------------------------------
228
229 /**
230 * Generate XML data from a query result object
231 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 * @param object The query result object
233 * @param array Any preferences
234 * @return string
235 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200236 public function xml_from_result($query, $params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 {
Pascal Kriete69b1fcc2009-08-24 16:42:52 +0000238 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000239 {
240 show_error('You must submit a valid result object');
241 }
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 // Set our default values
244 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
245 {
246 if ( ! isset($params[$key]))
247 {
248 $params[$key] = $val;
249 }
250 }
Barry Mienydd671972010-10-04 16:33:58 +0200251
Derek Allard2067d1a2008-11-13 22:59:24 +0000252 // Create variables for convenience
253 extract($params);
Barry Mienydd671972010-10-04 16:33:58 +0200254
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 // Load the xml helper
256 $CI =& get_instance();
257 $CI->load->helper('xml');
258
259 // Generate the result
Andrey Andreevb457a402012-04-09 16:11:56 +0300260 $xml = '<'.$root.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 foreach ($query->result_array() as $row)
262 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300263 $xml .= $tab.'<'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 foreach ($row as $key => $val)
265 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300266 $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000267 }
Andrey Andreevb457a402012-04-09 16:11:56 +0300268 $xml .= $tab.'</'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 }
Barry Mienydd671972010-10-04 16:33:58 +0200270
Andrey Andreevb457a402012-04-09 16:11:56 +0300271 return $xml.'</'.$root.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 }
273
274 // --------------------------------------------------------------------
275
276 /**
277 * Database Backup
278 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000279 * @return void
280 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200281 public function backup($params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000282 {
283 // If the parameters have not been submitted as an
284 // array then we know that it is simply the table
285 // name, which is a valid short cut.
286 if (is_string($params))
287 {
288 $params = array('tables' => $params);
289 }
Barry Mienydd671972010-10-04 16:33:58 +0200290
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200292
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 // Set up our default preferences
294 $prefs = array(
Andrey Andreev24276a32012-01-08 02:44:38 +0200295 'tables' => array(),
296 'ignore' => array(),
297 'filename' => '',
298 'format' => 'gzip', // gzip, zip, txt
299 'add_drop' => TRUE,
300 'add_insert' => TRUE,
301 'newline' => "\n"
302 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000303
304 // Did the user submit any preferences? If so set them....
305 if (count($params) > 0)
306 {
307 foreach ($prefs as $key => $val)
308 {
309 if (isset($params[$key]))
310 {
311 $prefs[$key] = $params[$key];
312 }
313 }
314 }
315
Barry Mienydd671972010-10-04 16:33:58 +0200316 // Are we backing up a complete database or individual tables?
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 // If no table names were submitted we'll fetch the entire table list
Andrey Andreev24276a32012-01-08 02:44:38 +0200318 if (count($prefs['tables']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000319 {
320 $prefs['tables'] = $this->db->list_tables();
321 }
Barry Mienydd671972010-10-04 16:33:58 +0200322
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 // Validate the format
324 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
325 {
326 $prefs['format'] = 'txt';
327 }
328
Andrey Andreev24276a32012-01-08 02:44:38 +0200329 // Is the encoder supported? If not, we'll either issue an
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 // error or use plain text depending on the debug settings
Andrey Andreevb457a402012-04-09 16:11:56 +0300331 if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
332 OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 {
334 if ($this->db->db_debug)
335 {
336 return $this->db->display_error('db_unsuported_compression');
337 }
Barry Mienydd671972010-10-04 16:33:58 +0200338
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 $prefs['format'] = 'txt';
340 }
341
Barry Mienydd671972010-10-04 16:33:58 +0200342 // Was a Zip file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200343 if ($prefs['format'] === 'zip')
Derek Allard2067d1a2008-11-13 22:59:24 +0000344 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200345 // Set the filename if not provided (only needed with Zip files)
346 if ($prefs['filename'] == '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000347 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200348 $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
349 .date('Y-m-d_H-i', time()).'.sql';
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200351 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200353 // If they included the .zip file extension we'll remove it
354 if (preg_match('|.+?\.zip$|', $prefs['filename']))
355 {
356 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
357 }
358
359 // Tack on the ".sql" file extension if needed
360 if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
361 {
362 $prefs['filename'] .= '.sql';
363 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000364 }
365
366 // Load the Zip class and output it
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 $CI =& get_instance();
368 $CI->load->library('zip');
Barry Mienydd671972010-10-04 16:33:58 +0200369 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 return $CI->zip->get_zip();
371 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200372 elseif ($prefs['format'] == 'txt') // Was a text file requested?
373 {
374 return $this->_backup($prefs);
375 }
376 elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
377 {
378 return gzencode($this->_backup($prefs));
379 }
Barry Mienydd671972010-10-04 16:33:58 +0200380
Andrey Andreev24276a32012-01-08 02:44:38 +0200381 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000382 }
383
384}
385
Derek Allard2067d1a2008-11-13 22:59:24 +0000386/* End of file DB_utility.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400387/* Location: ./system/database/DB_utility.php */