blob: a589ded0ce2bc833a567503af400b48900802e1b [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 *
347 * @access public
348 * @return integer
349 */
350 function affected_rows()
351 {
352 return @cubrid_affected_rows($this->conn_id);
353 }
354
355 // --------------------------------------------------------------------
356
357 /**
358 * Insert ID
359 *
360 * @access public
361 * @return integer
362 */
363 function insert_id()
364 {
365 return @cubrid_insert_id($this->conn_id);
366 }
367
368 // --------------------------------------------------------------------
369
370 /**
371 * "Count All" query
372 *
373 * Generates a platform-specific query string that counts all records in
374 * the specified table
375 *
376 * @access public
377 * @param string
378 * @return string
379 */
380 function count_all($table = '')
381 {
382 if ($table == '')
383 {
384 return 0;
385 }
386
387 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
388
389 if ($query->num_rows() == 0)
390 {
391 return 0;
392 }
393
394 $row = $query->row();
Greg Aker90248ab2011-08-20 14:23:14 -0500395 $this->_reset_select();
Esen Sagynov2e087942011-08-09 23:35:01 -0700396 return (int) $row->numrows;
397 }
398
399 // --------------------------------------------------------------------
400
401 /**
402 * List table query
403 *
404 * Generates a platform-specific query string so that the table names can be fetched
405 *
406 * @access private
407 * @param boolean
408 * @return string
409 */
410 function _list_tables($prefix_limit = FALSE)
411 {
412 $sql = "SHOW TABLES";
413
414 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
415 {
416 $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
417 }
418
419 return $sql;
420 }
421
422 // --------------------------------------------------------------------
423
424 /**
425 * Show column query
426 *
427 * Generates a platform-specific query string so that the column names can be fetched
428 *
429 * @access public
430 * @param string the table name
431 * @return string
432 */
433 function _list_columns($table = '')
434 {
435 return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
436 }
437
438 // --------------------------------------------------------------------
439
440 /**
441 * Field data query
442 *
443 * Generates a platform-specific query so that the column data can be retrieved
444 *
445 * @access public
446 * @param string the table name
447 * @return object
448 */
449 function _field_data($table)
450 {
451 return "SELECT * FROM ".$table." LIMIT 1";
452 }
453
454 // --------------------------------------------------------------------
455
456 /**
457 * The error message string
458 *
459 * @access private
460 * @return string
461 */
462 function _error_message()
463 {
464 return cubrid_error($this->conn_id);
465 }
466
467 // --------------------------------------------------------------------
468
469 /**
470 * The error message number
471 *
472 * @access private
473 * @return integer
474 */
475 function _error_number()
476 {
477 return cubrid_errno($this->conn_id);
478 }
479
480 // --------------------------------------------------------------------
481
482 /**
483 * Escape the SQL Identifiers
484 *
485 * This function escapes column and table names
486 *
487 * @access private
488 * @param string
489 * @return string
490 */
491 function _escape_identifiers($item)
492 {
493 if ($this->_escape_char == '')
494 {
495 return $item;
496 }
497
498 foreach ($this->_reserved_identifiers as $id)
499 {
500 if (strpos($item, '.'.$id) !== FALSE)
501 {
502 $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
503
504 // remove duplicates if the user already included the escape
505 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
506 }
507 }
508
509 if (strpos($item, '.') !== FALSE)
510 {
511 $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
512 }
513 else
514 {
515 $str = $this->_escape_char.$item.$this->_escape_char;
516 }
517
518 // remove duplicates if the user already included the escape
519 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
520 }
521
522 // --------------------------------------------------------------------
523
524 /**
525 * From Tables
526 *
527 * This function implicitly groups FROM tables so there is no confusion
528 * about operator precedence in harmony with SQL standards
529 *
530 * @access public
531 * @param type
532 * @return type
533 */
534 function _from_tables($tables)
535 {
536 if ( ! is_array($tables))
537 {
538 $tables = array($tables);
539 }
540
541 return '('.implode(', ', $tables).')';
542 }
543
544 // --------------------------------------------------------------------
545
546 /**
547 * Insert statement
548 *
549 * Generates a platform-specific insert string from the supplied data
550 *
551 * @access public
552 * @param string the table name
553 * @param array the insert keys
554 * @param array the insert values
555 * @return string
556 */
557 function _insert($table, $keys, $values)
558 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700559 return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
Esen Sagynov2e087942011-08-09 23:35:01 -0700560 }
561
562 // --------------------------------------------------------------------
563
564
565 /**
566 * Replace statement
567 *
568 * Generates a platform-specific replace string from the supplied data
569 *
570 * @access public
571 * @param string the table name
572 * @param array the insert keys
573 * @param array the insert values
574 * @return string
575 */
576 function _replace($table, $keys, $values)
577 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700578 return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
Esen Sagynov2e087942011-08-09 23:35:01 -0700579 }
580
581 // --------------------------------------------------------------------
582
583 /**
584 * Insert_batch statement
585 *
586 * Generates a platform-specific insert string from the supplied data
587 *
588 * @access public
589 * @param string the table name
590 * @param array the insert keys
591 * @param array the insert values
592 * @return string
593 */
594 function _insert_batch($table, $keys, $values)
595 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700596 return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
Esen Sagynov2e087942011-08-09 23:35:01 -0700597 }
598
599 // --------------------------------------------------------------------
600
601
602 /**
603 * Update statement
604 *
605 * Generates a platform-specific update string from the supplied data
606 *
607 * @access public
608 * @param string the table name
609 * @param array the update data
610 * @param array the where clause
611 * @param array the orderby clause
612 * @param array the limit clause
613 * @return string
614 */
615 function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
616 {
617 foreach ($values as $key => $val)
618 {
Esen Sagynovee3e5942011-08-10 03:22:58 -0700619 $valstr[] = sprintf('"%s" = %s', $key, $val);
Esen Sagynov2e087942011-08-09 23:35:01 -0700620 }
621
622 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
623
624 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
625
626 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
627
628 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
629
630 $sql .= $orderby.$limit;
631
632 return $sql;
633 }
634
635 // --------------------------------------------------------------------
636
637
638 /**
639 * Update_Batch statement
640 *
641 * Generates a platform-specific batch update string from the supplied data
642 *
643 * @access public
644 * @param string the table name
645 * @param array the update data
646 * @param array the where clause
647 * @return string
648 */
649 function _update_batch($table, $values, $index, $where = NULL)
650 {
651 $ids = array();
652 $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
653
654 foreach ($values as $key => $val)
655 {
656 $ids[] = $val[$index];
657
658 foreach (array_keys($val) as $field)
659 {
660 if ($field != $index)
661 {
Esen Sagynov2ab2b1e2011-08-11 00:41:16 -0700662 $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
Esen Sagynov2e087942011-08-09 23:35:01 -0700663 }
664 }
665 }
666
667 $sql = "UPDATE ".$table." SET ";
668 $cases = '';
669
670 foreach ($final as $k => $v)
671 {
672 $cases .= $k.' = CASE '."\n";
673 foreach ($v as $row)
674 {
675 $cases .= $row."\n";
676 }
677
678 $cases .= 'ELSE '.$k.' END, ';
679 }
680
681 $sql .= substr($cases, 0, -2);
682
683 $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
684
685 return $sql;
686 }
687
688 // --------------------------------------------------------------------
689
690
691 /**
692 * Truncate statement
693 *
694 * Generates a platform-specific truncate string from the supplied data
695 * If the database does not support the truncate() command
696 * This function maps to "DELETE FROM table"
697 *
698 * @access public
699 * @param string the table name
700 * @return string
701 */
702 function _truncate($table)
703 {
704 return "TRUNCATE ".$table;
705 }
706
707 // --------------------------------------------------------------------
708
709 /**
710 * Delete statement
711 *
712 * Generates a platform-specific delete string from the supplied data
713 *
714 * @access public
715 * @param string the table name
716 * @param array the where clause
717 * @param string the limit clause
718 * @return string
719 */
720 function _delete($table, $where = array(), $like = array(), $limit = FALSE)
721 {
722 $conditions = '';
723
724 if (count($where) > 0 OR count($like) > 0)
725 {
726 $conditions = "\nWHERE ";
727 $conditions .= implode("\n", $this->ar_where);
728
729 if (count($where) > 0 && count($like) > 0)
730 {
731 $conditions .= " AND ";
732 }
733 $conditions .= implode("\n", $like);
734 }
735
736 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
737
738 return "DELETE FROM ".$table.$conditions.$limit;
739 }
740
741 // --------------------------------------------------------------------
742
743 /**
744 * Limit string
745 *
746 * Generates a platform-specific LIMIT clause
747 *
748 * @access public
749 * @param string the sql query string
750 * @param integer the number of rows to limit the query to
751 * @param integer the offset value
752 * @return string
753 */
754 function _limit($sql, $limit, $offset)
755 {
756 if ($offset == 0)
757 {
758 $offset = '';
759 }
760 else
761 {
762 $offset .= ", ";
763 }
764
765 return $sql."LIMIT ".$offset.$limit;
766 }
767
768 // --------------------------------------------------------------------
769
770 /**
771 * Close DB Connection
772 *
773 * @access public
774 * @param resource
775 * @return void
776 */
777 function _close($conn_id)
778 {
779 @cubrid_close($conn_id);
780 }
781
782}
783
784
785/* End of file cubrid_driver.php */
Andrey Andreev063f5962012-02-27 12:20:52 +0200786/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */