]> source.dussan.org Git - nextcloud-server.git/commitdiff
Introduce cross-db ILIKE
authorRobin Appelman <icewind@owncloud.com>
Tue, 9 Sep 2014 11:57:02 +0000 (13:57 +0200)
committerLukas Reschke <lukas@owncloud.com>
Mon, 27 Oct 2014 22:00:49 +0000 (23:00 +0100)
adding ILIKE to AdapterSQLSrv

add test case for ILIKE with wildcard

Make sqlite LIKE case sensitive on default

Implement ILIKE for sqlite

Use ILIKE in cache search

Fix ILIKE without wildcards for oracle

lib/private/db/adaptermysql.php [new file with mode: 0644]
lib/private/db/adapteroci8.php
lib/private/db/adaptersqlite.php
lib/private/db/adaptersqlsrv.php
lib/private/db/connectionfactory.php
lib/private/db/sqlitesessioninit.php [new file with mode: 0644]
lib/private/files/cache/cache.php
tests/lib/db.php

diff --git a/lib/private/db/adaptermysql.php b/lib/private/db/adaptermysql.php
new file mode 100644 (file)
index 0000000..0b6e6a5
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+namespace OC\DB;
+
+class AdapterMySQL extends Adapter {
+       public function fixupStatement($statement) {
+               $statement = str_replace(' ILIKE ', ' COLLATE utf8_general_ci LIKE ', $statement);
+               return $statement;
+       }
+}
index bc226e979eceae7a4a9463a7e6eb9029b44e71d0..db7e66e7913473d0412d873115d8aa0b58a46a74 100644 (file)
@@ -11,18 +11,20 @@ namespace OC\DB;
 
 class AdapterOCI8 extends Adapter {
        public function lastInsertId($table) {
-               if($table !== null) {
+               if ($table !== null) {
                        $suffix = '_SEQ';
-                       $table = '"'.$table.$suffix.'"';
+                       $table = '"' . $table . $suffix . '"';
                }
                return $this->conn->realLastInsertId($table);
        }
 
        const UNIX_TIMESTAMP_REPLACEMENT = "(cast(sys_extract_utc(systimestamp) as date) - date'1970-01-01') * 86400";
+
        public function fixupStatement($statement) {
-               $statement = str_replace( '`', '"', $statement );
-               $statement = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $statement );
-               $statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement );
+               $statement = preg_replace('/`(\w+)` ILIKE \?/', 'REGEXP_LIKE(`$1`, \'^\' || REPLACE(?, \'%\', \'.*\') || \'$\', \'i\')', $statement);
+               $statement = str_replace('`', '"', $statement);
+               $statement = str_ireplace('NOW()', 'CURRENT_TIMESTAMP', $statement);
+               $statement = str_ireplace('UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement);
                return $statement;
        }
 }
