blob: 8ce19b17f54b61897555542802f949b491ec3d80 [file] [log] [blame]
Derek Allardd2df9bc2007-04-15 17:41:17 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, EllisLab, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Database Utility Class
20 *
21 * @category Database
22 * @author Rick Ellis
23 * @link http://www.codeigniter.com/user_guide/database/
24 */
25class CI_DB_utility {
26
27 var $db;
28 var $data_cache = array();
29
30 /**
31 * Constructor
32 *
33 * Grabs the CI super object instance so we can access it.
34 *
35 */
36 function CI_DB_utility()
37 {
38 // Assign the main database object to $this->db
39 $CI =& get_instance();
40 $this->db =& $CI->db;
41
42 log_message('debug', "Database Utility Class Initialized");
43 }
44
45 // --------------------------------------------------------------------
46
47 /**
48 * Create database
49 *
50 * @access public
51 * @param string the database name
52 * @return bool
53 */
54 function create_database($db_name)
55 {
56 $sql = $this->_create_database($db_name);
57
58 if (is_bool($sql))
59 {
60 return $sql;
61 }
62
63 return $this->db->query($sql);
64 }
65
66 // --------------------------------------------------------------------
67
68 /**
69 * Drop database
70 *
71 * @access public
72 * @param string the database name
73 * @return bool
74 */
75 function drop_database($db_name)
76 {
77 $sql = $this->_drop_database($db_name);
78
79 if (is_bool($sql))
80 {
81 return $sql;
82 }
83
84 return $this->db->query($sql);
85 }
86
87 // --------------------------------------------------------------------
88
89 /**
90 * List databases
91 *
92 * @access public
93 * @return bool
94 */
95 function list_databases()
96 {
97 // Is there a cached result?
98 if (isset($this->data_cache['db_names']))
99 {
100 return $this->data_cache['db_names'];
101 }
102
103 $query = $this->db->query($this->_list_databases());
104 $dbs = array();
105 if ($query->num_rows() > 0)
106 {
107 foreach ($query->result_array() as $row)
108 {
109 $dbs[] = current($row);
110 }
111 }
112
113 $this->data_cache['db_names'] = $dbs;
114 return $this->data_cache['db_names'];
115 }
116
117 // --------------------------------------------------------------------
118
119 /**
120 * Optimize Table
121 *
122 * @access public
123 * @param string the table name
124 * @return bool
125 */
126 function optimize_table($table_name)
127 {
128 $sql = $this->_optimize_table($table_name);
129
130 if (is_bool($sql))
131 {
132 return $sql;
133 }
134
135 $query = $this->db->query($sql);
136 $res = $query->result_array();
137
138 // Note: Due to a bug in current() that affects some versions
139 // of PHP we can not pass function call directly into it
140 return current($res);
141 }
142
143 // --------------------------------------------------------------------
144
145 /**
146 * Optimize Database
147 *
148 * @access public
149 * @return array
150 */
151 function optimize_database()
152 {
153 $result = array();
154 foreach ($this->db->list_tables() as $table_name)
155 {
156 $sql = $this->_optimize_table($table_name);
157
158 if (is_bool($sql))
159 {
160 return $sql;
161 }
162
163 $query = $this->db->query($sql);
164
165 // Build the result array...
166 // Note: Due to a bug in current() that affects some versions
167 // of PHP we can not pass function call directly into it
168 $res = $query->result_array();
169 $res = current($res);
170 $key = str_replace($this->db->database.'.', '', current($res));
171 $keys = array_keys($res);
172 unset($res[$keys[0]]);
173
174 $result[$key] = $res;
175 }
176
177 return $result;
178 }
179
180 // --------------------------------------------------------------------
181
182 /**
183 * Optimize Table
184 *
185 * @access public
186 * @param string the table name
187 * @return bool
188 */
189
190 function repair_table($table_name)
191 {
192 $sql = $this->_repair_table($table_name);
193
194 if (is_bool($sql))
195 {
196 return $sql;
197 }
198
199 $query = $this->db->query($sql);
200
201 // Note: Due to a bug in current() that affects some versions
202 // of PHP we can not pass function call directly into it
203 $res = $query->result_array();
204 return current($res);
205 }
206
207 // --------------------------------------------------------------------
208
209 /**
210 * Drop Table
211 *
212 * @access public
213 * @param string the table name
214 * @return bool
215 */
216 function drop_table($table_name)
217 {
218 $sql = $this->_drop_table($table_name);
219
220 if (is_bool($sql))
221 {
222 return $sql;
223 }
224
225 return $this->db->query($sql);
226 }
227
228 // --------------------------------------------------------------------
229
230 /**
231 * Generate CSV from a query result object
232 *
233 * @access public
234 * @param object The query result object
235 * @param string The delimiter - tab by default
236 * @param string The newline character - \n by default
237 * @return string
238 */
Derek Allard7dcd7a32007-07-12 12:36:50 +0000239 function csv_from_result($query, $delim = ',', $newline = '', $enclosure = '"')
Derek Allardd2df9bc2007-04-15 17:41:17 +0000240 {
Derek Allard7dcd7a32007-07-12 12:36:50 +0000241 if (!is_a($query, 'CI_DB_result')) {
242 show_error('CI_DB_utility::csv_from_result - You must submit a valid result object');
243 }
244
245 if ($delim === '') {
246 show_error('CI_DB_utility::csv_from_result - Empty delimiters are not permitted');
247 }
248
249 if ($newline === '') {
250 $newline = (stripos(getenv('HTTP_USER_AGENT'), 'win') !== false) ? "\r\n" : "\n";
251 }
Derek Allardd2df9bc2007-04-15 17:41:17 +0000252
Derek Allard7dcd7a32007-07-12 12:36:50 +0000253 if ((strpos($enclosure, $newline) !== false) or (($enclosure !== '') and (strpos($newline, $enclosure) !== false))) {
254 show_error('CI_DB_utility::csv_from_result - Field enclosure must not be contained within delimiter (or vice versa)');
255 }
256
Derek Allardd2df9bc2007-04-15 17:41:17 +0000257 $out = '';
258
259 // First generate the headings from the table column names
Derek Allard7dcd7a32007-07-12 12:36:50 +0000260 foreach ($query->list_fields() as $name) {
261 // there's no point enclosing strings that do not require it
262 if (strpos($name, $delim) !== false) {
263 $out .= $enclosure . $name . $enclosure . $delim;
264 } else {
265 $out .= $name . $delim;
Derek Allardd2df9bc2007-04-15 17:41:17 +0000266 }
Derek Allardd2df9bc2007-04-15 17:41:17 +0000267 }
Derek Allard7dcd7a32007-07-12 12:36:50 +0000268
269 $out = rtrim($out, $delim) . $newline;
270
271 // Next blast through the result array and build out the rows
272 foreach ($query->result_array() as $row) {
273 foreach ($row as $item) {
274 // there's no point enclosing strings that do not require it
275 if (strpos($item, $delim) !== false) {
276 $out .= $enclosure . $item . $enclosure . $delim;
277 } else {
278 $out .= $item . $delim;
279 }
280 }
281 $out = rtrim($out, $delim) . $newline;
282 }
283
Derek Allardd2df9bc2007-04-15 17:41:17 +0000284 return $out;
285 }
286
287 // --------------------------------------------------------------------
288
289 /**
290 * Generate XML data from a query result object
291 *
292 * @access public
293 * @param object The query result object
294 * @param array Any preferences
295 * @return string
296 */
297 function xml_from_result($query, $params = array())
298 {
299 if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
300 {
301 show_error('You must submit a valid result object');
302 }
303
304 // Set our default values
305 foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
306 {
307 if ( ! isset($params[$key]))
308 {
309 $params[$key] = $val;
310 }
311 }
312
313 // Create variables for convenience
314 extract($params);
315
316 // Load the xml helper
317 $CI =& get_instance();
318 $CI->load->helper('xml');
319
320 // Generate the result
321 $xml = "<{$root}>".$newline;
322 foreach ($query->result_array() as $row)
323 {
324 $xml .= $tab."<{$element}>".$newline;
325
326 foreach ($row as $key => $val)
327 {
328 $xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
329 }
330 $xml .= $tab."</{$element}>".$newline;
331 }
332 $xml .= "</$root>".$newline;
333
334 return $xml;
335 }
336
337 // --------------------------------------------------------------------
338
339 /**
340 * Database Backup
341 *
342 * @access public
343 * @return void
344 */
345 function backup($params = array())
346 {
347 // If the parameters have not been submitted as an
348 // array then we know that it is simply the table
349 // name, which is a valid short cut.
350 if (is_string($params))
351 {
352 $params = array('tables' => $params);
353 }
354
355 // ------------------------------------------------------
356
357 // Set up our default preferences
358 $prefs = array(
359 'tables' => array(),
360 'ignore' => array(),
361 'filename' => '',
362 'format' => 'gzip', // gzip, zip, txt
363 'add_drop' => TRUE,
364 'add_insert' => TRUE,
365 'newline' => "\n"
366 );
367
368 // Did the user submit any preferences? If so set them....
369 if (count($params) > 0)
370 {
371 foreach ($prefs as $key => $val)
372 {
373 if (isset($params[$key]))
374 {
375 $prefs[$key] = $params[$key];
376 }
377 }
378 }
379
380 // ------------------------------------------------------
381
382 // Are we backing up a complete database or individual tables?
383 // If no table names were submitted we'll fetch the entire table list
384 if (count($prefs['tables']) == 0)
385 {
386 $prefs['tables'] = $this->db->list_tables();
387 }
388
389 // ------------------------------------------------------
390
391 // Validate the format
392 if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
393 {
394 $prefs['format'] = 'txt';
395 }
396
397 // ------------------------------------------------------
398
399 // Is the encoder supported? If not, we'll either issue an
400 // error or use plain text depending on the debug settings
401 if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
402 OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
403 {
404 if ($this->db->db_debug)
405 {
406 return $this->db->display_error('db_unsuported_compression');
407 }
408
409 $prefs['format'] = 'txt';
410 }
411
412 // ------------------------------------------------------
413
414 // Set the filename if not provided - Only needed with Zip files
415 if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
416 {
417 $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
418 $prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
419 }
420
421 // ------------------------------------------------------
422
423 // Was a Gzip file requested?
424 if ($prefs['format'] == 'gzip')
425 {
426 return gzencode($this->_backup($prefs));
427 }
428
429 // ------------------------------------------------------
430
431 // Was a text file requested?
432 if ($prefs['format'] == 'txt')
433 {
434 return $this->_backup($prefs);
435 }
436
437 // ------------------------------------------------------
438
439 // Was a Zip file requested?
440 if ($prefs['format'] == 'zip')
441 {
442 // If they included the .zip file extension we'll remove it
443 if (preg_match("|.+?\.zip$|", $prefs['filename']))
444 {
445 $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
446 }
447
448 // Tack on the ".sql" file extension if needed
449 if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
450 {
451 $prefs['filename'] .= '.sql';
452 }
453
454 // Load the Zip class and output it
455
456 $CI =& get_instance();
457 $CI->load->library('zip');
458 $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
459 return $CI->zip->get_zip();
460 }
461
462 }
463
464
465
466
467
468
469}
470
admin7b613c72006-09-24 18:05:17 +0000471?>