blob: 42f08fbf63d52e394a9084f10718f245d2fd4569 [file] [log] [blame]
Derek Jonesf4a4bd82011-10-20 12:18:42 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Esen Sagynov2e087942011-08-09 23:35:01 -07002/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
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 *
Esen Sagynov2e087942011-08-09 23:35:01 -070019 * @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)
Esen Sagynov2e087942011-08-09 23:35:01 -070023 * @link http://codeigniter.com
24 * @since Version 2.0.2
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * CUBRID Database Adapter Class
32 *
33 * Note: _DB is an extender class that the app controller
34 * creates dynamically based on whether the active record
35 * class is being used or not.
36 *
37 * @package CodeIgniter
38 * @subpackage Drivers
39 * @category Database
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070040 * @author Esen Sagynov
Esen Sagynov2e087942011-08-09 23:35:01 -070041 * @link http://codeigniter.com/user_guide/database/
42 */
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070043class CI_DB_cubrid_driver extends CI_DB {
44
45 // Default CUBRID Broker port. Will be used unless user
46 // explicitly specifies another one.
47 const DEFAULT_PORT = 33000;
48
Esen Sagynov2e087942011-08-09 23:35:01 -070049 var $dbdriver = 'cubrid';
50
51 // The character used for escaping - no need in CUBRID
52 var $_escape_char = '';
53
54 // clause and character used for LIKE escape sequences - not used in CUBRID
55 var $_like_escape_str = '';
56 var $_like_escape_chr = '';
57
58 /**
59 * The syntax to count rows is slightly different across different
60 * database engines, so this string appears in each driver and is
61 * used for the count_all() and count_all_results() functions.
62 */
63 var $_count_string = 'SELECT COUNT(*) AS ';
64 var $_random_keyword = ' RAND()'; // database specific random keyword
65
66 /**
67 * Non-persistent database connection
68 *
69 * @access private called by the base class
70 * @return resource
71 */
72 function db_connect()
73 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070074 // If no port is defined by the user, use the default value
Esen Sagynov2e087942011-08-09 23:35:01 -070075 if ($this->port == '')
76 {
77 $this->port = self::DEFAULT_PORT;
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070078 }
Esen Sagynov2e087942011-08-09 23:35:01 -070079
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070080 $conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
Esen Sagynov2e087942011-08-09 23:35:01 -070081
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -070082 if ($conn)
83 {
84 // Check if a user wants to run queries in dry, i.e. run the
85 // queries but not commit them.
86 if (isset($this->auto_commit) && ! $this->auto_commit)
87 {
88 cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_FALSE);
89 }
90 else
91 {
92 cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_TRUE);
93 $this->auto_commit = TRUE;
94 }
95 }
96
97 return $conn;
Esen Sagynov2e087942011-08-09 23:35:01 -070098 }
99
100 // --------------------------------------------------------------------
101
102 /**
103 * Persistent database connection
104 * In CUBRID persistent DB connection is supported natively in CUBRID
105 * engine which can be configured in the CUBRID Broker configuration
106 * file by setting the CCI_PCONNECT parameter to ON. In that case, all
107 * connections established between the client application and the
108 * server will become persistent. This is calling the same
109 * @cubrid_connect function will establish persisten connection
110 * considering that the CCI_PCONNECT is ON.
111 *
112 * @access private called by the base class
113 * @return resource
114 */
115 function db_pconnect()
116 {
117 return $this->db_connect();
118 }
119
120 // --------------------------------------------------------------------
121
122 /**
123 * Reconnect
124 *
125 * Keep / reestablish the db connection if no queries have been
126 * sent for a length of time exceeding the server's idle timeout
127 *
128 * @access public
129 * @return void
130 */
131 function reconnect()
132 {
133 if (cubrid_ping($this->conn_id) === FALSE)
134 {
135 $this->conn_id = FALSE;
136 }
137 }
138
139 // --------------------------------------------------------------------
140
141 /**
142 * Select the database
143 *
144 * @access private called by the base class
145 * @return resource
146 */
147 function db_select()
148 {
149 // In CUBRID there is no need to select a database as the database
150 // is chosen at the connection time.
151 // So, to determine if the database is "selected", all we have to
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700152 // do is ping the server and return that value.
Esen Sagynov2e087942011-08-09 23:35:01 -0700153 return cubrid_ping($this->conn_id);
154 }
155
156 // --------------------------------------------------------------------
157
158 /**
Esen Sagynov2e087942011-08-09 23:35:01 -0700159 * Version number query string
160 *
161 * @access public
162 * @return string
163 */
164 function _version()
165 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700166 // To obtain the CUBRID Server version, no need to run the SQL query.
167 // CUBRID PHP API provides a function to determin this value.
168 // This is why we also need to add 'cubrid' value to the list of
169 // $driver_version_exceptions array in DB_driver class in
170 // version() function.
Esen Sagynov2e087942011-08-09 23:35:01 -0700171 return cubrid_get_server_info($this->conn_id);
172 }
173
174 // --------------------------------------------------------------------
175
176 /**
177 * Execute the query
178 *
179 * @access private called by the base class
180 * @param string an SQL query
181 * @return resource
182 */
183 function _execute($sql)
184 {
185 $sql = $this->_prep_query($sql);
186 return @cubrid_query($sql, $this->conn_id);
187 }
188
189 // --------------------------------------------------------------------
190
191 /**
192 * Prep the query
193 *
194 * If needed, each database adapter can prep the query string
195 *
196 * @access private called by execute()
197 * @param string an SQL query
198 * @return string
199 */
200 function _prep_query($sql)
201 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700202 // No need to prepare
Esen Sagynov2e087942011-08-09 23:35:01 -0700203 return $sql;
204 }
205
206 // --------------------------------------------------------------------
207
208 /**
209 * Begin Transaction
210 *
211 * @access public
212 * @return bool
213 */
214 function trans_begin($test_mode = FALSE)
215 {
216 if ( ! $this->trans_enabled)
217 {
218 return TRUE;
219 }
220
221 // When transactions are nested we only begin/commit/rollback the outermost ones
222 if ($this->_trans_depth > 0)
223 {
224 return TRUE;
225 }
226
227 // Reset the transaction failure flag.
228 // If the $test_mode flag is set to TRUE transactions will be rolled back
229 // even if the queries produce a successful result.
230 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
231
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700232 if (cubrid_get_autocommit($this->conn_id))
233 {
234 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
235 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700236
237 return TRUE;
238 }
239
240 // --------------------------------------------------------------------
241
242 /**
243 * Commit Transaction
244 *
245 * @access public
246 * @return bool
247 */
248 function trans_commit()
249 {
250 if ( ! $this->trans_enabled)
251 {
252 return TRUE;
253 }
254
255 // When transactions are nested we only begin/commit/rollback the outermost ones
256 if ($this->_trans_depth > 0)
257 {
258 return TRUE;
259 }
260
261 cubrid_commit($this->conn_id);
262
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700263 if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
264 {
265 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
266 }
267
Esen Sagynov2e087942011-08-09 23:35:01 -0700268 return TRUE;
269 }
270
271 // --------------------------------------------------------------------
272
273 /**
274 * Rollback Transaction
275 *
276 * @access public
277 * @return bool
278 */
279 function trans_rollback()
280 {
281 if ( ! $this->trans_enabled)
282 {
283 return TRUE;
284 }
285
286 // When transactions are nested we only begin/commit/rollback the outermost ones
287 if ($this->_trans_depth > 0)
288 {
289 return TRUE;
290 }
291
292 cubrid_rollback($this->conn_id);
293
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700294 if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
295 {
296 cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
297 }
298
Esen Sagynov2e087942011-08-09 23:35:01 -0700299 return TRUE;
300 }
301
302 // --------------------------------------------------------------------
303
304 /**
305 * Escape String
306 *
307 * @access public
308 * @param string
309 * @param bool whether or not the string will be used in a LIKE condition
310 * @return string
311 */
312 function escape_str($str, $like = FALSE)
313 {
314 if (is_array($str))
315 {
316 foreach ($str as $key => $val)
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700317 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700318 $str[$key] = $this->escape_str($val, $like);
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700319 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700320
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700321 return $str;
322 }
Esen Sagynov2e087942011-08-09 23:35:01 -0700323
324 if (function_exists('cubrid_real_escape_string') AND is_resource($this->conn_id))
325 {
326 $str = cubrid_real_escape_string($str, $this->conn_id);
327 }
328 else
329 {
330 $str = addslashes($str);
331 }
332
333 // escape LIKE condition wildcards
334 if ($like === TRUE)
335 {
Esen Sagynov2e087942011-08-09 23:35:01 -0700336 $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
337 }
338
339 return $str;
340 }
341
342 // --------------------------------------------------------------------
343
344 /**
345 * Affected Rows
346 *
Andrey Andreevea3eec92012-03-01 19:16:23 +0200347 * @return int
Esen Sagynov2e087942011-08-09 23:35:01 -0700348 */
Andrey Andreevea3eec92012-03-01 19:16:23 +0200349 public function affected_rows()
Esen Sagynov2e087942011-08-09 23:35:01 -0700350 {
Andrey Andreevea3eec92012-03-01 19:16:23 +0200351 return @cubrid_affected_rows();
Esen Sagynov2e087942011-08-09 23:35:01 -0700352 }
353
354 // --------------------------------------------------------------------
355
356 /**
357 * Insert ID
358 *
359 * @access public
360 * @return integer
361 */
362 function insert_id()
363 {
364 return @cubrid_insert_id($this->conn_id);
365 }
366
367 // --------------------------------------------------------------------
368
369 /**
370 * "Count All" query
371 *
372 * Generates a platform-specific query string that counts all records in
373 * the specified table
374 *
375 * @access public
376 * @param string
377 * @return string
378 */
379 function count_all($table = '')
380 {
381 if ($table == '')
382 {
383 return 0;
384 }
385
386 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
387
388 if ($query->num_rows() == 0)
389 {
390 return 0;
391 }
392
393 $row = $query->row();
Greg Aker90248ab2011-08-20 14:23:14 -0500394 $this->_reset_select();
Esen Sagynov2e087942011-08-09 23:35:01 -0700395 return (int) $row->numrows;
396 }
397
398 // --------------------------------------------------------------------
399
400 /**
401 * List table query
402 *
403 * Generates a platform-specific query string so that the table names can be fetched
404 *
405 * @access private
406 * @param boolean
407 * @return string
408 */
409 function _list_tables($prefix_limit = FALSE)
410 {
411 $sql = "SHOW TABLES";
412
413 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
414 {
415 $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
416 }
417
418 return $sql;
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Show column query
425 *
426 * Generates a platform-specific query string so that the column names can be fetched
427 *
428 * @access public
429 * @param string the table name
430 * @return string
431 */
432 function _list_columns($table = '')
433 {
434 return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
435 }
436
437 // --------------------------------------------------------------------
438
439 /**
440 * Field data query
441 *
442 * Generates a platform-specific query so that the column data can be retrieved
443 *
444 * @access public
445 * @param string the table name
446 * @return object
447 */
448 function _field_data($table)
449 {
450 return "SELECT * FROM ".$table." LIMIT 1";
451 }
452
453 // --------------------------------------------------------------------
454
455 /**
456 * The error message string
457 *
458 * @access private
459 * @return string
460 */
461 function _error_message()
462 {
463 return cubrid_error($this->conn_id);
464 }
465
466 // --------------------------------------------------------------------
467
468 /**
469 * The error message number
470 *
471 * @access private
472 * @return integer
473 */
474 function _error_number()
475 {
476 return cubrid_errno($this->conn_id);
477 }
478
479 // --------------------------------------------------------------------
480
481 /**
482 * Escape the SQL Identifiers
483 *
484 * This function escapes column and table names
485 *
486 * @access private
487 * @param string
488 * @return string
489 */
490 function _escape_identifiers($item)
491 {
492 if ($this->_escape_char == '')
493 {
494 return $item;
495 }
496
497 foreach ($this->_reserved_identifiers as $id)
498 {
499 if (strpos($item, '.'.$id) !== FALSE)
500 {
501 $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
502
503 // remove duplicates if the user already included the escape
504 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
505 }
506 }
507
508 if (strpos($item, '.') !== FALSE)
509 {
510 $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
511 }
512 else
513 {
514 $str = $this->_escape_char.$item.$this->_escape_char;
515 }
516
517 // remove duplicates if the user already included the escape
518 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
519 }
520
521 // --------------------------------------------------------------------
522
523 /**
524 * From Tables
525 *
526 * This function implicitly groups FROM tables so there is no confusion
527 * about operator precedence in harmony with SQL standards
528 *
529 * @access public
530 * @param type
531 * @return type
532 */
533 function _from_tables($tables)
534 {
535 if ( ! is_array($tables))
536 {
537 $tables = array($tables);
538 }
539
540 return '('.implode(', ', $tables).')';
541 }
542
543 // --------------------------------------------------------------------
544
545 /**
546 * Insert statement
547 *
548 * Generates a platform-specific insert string from the supplied data
549 *
550 * @access public
551 * @param string the table name
552 * @param array the insert keys
553 * @param array the insert values
554 * @return string
555 */
556 function _insert($table, $keys, $values)
557 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700558 return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
Esen Sagynov2e087942011-08-09 23:35:01 -0700559 }
560
561 // --------------------------------------------------------------------
562
563
564 /**
565 * Replace statement
566 *
567 * Generates a platform-specific replace string from the supplied data
568 *
569 * @access public
570 * @param string the table name
571 * @param array the insert keys
572 * @param array the insert values
573 * @return string
574 */
575 function _replace($table, $keys, $values)
576 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700577 return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
Esen Sagynov2e087942011-08-09 23:35:01 -0700578 }
579
580 // --------------------------------------------------------------------
581
582 /**
583 * Insert_batch statement
584 *
585 * Generates a platform-specific insert string from the supplied data
586 *
587 * @access public
588 * @param string the table name
589 * @param array the insert keys
590 * @param array the insert values
591 * @return string
592 */
593 function _insert_batch($table, $keys, $values)
594 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700595 return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
Esen Sagynov2e087942011-08-09 23:35:01 -0700596 }
597
598 // --------------------------------------------------------------------
599
600
601 /**
602 * Update statement
603 *
604 * Generates a platform-specific update string from the supplied data
605 *
606 * @access public
607 * @param string the table name
608 * @param array the update data
609 * @param array the where clause
610 * @param array the orderby clause
611 * @param array the limit clause
612 * @return string
613 */
614 function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
615 {
616 foreach ($values as $key => $val)
617 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700618 $valstr[] = sprintf('"%s" = %s', $key, $val);
Esen Sagynov2e087942011-08-09 23:35:01 -0700619 }
620
621 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
622
623 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
624
625 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
626
627 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
628
629 $sql .= $orderby.$limit;
630
631 return $sql;
632 }
633
634 // --------------------------------------------------------------------
635
636
637 /**
638 * Update_Batch statement
639 *
640 * Generates a platform-specific batch update string from the supplied data
641 *
642 * @access public
643 * @param string the table name
644 * @param array the update data
645 * @param array the where clause
646 * @return string
647 */
648 function _update_batch($table, $values, $index, $where = NULL)
649 {
650 $ids = array();
651 $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
652
653 foreach ($values as $key => $val)
654 {
655 $ids[] = $val[$index];
656
657 foreach (array_keys($val) as $field)
658 {
659 if ($field != $index)
660 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700661 $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
Esen Sagynov2e087942011-08-09 23:35:01 -0700662 }
663 }
664 }
665
666 $sql = "UPDATE ".$table." SET ";
667 $cases = '';
668
669 foreach ($final as $k => $v)
670 {
671 $cases .= $k.' = CASE '."\n";
672 foreach ($v as $row)
673 {
674 $cases .= $row."\n";
675 }
676
677 $cases .= 'ELSE '.$k.' END, ';
678 }
679
680 $sql .= substr($cases, 0, -2);
681
682 $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
683
684 return $sql;
685 }
686
687 // --------------------------------------------------------------------
688
689
690 /**
691 * Truncate statement
692 *
693 * Generates a platform-specific truncate string from the supplied data
694 * If the database does not support the truncate() command
695 * This function maps to "DELETE FROM table"
696 *
697 * @access public
698 * @param string the table name
699 * @return string
700 */
701 function _truncate($table)
702 {
703 return "TRUNCATE ".$table;
704 }
705
706 // --------------------------------------------------------------------
707
708 /**
709 * Delete statement
710 *
711 * Generates a platform-specific delete string from the supplied data
712 *
713 * @access public
714 * @param string the table name
715 * @param array the where clause
716 * @param string the limit clause
717 * @return string
718 */
719 function _delete($table, $where = array(), $like = array(), $limit = FALSE)
720 {
721 $conditions = '';
722
723 if (count($where) > 0 OR count($like) > 0)
724 {
725 $conditions = "\nWHERE ";
726 $conditions .= implode("\n", $this->ar_where);
727
728 if (count($where) > 0 && count($like) > 0)
729 {
730 $conditions .= " AND ";
731 }
732 $conditions .= implode("\n", $like);
733 }
734
735 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
736
737 return "DELETE FROM ".$table.$conditions.$limit;
738 }
739
740 // --------------------------------------------------------------------
741
742 /**
743 * Limit string
744 *
745 * Generates a platform-specific LIMIT clause
746 *
747 * @access public
748 * @param string the sql query string
749 * @param integer the number of rows to limit the query to
750 * @param integer the offset value
751 * @return string
752 */
753 function _limit($sql, $limit, $offset)
754 {
755 if ($offset == 0)
756 {
757 $offset = '';
758 }
759 else
760 {
761 $offset .= ", ";
762 }
763
764 return $sql."LIMIT ".$offset.$limit;
765 }
766
767 // --------------------------------------------------------------------
768
769 /**
770 * Close DB Connection
771 *
772 * @access public
773 * @param resource
774 * @return void
775 */
776 function _close($conn_id)
777 {
778 @cubrid_close($conn_id);
779 }
780
781}
782
783
784/* End of file cubrid_driver.php */
Andrey Andreev063f5962012-02-27 12:20:52 +0200785/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */