summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rw-r--r--composer.json5
-rwxr-xr-xsystem/core/Lang.php4
-rwxr-xr-xsystem/database/DB.php9
-rw-r--r--system/database/DB_driver.php17
-rw-r--r--system/database/DB_query_builder.php43
-rw-r--r--system/database/DB_result.php16
-rw-r--r--system/database/DB_utility.php4
-rw-r--r--system/database/drivers/mysql/mysql_driver.php6
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php6
-rw-r--r--system/database/drivers/oci8/oci8_result.php16
-rw-r--r--system/database/drivers/pdo/pdo_driver.php6
-rw-r--r--system/database/drivers/postgre/postgre_driver.php41
-rw-r--r--system/database/drivers/sqlite3/sqlite3_result.php16
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php10
-rw-r--r--system/libraries/Upload.php2
-rw-r--r--tests/Bootstrap.php19
-rw-r--r--tests/codeigniter/database/DB_driver_test.php4
-rw-r--r--tests/codeigniter/database/DB_test.php4
-rw-r--r--tests/codeigniter/database/query_builder/escape_test.php54
-rwxr-xr-xtests/mocks/database/ci_test.sqlitebin19456 -> 19456 bytes
-rw-r--r--tests/mocks/database/schema/skeleton.php21
-rw-r--r--user_guide_src/source/changelog.rst14
23 files changed, 226 insertions, 99 deletions
diff --git a/.travis.yml b/.travis.yml
index 97ea0422d..6a7d37812 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,9 +13,8 @@ env:
- DB=pdo/sqlite
before_script:
- - pyrus channel-discover pear.php-tools.net
- - pyrus install http://pear.php-tools.net/get/vfsStream-0.11.2.tgz
- - phpenv rehash
+ - curl -s http://getcomposer.org/installer | php
+ - php composer.phar install
- sh -c "if [ '$DB' = 'pgsql' ] || [ '$DB' = 'pdo/pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS ci_test;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ] || [ '$DB' = 'pdo/pgsql' ]; then psql -c 'create database ci_test;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ] || [ '$DB' = 'pdo/mysql' ]; then mysql -e 'create database IF NOT EXISTS ci_test;'; fi"
@@ -24,5 +23,4 @@ script: phpunit --configuration tests/travis/$DB.phpunit.xml
branches:
only:
- - develop
- - master \ No newline at end of file
+ - develop \ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 000000000..fa6dc02e4
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "mikey179/vfsStream": "*"
+ }
+} \ No newline at end of file
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 5cb0cad71..73c9127ac 100755
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -65,14 +65,14 @@ class CI_Lang {
/**
* Load a language file
*
- * @param mixed the name of the language file to be loaded. Can be an array
+ * @param mixed the name of the language file to be loaded
* @param string the language (english, etc.)
* @param bool return loaded array of translations
* @param bool add suffix to $langfile
* @param string alternative path to look for language file
* @return mixed
*/
- public function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
+ public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
{
$langfile = str_replace('.php', '', $langfile);
diff --git a/system/database/DB.php b/system/database/DB.php
index b28439b29..1fe44c0e5 100755
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -118,6 +118,13 @@ function &DB($params = '', $query_builder_override = NULL)
{
$query_builder = $query_builder_override;
}
+ // Backwards compatibility work-around for keeping the
+ // $active_record config variable working. Should be
+ // removed in v3.1
+ elseif ( ! isset($query_builder) && isset($active_record))
+ {
+ $query_builder = $active_record;
+ }
require_once(BASEPATH.'database/DB_driver.php');
@@ -159,4 +166,4 @@ function &DB($params = '', $query_builder_override = NULL)
}
/* End of file DB.php */
-/* Location: ./system/database/DB.php */
+/* Location: ./system/database/DB.php */ \ No newline at end of file
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index a0812d4c7..d8a1c13f0 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -1404,23 +1404,6 @@ abstract class CI_DB_driver {
{
}
- // --------------------------------------------------------------------
-
- /**
- * Destructor
- *
- * Closes the database connection, if needed.
- *
- * @return void
- */
- public function __destruct()
- {
- if ( ! $this->pconnect)
- {
- $this->close();
- }
- }
-
}
/* End of file DB_driver.php */
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index d0af66de1..cee4354e9 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -211,8 +211,8 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$alias = $this->_create_alias_from_table(trim($select));
}
- $sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->protect_identifiers(trim($alias));
-
+ $sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->escape_identifiers(trim($alias));
+
$this->qb_select[] = $sql;
$this->qb_no_escape[] = NULL;
@@ -256,7 +256,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*/
public function distinct($val = TRUE)
{
- $this->qb_distinct = (is_bool($val)) ? $val : TRUE;
+ $this->qb_distinct = is_bool($val) ? $val : TRUE;
return $this;
}
@@ -272,7 +272,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*/
public function from($from)
{
- foreach ((array)$from as $val)
+ foreach ((array) $from as $val)
{
if (strpos($val, ',') !== FALSE)
{
@@ -1111,6 +1111,8 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
return $result;
}
+ // --------------------------------------------------------------------
+
/**
* "Count All Results" query
*
@@ -1139,6 +1141,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$row = $result->row();
return (int) $row->numrows;
}
+
// --------------------------------------------------------------------
/**
@@ -1401,16 +1404,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
- if ($table == '')
+ if ($table != '')
{
- if ( ! isset($this->qb_from[0]))
- {
- return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
- }
+ $this->qb_from[0] = $table;
}
- else
+ elseif ( ! isset($this->qb_from[0]))
{
- $this->qb_from[0] = $table;
+ return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
}
return TRUE;
@@ -1600,16 +1600,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
- if ($table == '')
+ if ($table != '')
{
- if ( ! isset($this->qb_from[0]))
- {
- return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
- }
+ $this->qb_from[0] = $table;
}
- else
+ elseif ( ! isset($this->qb_from[0]))
{
- $this->qb_from[0] = $table;
+ return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
}
return TRUE;
@@ -1696,15 +1693,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
$index_set = TRUE;
}
- else
- {
- $not[] = $k.'-'.$v;
- }
$clean[$this->protect_identifiers($k2)] = ($escape === FALSE) ? $v2 : $this->escape($v2);
}
- if ($index_set == FALSE)
+ if ($index_set === FALSE)
{
return $this->display_error('db_batch_missing_index');
}
@@ -2102,7 +2095,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param object
* @return array
*/
- public function _object_to_array($object)
+ protected function _object_to_array($object)
{
if ( ! is_object($object))
{
@@ -2132,7 +2125,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param object
* @return array
*/
- public function _object_to_array_batch($object)
+ protected function _object_to_array_batch($object)
{
if ( ! is_object($object))
{
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index 690734b08..334e08c72 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -242,7 +242,7 @@ class CI_DB_result {
$result = $this->custom_result_object($type);
if (count($result) === 0)
{
- return $result;
+ return NULL;
}
if ($n != $this->current_row && isset($result[$n]))
@@ -253,6 +253,8 @@ class CI_DB_result {
return $result[$this->current_row];
}
+ // --------------------------------------------------------------------
+
/**
* Returns a single result row - object version
*
@@ -263,7 +265,7 @@ class CI_DB_result {
$result = $this->result_object();
if (count($result) === 0)
{
- return $result;
+ return NULL;
}
if ($n != $this->current_row && isset($result[$n]))
@@ -286,7 +288,7 @@ class CI_DB_result {
$result = $this->result_array();
if (count($result) === 0)
{
- return $result;
+ return NULL;
}
if ($n != $this->current_row && isset($result[$n]))
@@ -307,7 +309,7 @@ class CI_DB_result {
public function first_row($type = 'object')
{
$result = $this->result($type);
- return (count($result) === 0) ? $result : $result[0];
+ return (count($result) === 0) ? NULL : $result[0];
}
// --------------------------------------------------------------------
@@ -320,7 +322,7 @@ class CI_DB_result {
public function last_row($type = 'object')
{
$result = $this->result($type);
- return (count($result) === 0) ? $result : $result[count($result) - 1];
+ return (count($result) === 0) ? NULL : $result[count($result) - 1];
}
// --------------------------------------------------------------------
@@ -335,7 +337,7 @@ class CI_DB_result {
$result = $this->result($type);
if (count($result) === 0)
{
- return $result;
+ return NULL;
}
if (isset($result[$this->current_row + 1]))
@@ -358,7 +360,7 @@ class CI_DB_result {
$result = $this->result($type);
if (count($result) === 0)
{
- return $result;
+ return NULL;
}
if (isset($result[$this->current_row - 1]))
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 587dfdc01..cb97ff448 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -212,7 +212,7 @@ abstract class CI_DB_utility extends CI_DB_forge {
$out = rtrim($out).$newline;
// Next blast through the result array and build out the rows
- foreach ($query->result_array() as $row)
+ while ($row = $query->unbuffered_row('array'))
{
foreach ($row as $item)
{
@@ -258,7 +258,7 @@ abstract class CI_DB_utility extends CI_DB_forge {
// Generate the result
$xml = '<'.$root.'>'.$newline;
- foreach ($query->result_array() as $row)
+ while ($row = $query->unbuffered_row())
{
$xml .= $tab.'<'.$element.'>'.$newline;
foreach ($row as $key => $val)
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 161f99541..d801a9aaf 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -47,7 +47,7 @@ class CI_DB_mysql_driver extends CI_DB {
// clause and character used for LIKE escape sequences - not used in MySQL
protected $_like_escape_str = '';
- protected $_like_escape_chr = '';
+ protected $_like_escape_chr = '\\';
/**
* The syntax to count rows is slightly different across different
@@ -291,7 +291,9 @@ class CI_DB_mysql_driver extends CI_DB {
// escape LIKE condition wildcards
if ($like === TRUE)
{
- return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+ return str_replace(array($this->_like_escape_chr, '%', '_'),
+ array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+ $str);
}
return $str;
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 9261883f5..61761e0c6 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -47,7 +47,7 @@ class CI_DB_mysqli_driver extends CI_DB {
// clause and character used for LIKE escape sequences - not used in MySQL
protected $_like_escape_str = '';
- protected $_like_escape_chr = '';
+ protected $_like_escape_chr = '\\';
/**
* The syntax to count rows is slightly different across different
@@ -291,7 +291,9 @@ class CI_DB_mysqli_driver extends CI_DB {
// escape LIKE condition wildcards
if ($like === TRUE)
{
- return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+ return str_replace(array($this->_like_escape_chr, '%', '_'),
+ array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+ $str);
}
return $str;
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 7b05e0a43..6fb6c81f1 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -419,7 +419,7 @@ class CI_DB_oci8_result extends CI_DB_result {
OR $n < $this->current_row)
{
// No such row exists
- return array();
+ return NULL;
}
// Get the next row index that would actually need to be fetched
@@ -460,7 +460,7 @@ class CI_DB_oci8_result extends CI_DB_result {
$this->num_rows = 0;
}
- return array();
+ return NULL;
}
$this->current_row = $n;
@@ -507,7 +507,7 @@ class CI_DB_oci8_result extends CI_DB_result {
return (object) $row;
}
- return array();
+ return NULL;
}
// --------------------------------------------------------------------
@@ -539,19 +539,19 @@ class CI_DB_oci8_result extends CI_DB_result {
}
else
{
- return array();
+ return NULL;
}
}
elseif ( ! class_exists($class_name)) // No such class exists
{
- return array();
+ return NULL;
}
$row = $this->row_array($n);
- // An array would mean that the row doesn't exist
- if (is_array($row))
+ // A non-array would mean that the row doesn't exist
+ if ( ! is_array($row))
{
- return $row;
+ return NULL;
}
// Convert to the desired class and return
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index e38c1145c..4784fc65b 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -79,13 +79,13 @@ class CI_DB_pdo_driver extends CI_DB {
// clause and character used for LIKE escape sequences
// this one depends on the driver being used
- if ($this->pdodriver == 'mysql')
+ if ($this->pdodriver === 'mysql')
{
$this->_escape_char = '`';
$this->_like_escape_str = '';
- $this->_like_escape_chr = '';
+ $this->_like_escape_chr = '\\';
}
- elseif ($this->pdodriver == 'odbc')
+ elseif ($this->pdodriver === 'odbc')
{
$this->_like_escape_str = " {escape '%s'} ";
}
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 0ddfd0abe..30689cc70 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -539,6 +539,47 @@ class CI_DB_postgre_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * Update_Batch statement
+ *
+ * Generates a platform-specific batch update string from the supplied data
+ *
+ * @param string the table name
+ * @param array the update data
+ * @param array the where clause
+ * @return string
+ */
+ protected function _update_batch($table, $values, $index, $where = NULL)
+ {
+ $ids = array();
+ foreach ($values as $key => $val)
+ {
+ $ids[] = $val[$index];
+
+ foreach (array_keys($val) as $field)
+ {
+ if ($field != $index)
+ {
+ $final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field];
+ }
+ }
+ }
+
+ $cases = '';
+ foreach ($final as $k => $v)
+ {
+ $cases .= $k.' = (CASE '.$k."\n"
+ .implode("\n", $v)."\n"
+ .'ELSE '.$k.' END), ';
+ }
+
+ return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
+ .' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+ .$index.' IN('.implode(',', $ids).')';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Delete statement
*
* Generates a platform-specific delete string from the supplied data
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
index d83d6b2cd..946b36557 100644
--- a/system/database/drivers/sqlite3/sqlite3_result.php
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -386,7 +386,7 @@ class CI_DB_sqlite3_result extends CI_DB_result {
OR count($this->result_array) > 0 OR $n < $this->current_row)
{
// No such row exists
- return array();
+ return NULL;
}
// Get the next row index that would actually need to be fetched
@@ -427,7 +427,7 @@ class CI_DB_sqlite3_result extends CI_DB_result {
$this->num_rows = 0;
}
- return array();
+ return NULL;
}
$this->current_row = $n;
@@ -469,7 +469,7 @@ class CI_DB_sqlite3_result extends CI_DB_result {
return (object) $row;
}
- return array();
+ return NULL;
}
// --------------------------------------------------------------------
@@ -501,19 +501,19 @@ class CI_DB_sqlite3_result extends CI_DB_result {
}
else
{
- return array();
+ return NULL;
}
}
elseif ( ! class_exists($class_name)) // No such class exists
{
- return array();
+ return NULL;
}
$row = $this->row_array($n);
- // An array would mean that the row doesn't exist
- if (is_array($row))
+ // A non-array would mean that the row doesn't exist
+ if ( ! is_array($row))
{
- return $row;
+ return NULL;
}
// Convert to the desired class and return
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 3e9fa7b1a..5a24f5532 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -132,11 +132,9 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
protected function _execute($sql)
{
- return sqlsrv_query($this->conn_id,
- $sql,
- NULL,
- array('Scrollable'=> SQLSRV_CURSOR_STATIC, 'SendStreamParamsAtExec' => TRUE)
- );
+ return (is_write_type($sql) && stripos($sql, 'INSERT') === FALSE)
+ ? sqlsrv_query($this->conn_id, $sql)
+ : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC));
}
// --------------------------------------------------------------------
@@ -237,7 +235,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
public function affected_rows()
{
- return @sqlrv_rows_affected($this->conn_id);
+ return sqlrv_rows_affected($this->result_id);
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 271c6d21f..7456e922a 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -747,6 +747,8 @@ class CI_Upload {
';',
'?',
'/',
+ '!',
+ '#',
'%20',
'%22',
'%3c', // <
diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php
index 9f89d1be8..38615dd89 100644
--- a/tests/Bootstrap.php
+++ b/tests/Bootstrap.php
@@ -12,8 +12,25 @@ define('BASEPATH', PROJECT_BASE.'system/');
define('APPPATH', PROJECT_BASE.'application/');
define('VIEWPATH', PROJECT_BASE.'');
+// Get vfsStream either via PEAR or composer
+foreach (explode(PATH_SEPARATOR, get_include_path()) as $path)
+{
+ if (file_exists($path.DIRECTORY_SEPARATOR.'vfsStream/vfsStream.php'))
+ {
+ require_once 'vfsStream/vfsStream.php';
+ break;
+ }
+}
+
+if ( ! class_exists('vfsStream') && file_exists(PROJECT_BASE.'vendor/autoload.php'))
+{
+ include_once PROJECT_BASE.'vendor/autoload.php';
+ class_alias('org\bovigo\vfs\vfsStream', 'vfsStream');
+ class_alias('org\bovigo\vfs\vfsStreamDirectory', 'vfsStreamDirectory');
+ class_alias('org\bovigo\vfs\vfsStreamWrapper', 'vfsStreamWrapper');
+}
+
// Prep our test environment
-require_once 'vfsStream/vfsStream.php';
include_once $dir.'/mocks/core/common.php';
include_once $dir.'/mocks/autoloader.php';
spl_autoload_register('autoload');
diff --git a/tests/codeigniter/database/DB_driver_test.php b/tests/codeigniter/database/DB_driver_test.php
index fb40f0608..9e16e29b4 100644
--- a/tests/codeigniter/database/DB_driver_test.php
+++ b/tests/codeigniter/database/DB_driver_test.php
@@ -2,8 +2,6 @@
class DB_driver_test extends CI_TestCase {
- // ------------------------------------------------------------------------
-
public function test_initialize()
{
$config = Mock_Database_DB::config(DB_DRIVER);
@@ -32,5 +30,5 @@ class DB_driver_test extends CI_TestCase {
{
return new Mock_Database_Drivers_Postgre($config);
}
-
+
} \ No newline at end of file
diff --git a/tests/codeigniter/database/DB_test.php b/tests/codeigniter/database/DB_test.php
index 9b93e223d..d5c0dea08 100644
--- a/tests/codeigniter/database/DB_test.php
+++ b/tests/codeigniter/database/DB_test.php
@@ -2,8 +2,6 @@
class DB_test extends CI_TestCase {
- // ------------------------------------------------------------------------
-
public function test_db_invalid()
{
$connection = new Mock_Database_DB(array(
@@ -45,5 +43,5 @@ class DB_test extends CI_TestCase {
$this->assertTrue($db instanceof CI_DB);
$this->assertTrue($db instanceof CI_DB_Driver);
}
-
+
} \ No newline at end of file
diff --git a/tests/codeigniter/database/query_builder/escape_test.php b/tests/codeigniter/database/query_builder/escape_test.php
new file mode 100644
index 000000000..50685922a
--- /dev/null
+++ b/tests/codeigniter/database/query_builder/escape_test.php
@@ -0,0 +1,54 @@
+<?php
+
+class Escape_test extends CI_TestCase {
+
+ /**
+ * @var object Database/Query Builder holder
+ */
+ protected $db;
+
+ public function set_up()
+ {
+ $this->db = Mock_Database_Schema_Skeleton::init(DB_DRIVER);
+
+ Mock_Database_Schema_Skeleton::create_tables();
+ Mock_Database_Schema_Skeleton::create_data();
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * @see ./mocks/schema/skeleton.php
+ */
+ public function test_escape_like_percent_sign()
+ {
+ $string = '\%foo'
+;
+ $this->db->select('value');
+ $this->db->from('misc');
+ $this->db->like('key', $string, 'after');
+ $res = $this->db->get();
+
+ // Check the result
+ $this->assertEquals(1, count($res->result_array()));
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * @see ./mocks/schema/skeleton.php
+ */
+ public function test_escape_like_backslash_sign()
+ {
+ $string = '\\';
+
+ $this->db->select('value');
+ $this->db->from('misc');
+ $this->db->like('key', $string, 'after');
+ $res = $this->db->get();
+
+ // Check the result
+ $this->assertEquals(2, count($res->result_array()));
+ }
+
+} \ No newline at end of file
diff --git a/tests/mocks/database/ci_test.sqlite b/tests/mocks/database/ci_test.sqlite
index 23a3de2a4..44dcef9ec 100755
--- a/tests/mocks/database/ci_test.sqlite
+++ b/tests/mocks/database/ci_test.sqlite
Binary files differ
diff --git a/tests/mocks/database/schema/skeleton.php b/tests/mocks/database/schema/skeleton.php
index 671336cc4..05499f82f 100644
--- a/tests/mocks/database/schema/skeleton.php
+++ b/tests/mocks/database/schema/skeleton.php
@@ -88,6 +88,23 @@ class Mock_Database_Schema_Skeleton {
));
static::$forge->add_key('id', TRUE);
static::$forge->create_table('job', (strpos(static::$driver, 'pgsql') === FALSE));
+
+ // Misc Table
+ static::$forge->add_field(array(
+ 'id' => array(
+ 'type' => 'INTEGER',
+ 'constraint' => 3,
+ ),
+ 'key' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => 40,
+ ),
+ 'value' => array(
+ 'type' => 'TEXT',
+ ),
+ ));
+ static::$forge->add_key('id', TRUE);
+ static::$forge->create_table('misc', (strpos(static::$driver, 'pgsql') === FALSE));
}
/**
@@ -111,6 +128,10 @@ class Mock_Database_Schema_Skeleton {
array('id' => 3, 'name' => 'Accountant', 'description' => 'Boring job, but you will get free snack at lunch'),
array('id' => 4, 'name' => 'Musician', 'description' => 'Only Coldplay can actually called Musician'),
),
+ 'misc' => array(
+ array('id' => 1, 'key' => '\\xxxfoo456', 'value' => 'Entry with \\xxx'),
+ array('id' => 2, 'key' => '\\%foo456', 'value' => 'Entry with \\%'),
+ ),
);
foreach ($data as $table => $dummy_data)
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index e0d745fd8..4b8a0f2d3 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -75,6 +75,7 @@ Release Date: Not Released
- Added db_set_charset() support.
- Added _optimize_table() support for the :doc:`Database Utility Class <database/utilities>` (rebuilds table indexes).
- Added boolean data type support in escape().
+ - Added update_batch() support.
- Added a constructor to the DB_result class and moved all driver-specific properties and logic out of the base DB_driver class to allow better abstraction.
- Removed limit() and order_by() support for UPDATE and DELETE queries in PostgreSQL driver. Postgres does not support those features.
- Removed protect_identifiers() and renamed internal method _protect_identifiers() to it instead - it was just an alias.
@@ -149,7 +150,7 @@ Bug fixes for 3.0
- Fixed a bug where ``unlink()`` raised an error if cache file did not exist when you try to delete it.
- Fixed a bug (#181) where a mis-spelling was in the form validation language file.
-- Fixed a bug (#159, #163) that mishandled Active Record nested transactions because _trans_depth was not getting incremented.
+- Fixed a bug (#159, #163) that mishandled Query Builder nested transactions because _trans_depth was not getting incremented.
- Fixed a bug (#737, #75) where pagination anchor class was not set properly when using initialize method.
- Fixed a bug (#419) - auto_link() now recognizes URLs that come after a word boundary.
- Fixed a bug (#724) - is_unique in form validation now checks that you are connected to a database.
@@ -190,11 +191,11 @@ Bug fixes for 3.0
- Fixed a bug (#499) - a CSRF cookie was created even with CSRF protection being disabled.
- Fixed a bug (#306) - ODBC's insert_id() method was calling non-existent function odbc_insert_id(), which resulted in a fatal error.
- Fixed a bug in Oracle's DB_result class where the cursor id passed to it was always NULL.
-- Fixed a bug (#64) - Regular expression in DB_active_rec.php failed to handle queries containing SQL bracket delimiters in the join condition.
+- Fixed a bug (#64) - Regular expression in DB_query_builder.php failed to handle queries containing SQL bracket delimiters in the join condition.
- Fixed a bug in the :doc:`Session Library <libraries/sessions>` where a PHP E_NOTICE error was triggered by _unserialize() due to results from databases such as MSSQL and Oracle being space-padded on the right.
- Fixed a bug (#501) - set_rules() to check if the request method is not 'POST' before aborting, instead of depending on count($_POST) in the :doc:`Form Validation Library <libraries/form_validation>`.
- Fixed a bug (#940) - csrf_verify() used to set the CSRF cookie while processing a POST request with no actual POST data, which resulted in validating a request that should be considered invalid.
-- Fixed a bug in PostgreSQL's escape_str() where it didn't properly escape LIKE wild characters.
+- Fixed a bug (#136) - PostgreSQL, MySQL and MySQLi's escape_str() method didn't properly escape LIKE wild characters.
- Fixed a bug in the library loader where some PHP versions wouldn't execute the class constructor.
- Fixed a bug (#88) - An unexisting property was used for configuration of the Memcache cache driver.
- Fixed a bug (#14) - create_database() method in the :doc:`Database Forge Library <database/forge>` didn't utilize the configured database character set.
@@ -213,7 +214,12 @@ Bug fixes for 3.0
- Fixed a bug (#128) - :doc:`Language Library <libraries/language>` did not correctly keep track of loaded language files.
- Fixed a bug (#1242) - Added Windows path compatibility to function read_dir of ZIP library.
- Fixed a bug (#1314) - sess_destroy() did not destroy userdata.
-- Fixed a bug (#1349) - get_extension() in the `File Uploading Library <libraries/file_uploading>` returned the original filename when it didn't have an actual extension.
+- Fixed a bug (#1349) - get_extension() in the :doc:`File Uploading Library <libraries/file_uploading>` returned the original filename when it didn't have an actual extension.
+- Fixed a bug (#1273) - E_NOTICE being generated by :doc:`Query Builder <database/query_builder>`'s set_update_batch() method.
+- Fixed a bug (#44, #110) - :doc:`Upload library <libraries/file_uploading>`'s clean_file_name() method didn't clear '!' and '#' characters.
+- Fixed a bug (#121) - ``CI_DB_result::row()`` returned an array when there's no actual result to be returned.
+- Fixed a bug (#319) - SQLSRV's affected_rows() method failed due to a scrollable cursor being created for write-type queries.
+- Fixed a bug (#356) - PostgreSQL driver didn't have an _update_batch() method, which resulted in fatal error being triggered when update_batch() is used with it.
Version 2.1.1
=============