blob: 12680be5fbb3dada051074d2ac6dbf5cddeefbf4 [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/**
30 * Database Utility Class
31 *
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_utility extends CI_DB_forge {
Derek Allard2067d1a2008-11-13 22:59:24 +000037
Andrey Andreev24276a32012-01-08 02:44:38 +020038 public $db;
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 Andreev5fd3ae82012-10-24 14:55:35 +030045 /**
46 * Constructor
47 *
48 * @return void
49 */
Andrey Andreev24276a32012-01-08 02:44:38 +020050 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000051 {
52 // Assign the main database object to $this->db
53 $CI =& get_instance();
54 $this->db =& $CI->db;
Andrey Andreev24276a32012-01-08 02:44:38 +020055 log_message('debug', 'Database Utility Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000056 }
57
58 // --------------------------------------------------------------------
59
60 /**
61 * List databases
62 *
Andrey Andreevb457a402012-04-09 16:11:56 +030063 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +000064 */
Andrey Andreev24276a32012-01-08 02:44:38 +020065 public function list_databases()
Barry Mienydd671972010-10-04 16:33:58 +020066 {
Derek Allard2067d1a2008-11-13 22:59:24 +000067 // Is there a cached result?
Andrey Andreev5d281762012-06-11 22:05:40 +030068 if (isset($this->db->data_cache['db_names']))
Derek Allard2067d1a2008-11-13 22:59:24 +000069 {
Andrey Andreev5d281762012-06-11 22:05:40 +030070 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000071 }
Andrey Andreevb457a402012-04-09 16:11:56 +030072 elseif ($this->_list_databases === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000073 {
Andrey Andreevb457a402012-04-09 16:11:56 +030074 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +000075 }
Barry Mienydd671972010-10-04 16:33:58 +020076
Andrey Andreev5d281762012-06-11 22:05:40 +030077 $this->db->data_cache['db_names'] = array();
Andrey Andreevb457a402012-04-09 16:11:56 +030078
79 $query = $this->db->query($this->_list_databases);
80 if ($query === FALSE)
81 {
Andrey Andreev5d281762012-06-11 22:05:40 +030082 return $this->db->data_cache['db_names'];
Andrey Andreevb457a402012-04-09 16:11:56 +030083 }
84
85 for ($i = 0, $c = count($query); $i < $c; $i++)
86 {
Andrey Andreev5d281762012-06-11 22:05:40 +030087 $this->db->data_cache['db_names'] = current($query[$i]);
Andrey Andreevb457a402012-04-09 16:11:56 +030088 }
89
Andrey Andreev5d281762012-06-11 22:05:40 +030090 return $this->db->data_cache['db_names'];
Derek Allard2067d1a2008-11-13 22:59:24 +000091 }
92
93 // --------------------------------------------------------------------
94
95 /**
Derek Allarde7f03252010-02-04 16:47:01 +000096 * Determine if a particular database exists
97 *
Derek Allarde7f03252010-02-04 16:47:01 +000098 * @param string
Andrey Andreevb457a402012-04-09 16:11:56 +030099 * @return bool
Derek Allarde7f03252010-02-04 16:47:01 +0000100 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200101 public function database_exists($database_name)
Derek Allard62396232010-02-04 17:45:47 +0000102 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300103 return in_array($database_name, $this->list_databases());
Derek Allarde7f03252010-02-04 16:47:01 +0000104 }
105
106 // --------------------------------------------------------------------
107
108 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 * Optimize Table
110 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300112 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200114 public function optimize_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300116 if ($this->_optimize_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000117 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300118 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 }
Barry Mienydd671972010-10-04 16:33:58 +0200120
Andrey Andreevb457a402012-04-09 16:11:56 +0300121 $query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
122 if ($query !== FALSE)
123 {
124 $query = $query->result_array();
125 return current($res);
126 }
Barry Mienydd671972010-10-04 16:33:58 +0200127
Andrey Andreevb457a402012-04-09 16:11:56 +0300128 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000129 }
130
131 // --------------------------------------------------------------------
132
133 /**
134 * Optimize Database
135 *
Andrey Andreevb457a402012-04-09 16:11:56 +0300136 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000137 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200138 public function optimize_database()
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300140 if ($this->_optimize_table === FALSE)
141 {
142 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
143 }
144
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 $result = array();
146 foreach ($this->db->list_tables() as $table_name)
147 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300148 $res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
149 if (is_bool($res))
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300151 return $res;
Derek Allard2067d1a2008-11-13 22:59:24 +0000152 }
Barry Mienydd671972010-10-04 16:33:58 +0200153
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 // Build the result array...
Andrey Andreevb457a402012-04-09 16:11:56 +0300155 $res = $res->result_array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 $res = current($res);
157 $key = str_replace($this->db->database.'.', '', current($res));
158 $keys = array_keys($res);
159 unset($res[$keys[0]]);
Barry Mienydd671972010-10-04 16:33:58 +0200160
Derek Allard2067d1a2008-11-13 22:59:24 +0000161 $result[$key] = $res;
162 }
163
164 return $result;
165 }
166
167 // --------------------------------------------------------------------
168
169 /**
170 * Repair Table
171 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 * @param string the table name
Andrey Andreevb457a402012-04-09 16:11:56 +0300173 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +0000174 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200175 public function repair_table($table_name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000176 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300177 if ($this->_repair_table === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300179 return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000180 }
Barry Mienydd671972010-10-04 16:33:58 +0200181
Andrey Andreevb457a402012-04-09 16:11:56 +0300182 $query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
183 if (is_bool($query))
184 {
185 return $query;
186 }
Barry Mienydd671972010-10-04 16:33:58 +0200187
Andrey Andreevb457a402012-04-09 16:11:56 +0300188 $query = $query->result_array();
189 return current($query);
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 }
Barry Mienydd671972010-10-04 16:33:58 +0200191
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 // --------------------------------------------------------------------
193
194 /**
195 * Generate CSV from a query result object
196 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 * @param object The query result object
198 * @param string The delimiter - comma by default
199 * @param string The newline character - \n by default
200 * @param string The enclosure - double quote by default
201 * @return string
202 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200203 public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
Derek Jones47874132009-02-10 17:32:15 +0000205 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000206 {
207 show_error('You must submit a valid result object');
Barry Mienydd671972010-10-04 16:33:58 +0200208 }
209
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 $out = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000211 // First generate the headings from the table column names
212 foreach ($query->list_fields() as $name)
213 {
214 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
215 }
Barry Mienydd671972010-10-04 16:33:58 +0200216
Andrey Andreev24276a32012-01-08 02:44:38 +0200217 $out = rtrim($out).$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200218
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 // Next blast through the result array and build out the rows
Andrey Andreevd06acd82012-05-25 00:29:09 +0300220 while ($row = $query->unbuffered_row('array'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000221 {
222 foreach ($row as $item)
223 {
Barry Mienydd671972010-10-04 16:33:58 +0200224 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200226 $out = rtrim($out).$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000227 }
228
229 return $out;
230 }
Barry Mienydd671972010-10-04 16:33:58 +0200231
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 // --------------------------------------------------------------------
233
234 /**
235 * Generate XML data from a query result object
236 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 * @param object The query result object
238 * @param array Any preferences
239 * @return string
240 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200241 public function xml_from_result($query, $params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 {
Pascal Kriete69b1fcc2009-08-24 16:42:52 +0000243 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 {
245 show_error('You must submit a valid result object');
246 }
Barry Mienydd671972010-10-04 16:33:58 +0200247
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 // Set our default values
249 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
250 {
251 if ( ! isset($params[$key]))
252 {
253 $params[$key] = $val;
254 }
255 }
Barry Mienydd671972010-10-04 16:33:58 +0200256
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 // Create variables for convenience
258 extract($params);
Barry Mienydd671972010-10-04 16:33:58 +0200259
Derek Allard2067d1a2008-11-13 22:59:24 +0000260 // Load the xml helper
261 $CI =& get_instance();
262 $CI->load->helper('xml');
263
264 // Generate the result
Andrey Andreevb457a402012-04-09 16:11:56 +0300265 $xml = '<'.$root.'>'.$newline;
Andrey Andreevd06acd82012-05-25 00:29:09 +0300266 while ($row = $query->unbuffered_row())
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 foreach ($row as $key => $val)
270 {
Andrey Andreevb457a402012-04-09 16:11:56 +0300271 $xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000272 }
Andrey Andreevb457a402012-04-09 16:11:56 +0300273 $xml .= $tab.'</'.$element.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 }
Barry Mienydd671972010-10-04 16:33:58 +0200275
Andrey Andreevb457a402012-04-09 16:11:56 +0300276 return $xml.'</'.$root.'>'.$newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 }
278
279 // --------------------------------------------------------------------
280
281 /**
282 * Database Backup
283 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300284 * @param array $params = array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000285 * @return void
286 */
Andrey Andreev24276a32012-01-08 02:44:38 +0200287 public function backup($params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 {
289 // If the parameters have not been submitted as an
290 // array then we know that it is simply the table
291 // name, which is a valid short cut.
292 if (is_string($params))
293 {
294 $params = array('tables' => $params);
295 }
Barry Mienydd671972010-10-04 16:33:58 +0200296
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200298
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 // Set up our default preferences
300 $prefs = array(
Andrey Andreev24276a32012-01-08 02:44:38 +0200301 'tables' => array(),
302 'ignore' => array(),
303 'filename' => '',
304 'format' => 'gzip', // gzip, zip, txt
305 'add_drop' => TRUE,
306 'add_insert' => TRUE,
307 'newline' => "\n"
308 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000309
310 // Did the user submit any preferences? If so set them....
311 if (count($params) > 0)
312 {
313 foreach ($prefs as $key => $val)
314 {
315 if (isset($params[$key]))
316 {
317 $prefs[$key] = $params[$key];
318 }
319 }
320 }
321
Barry Mienydd671972010-10-04 16:33:58 +0200322 // Are we backing up a complete database or individual tables?
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 // If no table names were submitted we'll fetch the entire table list
Andrey Andreev24276a32012-01-08 02:44:38 +0200324 if (count($prefs['tables']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000325 {
326 $prefs['tables'] = $this->db->list_tables();
327 }
Barry Mienydd671972010-10-04 16:33:58 +0200328
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 // Validate the format
330 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
331 {
332 $prefs['format'] = 'txt';
333 }
334
Andrey Andreev24276a32012-01-08 02:44:38 +0200335 // Is the encoder supported? If not, we'll either issue an
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 // error or use plain text depending on the debug settings
Andrey Andreevb457a402012-04-09 16:11:56 +0300337 if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
338 OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 {
340 if ($this->db->db_debug)
341 {
342 return $this->db->display_error('db_unsuported_compression');
343 }
Barry Mienydd671972010-10-04 16:33:58 +0200344
Derek Allard2067d1a2008-11-13 22:59:24 +0000345 $prefs['format'] = 'txt';
346 }
347
Barry Mienydd671972010-10-04 16:33:58 +0200348 // Was a Zip file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200349 if ($prefs['format'] === 'zip')
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200351 // Set the filename if not provided (only needed with Zip files)
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100352 if ($prefs['filename'] === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000353 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200354 $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
355 .date('Y-m-d_H-i', time()).'.sql';
Derek Allard2067d1a2008-11-13 22:59:24 +0000356 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200357 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 {
Andrey Andreev24276a32012-01-08 02:44:38 +0200359 // If they included the .zip file extension we'll remove it
360 if (preg_match('|.+?\.zip$|', $prefs['filename']))
361 {
362 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
363 }
364
365 // Tack on the ".sql" file extension if needed
366 if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
367 {
368 $prefs['filename'] .= '.sql';
369 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 }
371
372 // Load the Zip class and output it
Derek Allard2067d1a2008-11-13 22:59:24 +0000373 $CI =& get_instance();
374 $CI->load->library('zip');
Barry Mienydd671972010-10-04 16:33:58 +0200375 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 return $CI->zip->get_zip();
377 }
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100378 elseif ($prefs['format'] === 'txt') // Was a text file requested?
Andrey Andreev24276a32012-01-08 02:44:38 +0200379 {
380 return $this->_backup($prefs);
381 }
382 elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
383 {
384 return gzencode($this->_backup($prefs));
385 }
Barry Mienydd671972010-10-04 16:33:58 +0200386
Andrey Andreev24276a32012-01-08 02:44:38 +0200387 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000388 }
389
390}
391
Derek Allard2067d1a2008-11-13 22:59:24 +0000392/* End of file DB_utility.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400393/* Location: ./system/database/DB_utility.php */