index fa6d308ae328c85d73c2ac1ff16485797aa1c09f..f73f364df540d6913307c46df14149eeb885d9dd 100644 (file)
@@ -11,6 +11,7 @@ namespace OC\DB;
 
 class AdapterSqlite extends Adapter {
        public function fixupStatement($statement) {
+               $statement = preg_replace('/`(\w+)` ILIKE \?/', 'LOWER($1) LIKE LOWER(?)', $statement);
                $statement = str_replace( '`', '"', $statement );
                $statement = str_ireplace( 'NOW()', 'datetime(\'now\')', $statement );
                $statement = str_ireplace( 'UNIX_TIMESTAMP()', 'strftime(\'%s\',\'now\')', $statement );
index a6bc0e21052f67f8cedf6d6692b964df57318101..1ac9badab9406edc172cc051f59f8cd08dcb8678 100644 (file)
@@ -11,6 +11,7 @@ namespace OC\DB;
 
 class AdapterSQLSrv extends Adapter {
        public function fixupStatement($statement) {
+               $statement = str_replace(' ILIKE ', ' COLLATE Latin1_General_CI_AS LIKE ', $statement);
                $statement = preg_replace( "/\`(.*?)`/", "[$1]", $statement );
                $statement = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $statement );
                $statement = str_replace( 'LENGTH(', 'LEN(', $statement );
index 033065bcb77cab1c08c19c38f807357743f191af..0a3c1118839509bce87e655dc2285539e393e53c 100644 (file)
@@ -26,7 +26,7 @@ class ConnectionFactory {
                        'wrapperClass' => 'OC\DB\Connection',
                ),
                'mysql' => array(
-                       'adapter' => '\OC\DB\Adapter',
+                       'adapter' => '\OC\DB\AdapterMySQL',
                        'charset' => 'UTF8',
                        'driver' => 'pdo_mysql',
                        'wrapperClass' => 'OC\DB\Connection',
@@ -89,6 +89,9 @@ class ConnectionFactory {
                        case 'oci':
                                $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit);
                                break;
+                       case 'sqlite3':
+                               $eventManager->addEventSubscriber(new SQLiteSessionInit);
+                               break;
                }
                $connection = \Doctrine\DBAL\DriverManager::getConnection(
                        array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams),
diff --git a/lib/private/db/sqlitesessioninit.php b/lib/private/db/sqlitesessioninit.php
new file mode 100644 (file)
index 0000000..7e1166b
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+use Doctrine\DBAL\Event\ConnectionEventArgs;
+use Doctrine\DBAL\Events;
+use Doctrine\Common\EventSubscriber;
+
+class SQLiteSessionInit implements EventSubscriber {
+       /**
+        * @var bool
+        */
+       private $caseSensitiveLike;
+
+       /**
+        * Configure case sensitive like for each connection
+        *
+        * @param bool $caseSensitiveLike
+        */
+       public function __construct($caseSensitiveLike = true) {
+               $this->caseSensitiveLike = $caseSensitiveLike;
+       }
+
+       /**
+        * @param ConnectionEventArgs $args
+        * @return void
+        */
+       public function postConnect(ConnectionEventArgs $args) {
+               $sensitive = ($this->caseSensitiveLike) ? 'true' : 'false';
+               $args->getConnection()->executeUpdate('PRAGMA case_sensitive_like = ' . $sensitive);
+       }
+
+       public function getSubscribedEvents() {
+               return array(Events::postConnect);
+       }
+}
index cfa3e916185f78ace3a4af08e8ef990272afa987..7ea00325a1015d34bb51e9877d2422e66b69f76c 100644 (file)
@@ -464,19 +464,7 @@ class Cache {
                                `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`,
                                `unencrypted_size`, `etag`, `permissions`
                        FROM `*PREFIX*filecache`
-                       WHERE `storage` = ? AND ';
-               $dbtype = \OC_Config::getValue( 'dbtype', 'sqlite' );
-               if($dbtype === 'oci') {
-                       //remove starting and ending % from the pattern
-                       $pattern = '^'.str_replace('%', '.*', $pattern).'$';
-                       $sql .= 'REGEXP_LIKE(`name`, ?, \'i\')';
-               } else if($dbtype === 'pgsql') {
-                       $sql .= '`name` ILIKE ?';
-               } else if ($dbtype === 'mysql') {
-                       $sql .= '`name` COLLATE utf8_general_ci LIKE ?';
-               } else {
-                       $sql .= '`name` LIKE ?';
-               }
+                       WHERE `storage` = ? AND `name` ILIKE ?';
                $result = \OC_DB::executeAudited($sql,
                        array($this->getNumericStorageId(), $pattern)
                );
index 4b1a474c4efa5ab7d1d1c205b150b8c51af36e71..2e236295ff3555a40f7d92e3416e60aa2a2c3214 100644 (file)
@@ -27,6 +27,11 @@ class Test_DB extends PHPUnit_Framework_TestCase {
         */
        private $table3;
 
+       /**
+        * @var string
+        */
+       private $table4;
+
        public function setUp() {
                $dbfile = OC::$SERVERROOT.'/tests/data/db_structure.xml';
 
@@ -241,4 +246,54 @@ class Test_DB extends PHPUnit_Framework_TestCase {
                $query = OC_DB::prepare("UPDATE `*PREFIX*{$this->table2}` SET `uri` = ? WHERE `fullname` = ?");
                return $query->execute(array($uri, $fullname));
        }
+
+       public function testILIKE() {
+               $table = "*PREFIX*{$this->table2}";
+
+               $query = OC_DB::prepare("INSERT INTO `$table` (`fullname`, `uri`, `carddata`) VALUES (?, ?, ?)");
+               $query->execute(array('fooBAR', 'foo', 'bar'));
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` LIKE ?");
+               $result = $query->execute(array('foobar'));
+               $this->assertCount(0, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` ILIKE ?");
+               $result = $query->execute(array('foobar'));
+               $this->assertCount(1, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` ILIKE ?");
+               $result = $query->execute(array('foo'));
+               $this->assertCount(0, $result->fetchAll());
+       }
+
+       public function testILIKEWildcard() {
+               $table = "*PREFIX*{$this->table2}";
+
+               $query = OC_DB::prepare("INSERT INTO `$table` (`fullname`, `uri`, `carddata`) VALUES (?, ?, ?)");
+               $query->execute(array('FooBAR', 'foo', 'bar'));
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` LIKE ?");
+               $result = $query->execute(array('%bar'));
+               $this->assertCount(0, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` LIKE ?");
+               $result = $query->execute(array('foo%'));
+               $this->assertCount(0, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` LIKE ?");
+               $result = $query->execute(array('%ba%'));
+               $this->assertCount(0, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` ILIKE ?");
+               $result = $query->execute(array('%bar'));
+               $this->assertCount(1, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` ILIKE ?");
+               $result = $query->execute(array('foo%'));
+               $this->assertCount(1, $result->fetchAll());
+
+               $query = OC_DB::prepare("SELECT * FROM `$table` WHERE `fullname` ILIKE ?");
+               $result = $query->execute(array('%ba%'));
+               $this->assertCount(1, $result->fetchAll());
+       }
 }