blob: 60ecb52695897106dcc9227477fb6d4012456f1d [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?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 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * 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
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @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
28// ------------------------------------------------------------------------
29
30/**
31 * Database Utility Class
32 *
33 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050034 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000035 * @link http://codeigniter.com/user_guide/database/
36 */
37class CI_DB_utility extends CI_DB_forge {
38
39 var $db;
Barry Mienydd671972010-10-04 16:33:58 +020040 var $data_cache = array();
Derek Allard2067d1a2008-11-13 22:59:24 +000041
42 /**
43 * Constructor
44 *
45 * Grabs the CI super object instance so we can access it.
46 *
Barry Mienydd671972010-10-04 16:33:58 +020047 */
Timothy Warrena2097a02011-10-10 10:10:46 -040048 function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000049 {
50 // Assign the main database object to $this->db
51 $CI =& get_instance();
52 $this->db =& $CI->db;
Barry Mienydd671972010-10-04 16:33:58 +020053
Derek Allard2067d1a2008-11-13 22:59:24 +000054 log_message('debug', "Database Utility Class Initialized");
55 }
56
57 // --------------------------------------------------------------------
58
59 /**
60 * List databases
61 *
62 * @access public
63 * @return bool
64 */
65 function list_databases()
Barry Mienydd671972010-10-04 16:33:58 +020066 {
Derek Allard2067d1a2008-11-13 22:59:24 +000067 // Is there a cached result?
68 if (isset($this->data_cache['db_names']))
69 {
70 return $this->data_cache['db_names'];
71 }
Barry Mienydd671972010-10-04 16:33:58 +020072
Derek Allard2067d1a2008-11-13 22:59:24 +000073 $query = $this->db->query($this->_list_databases());
74 $dbs = array();
75 if ($query->num_rows() > 0)
76 {
77 foreach ($query->result_array() as $row)
78 {
79 $dbs[] = current($row);
80 }
81 }
Barry Mienydd671972010-10-04 16:33:58 +020082
Derek Allard2067d1a2008-11-13 22:59:24 +000083 $this->data_cache['db_names'] = $dbs;
84 return $this->data_cache['db_names'];
85 }
86
87 // --------------------------------------------------------------------
88
89 /**
Derek Allarde7f03252010-02-04 16:47:01 +000090 * Determine if a particular database exists
91 *
92 * @access public
93 * @param string
94 * @return boolean
95 */
96 function database_exists($database_name)
Derek Allard62396232010-02-04 17:45:47 +000097 {
98 // Some databases won't have access to the list_databases() function, so
99 // this is intended to allow them to override with their own functions as
100 // defined in $driver_utility.php
101 if (method_exists($this, '_database_exists'))
102 {
103 return $this->_database_exists($database_name);
104 }
105 else
106 {
107 return ( ! in_array($database_name, $this->list_databases())) ? FALSE : TRUE;
108 }
Derek Allarde7f03252010-02-04 16:47:01 +0000109 }
110
Derek Allard62396232010-02-04 17:45:47 +0000111
Derek Allarde7f03252010-02-04 16:47:01 +0000112 // --------------------------------------------------------------------
113
114 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 * Optimize Table
116 *
117 * @access public
118 * @param string the table name
119 * @return bool
120 */
121 function optimize_table($table_name)
122 {
123 $sql = $this->_optimize_table($table_name);
Barry Mienydd671972010-10-04 16:33:58 +0200124
Derek Allard2067d1a2008-11-13 22:59:24 +0000125 if (is_bool($sql))
126 {
127 show_error('db_must_use_set');
128 }
Barry Mienydd671972010-10-04 16:33:58 +0200129
Derek Allard2067d1a2008-11-13 22:59:24 +0000130 $query = $this->db->query($sql);
131 $res = $query->result_array();
Barry Mienydd671972010-10-04 16:33:58 +0200132
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 // Note: Due to a bug in current() that affects some versions
134 // of PHP we can not pass function call directly into it
135 return current($res);
136 }
137
138 // --------------------------------------------------------------------
139
140 /**
141 * Optimize Database
142 *
143 * @access public
144 * @return array
145 */
146 function optimize_database()
147 {
148 $result = array();
149 foreach ($this->db->list_tables() as $table_name)
150 {
151 $sql = $this->_optimize_table($table_name);
Barry Mienydd671972010-10-04 16:33:58 +0200152
Derek Allard2067d1a2008-11-13 22:59:24 +0000153 if (is_bool($sql))
154 {
155 return $sql;
156 }
Barry Mienydd671972010-10-04 16:33:58 +0200157
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 $query = $this->db->query($sql);
Barry Mienydd671972010-10-04 16:33:58 +0200159
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 // Build the result array...
161 // Note: Due to a bug in current() that affects some versions
162 // of PHP we can not pass function call directly into it
163 $res = $query->result_array();
164 $res = current($res);
165 $key = str_replace($this->db->database.'.', '', current($res));
166 $keys = array_keys($res);
167 unset($res[$keys[0]]);
Barry Mienydd671972010-10-04 16:33:58 +0200168
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 $result[$key] = $res;
170 }
171
172 return $result;
173 }
174
175 // --------------------------------------------------------------------
176
177 /**
178 * Repair Table
179 *
180 * @access public
181 * @param string the table name
182 * @return bool
183 */
184 function repair_table($table_name)
185 {
186 $sql = $this->_repair_table($table_name);
Barry Mienydd671972010-10-04 16:33:58 +0200187
Derek Allard2067d1a2008-11-13 22:59:24 +0000188 if (is_bool($sql))
189 {
190 return $sql;
191 }
Barry Mienydd671972010-10-04 16:33:58 +0200192
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 $query = $this->db->query($sql);
Barry Mienydd671972010-10-04 16:33:58 +0200194
Derek Allard2067d1a2008-11-13 22:59:24 +0000195 // Note: Due to a bug in current() that affects some versions
196 // of PHP we can not pass function call directly into it
197 $res = $query->result_array();
198 return current($res);
199 }
Barry Mienydd671972010-10-04 16:33:58 +0200200
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 // --------------------------------------------------------------------
202
203 /**
204 * Generate CSV from a query result object
205 *
206 * @access public
207 * @param object The query result object
208 * @param string The delimiter - comma by default
209 * @param string The newline character - \n by default
210 * @param string The enclosure - double quote by default
211 * @return string
212 */
213 function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
214 {
Derek Jones47874132009-02-10 17:32:15 +0000215 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 {
217 show_error('You must submit a valid result object');
Barry Mienydd671972010-10-04 16:33:58 +0200218 }
219
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 $out = '';
Barry Mienydd671972010-10-04 16:33:58 +0200221
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 // First generate the headings from the table column names
223 foreach ($query->list_fields() as $name)
224 {
225 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
226 }
Barry Mienydd671972010-10-04 16:33:58 +0200227
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 $out = rtrim($out);
229 $out .= $newline;
Barry Mienydd671972010-10-04 16:33:58 +0200230
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 // Next blast through the result array and build out the rows
232 foreach ($query->result_array() as $row)
233 {
234 foreach ($row as $item)
235 {
Barry Mienydd671972010-10-04 16:33:58 +0200236 $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 }
238 $out = rtrim($out);
239 $out .= $newline;
240 }
241
242 return $out;
243 }
Barry Mienydd671972010-10-04 16:33:58 +0200244
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 // --------------------------------------------------------------------
246
247 /**
248 * Generate XML data from a query result object
249 *
250 * @access public
251 * @param object The query result object
252 * @param array Any preferences
253 * @return string
254 */
255 function xml_from_result($query, $params = array())
256 {
Pascal Kriete69b1fcc2009-08-24 16:42:52 +0000257 if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 {
259 show_error('You must submit a valid result object');
260 }
Barry Mienydd671972010-10-04 16:33:58 +0200261
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 // Set our default values
263 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
264 {
265 if ( ! isset($params[$key]))
266 {
267 $params[$key] = $val;
268 }
269 }
Barry Mienydd671972010-10-04 16:33:58 +0200270
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 // Create variables for convenience
272 extract($params);
Barry Mienydd671972010-10-04 16:33:58 +0200273
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 // Load the xml helper
275 $CI =& get_instance();
276 $CI->load->helper('xml');
277
278 // Generate the result
279 $xml = "<{$root}>".$newline;
280 foreach ($query->result_array() as $row)
281 {
282 $xml .= $tab."<{$element}>".$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200283
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 foreach ($row as $key => $val)
285 {
286 $xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
287 }
288 $xml .= $tab."</{$element}>".$newline;
289 }
290 $xml .= "</$root>".$newline;
Barry Mienydd671972010-10-04 16:33:58 +0200291
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 return $xml;
293 }
294
295 // --------------------------------------------------------------------
296
297 /**
298 * Database Backup
299 *
300 * @access public
301 * @return void
302 */
303 function backup($params = array())
304 {
305 // If the parameters have not been submitted as an
306 // array then we know that it is simply the table
307 // name, which is a valid short cut.
308 if (is_string($params))
309 {
310 $params = array('tables' => $params);
311 }
Barry Mienydd671972010-10-04 16:33:58 +0200312
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200314
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 // Set up our default preferences
316 $prefs = array(
317 'tables' => array(),
318 'ignore' => array(),
319 'filename' => '',
320 'format' => 'gzip', // gzip, zip, txt
321 'add_drop' => TRUE,
322 'add_insert' => TRUE,
323 'newline' => "\n"
324 );
325
326 // Did the user submit any preferences? If so set them....
327 if (count($params) > 0)
328 {
329 foreach ($prefs as $key => $val)
330 {
331 if (isset($params[$key]))
332 {
333 $prefs[$key] = $params[$key];
334 }
335 }
336 }
337
338 // ------------------------------------------------------
339
Barry Mienydd671972010-10-04 16:33:58 +0200340 // Are we backing up a complete database or individual tables?
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 // If no table names were submitted we'll fetch the entire table list
342 if (count($prefs['tables']) == 0)
343 {
344 $prefs['tables'] = $this->db->list_tables();
345 }
Barry Mienydd671972010-10-04 16:33:58 +0200346
Derek Allard2067d1a2008-11-13 22:59:24 +0000347 // ------------------------------------------------------
348
349 // Validate the format
350 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
351 {
352 $prefs['format'] = 'txt';
353 }
354
355 // ------------------------------------------------------
356
Derek Jones37f4b9c2011-07-01 17:56:50 -0500357 // Is the encoder supported? If not, we'll either issue an
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 // error or use plain text depending on the debug settings
359 if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
Derek Jones37f4b9c2011-07-01 17:56:50 -0500360 OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 {
362 if ($this->db->db_debug)
363 {
364 return $this->db->display_error('db_unsuported_compression');
365 }
Barry Mienydd671972010-10-04 16:33:58 +0200366
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 $prefs['format'] = 'txt';
368 }
369
370 // ------------------------------------------------------
371
372 // Set the filename if not provided - Only needed with Zip files
373 if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
374 {
375 $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
376 $prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
377 }
378
379 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200380
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 // Was a Gzip file requested?
382 if ($prefs['format'] == 'gzip')
383 {
384 return gzencode($this->_backup($prefs));
385 }
386
387 // ------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200388
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 // Was a text file requested?
390 if ($prefs['format'] == 'txt')
391 {
392 return $this->_backup($prefs);
393 }
394
395 // ------------------------------------------------------
396
Barry Mienydd671972010-10-04 16:33:58 +0200397 // Was a Zip file requested?
Derek Allard2067d1a2008-11-13 22:59:24 +0000398 if ($prefs['format'] == 'zip')
399 {
400 // If they included the .zip file extension we'll remove it
401 if (preg_match("|.+?\.zip$|", $prefs['filename']))
402 {
403 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
404 }
Barry Mienydd671972010-10-04 16:33:58 +0200405
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 // Tack on the ".sql" file extension if needed
407 if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
408 {
409 $prefs['filename'] .= '.sql';
410 }
411
412 // Load the Zip class and output it
Barry Mienydd671972010-10-04 16:33:58 +0200413
Derek Allard2067d1a2008-11-13 22:59:24 +0000414 $CI =& get_instance();
415 $CI->load->library('zip');
Barry Mienydd671972010-10-04 16:33:58 +0200416 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
Derek Allard2067d1a2008-11-13 22:59:24 +0000417 return $CI->zip->get_zip();
418 }
Barry Mienydd671972010-10-04 16:33:58 +0200419
Derek Allard2067d1a2008-11-13 22:59:24 +0000420 }
421
422}
423
424
425/* End of file DB_utility.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000426/* Location: ./system/database/DB_utility.php */