]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add function builder to the query builder
authorRobin Appelman <robin@icewind.nl>
Mon, 16 Jan 2017 14:31:04 +0000 (15:31 +0100)
committerRobin Appelman <robin@icewind.nl>
Thu, 30 Mar 2017 09:09:26 +0000 (11:09 +0200)
Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php [new file with mode: 0644]
lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php [new file with mode: 0644]
lib/private/DB/QueryBuilder/FunctionBuilder/PgSqlFunctionBuilder.php [new file with mode: 0644]
lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php [new file with mode: 0644]
lib/private/DB/QueryBuilder/QueryBuilder.php
lib/public/DB/QueryBuilder/IFunctionBuilder.php [new file with mode: 0644]
lib/public/DB/QueryBuilder/IQueryBuilder.php
tests/lib/DB/QueryBuilder/FunctionBuilderTest.php [new file with mode: 0644]

diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
new file mode 100644 (file)
index 0000000..61d32d0
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\DB\QueryBuilder\FunctionBuilder;
+
+use OC\DB\QueryBuilder\QueryFunction;
+use OC\DB\QueryBuilder\QuoteHelper;
+use OCP\DB\QueryBuilder\IFunctionBuilder;
+
+class FunctionBuilder implements IFunctionBuilder {
+       /** @var QuoteHelper */
+       protected $helper;
+
+       /**
+        * ExpressionBuilder constructor.
+        *
+        * @param QuoteHelper $helper
+        */
+       public function __construct(QuoteHelper $helper) {
+               $this->helper = $helper;
+       }
+
+       public function md5($input) {
+               return new QueryFunction('MD5(' . $this->helper->quoteColumnName($input) . ')');
+       }
+
+       public function concat($x, $y) {
+               return new QueryFunction('CONCAT(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+       }
+
+       public function substring($input, $start, $length = null) {
+               if ($length) {
+                       return new QueryFunction('SUBSTR(' . $this->helper->quoteColumnName($input) . ', ' . $this->helper->quoteColumnName($start) . ', ' . $this->helper->quoteColumnName($length) . ')');
+               } else {
+                       return new QueryFunction('SUBSTR(' . $this->helper->quoteColumnName($input) . ', ' . $this->helper->quoteColumnName($start) . ')');
+               }
+       }
+}
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php
new file mode 100644 (file)
index 0000000..0877d47
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\DB\QueryBuilder\FunctionBuilder;
+
+use OC\DB\QueryBuilder\QueryFunction;
+
+class OCIFunctionBuilder extends FunctionBuilder {
+       public function md5($input) {
+               return new QueryFunction('LOWER(DBMS_OBFUSCATION_TOOLKIT.md5 (input => UTL_RAW.cast_to_raw(' . $this->helper->quoteColumnName($input) .')))');
+       }
+}
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/PgSqlFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/PgSqlFunctionBuilder.php
new file mode 100644 (file)
index 0000000..b6a7dce
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\DB\QueryBuilder\FunctionBuilder;
+
+use OC\DB\QueryBuilder\QueryFunction;
+
+class PgSqlFunctionBuilder extends FunctionBuilder {
+       public function concat($x, $y) {
+               return new QueryFunction($this->helper->quoteColumnName($x) . ' || ' . $this->helper->quoteColumnName($y));
+       }
+}
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
new file mode 100644 (file)
index 0000000..20b30d0
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\DB\QueryBuilder\FunctionBuilder;
+
+use OC\DB\QueryBuilder\QueryFunction;
+
+class SqliteFunctionBuilder extends FunctionBuilder {
+       public function concat($x, $y) {
+               return new QueryFunction($this->helper->quoteColumnName($x) . ' || ' . $this->helper->quoteColumnName($y));
+       }
+}
index a434140806e8faab783e9e3f98e05889fab640c5..3ff31de19a3f6a82f365393138ae48242711ddf1 100644 (file)
@@ -34,6 +34,8 @@ use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder;
 use OC\DB\QueryBuilder\ExpressionBuilder\PgSqlExpressionBuilder;
 use OC\DB\QueryBuilder\ExpressionBuilder\SqliteExpressionBuilder;
 use OC\DB\QueryBuilder\FunctionBuilder\FunctionBuilder;
+use OC\DB\QueryBuilder\FunctionBuilder\OCIFunctionBuilder;
+use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder;
 use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder;
 use OC\SystemConfig;
 use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -121,6 +123,34 @@ class QueryBuilder implements IQueryBuilder {
                }
        }
 
+       /**
+        * Gets an FunctionBuilder used for object-oriented construction of query functions.
+        * This producer method is intended for convenient inline usage. Example:
+        *
+        * <code>
+        *     $qb = $conn->getQueryBuilder()
+        *         ->select('u')
+        *         ->from('users', 'u')
+        *         ->where($qb->fun()->md5('u.id'));
+        * </code>
+        *
+        * For more complex function construction, consider storing the function
+        * builder object in a local variable.
+        *
+        * @return \OCP\DB\QueryBuilder\IFunctionBuilder
+        */
+       public function fun() {
+               if ($this->connection instanceof OracleConnection) {
+                       return new OCIFunctionBuilder($this->helper);
+               } else if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
+                       return new SqliteFunctionBuilder($this->helper);
+               } else if ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) {
+                       return new PgSqlFunctionBuilder($this->helper);
+               } else {
+                       return new FunctionBuilder($this->helper);
+               }
+       }
+
        /**
         * Gets the type of the currently built query.
         *
diff --git a/lib/public/DB/QueryBuilder/IFunctionBuilder.php b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
new file mode 100644 (file)
index 0000000..9798a3a
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\DB\QueryBuilder;
+
+/**
+ * This class provides a builder for sql some functions
+ *
+ * @since 12.0.0
+ */
+interface IFunctionBuilder {
+       /**
+        * Calculates the MD5 hash of a given input
+        *
+        * @param mixed $input The input to be hashed
+        *
+        * @return IQueryFunction
+        * @since 12.0.0
+        */
+       public function md5($input);
+
+       /**
+        * Combines two input strings
+        *
+        * @param mixed $x The first input string
+        * @param mixed $y The seccond input string
+        *
+        * @return IQueryFunction
+        * @since 12.0.0
+        */
+       public function concat($x, $y);
+
+       /**
+        * Takes a substring from the input string
+        *
+        * @param mixed $input The input string
+        * @param mixed $start The start of the substring, note that counting starts at 1
+        * @param mixed $length The length of the substring
+        *
+        * @return IQueryFunction
+        * @since 12.0.0
+        */
+       public function substring($input, $start, $length = null);
+}
index 8ef8a96b25f1acea2b31b2f8cb6bbfa05d924003..2a88e7ac5667e19f6edd61dacb2409b6d24ae890 100644 (file)
@@ -94,6 +94,25 @@ interface IQueryBuilder {
         */
        public function expr();
 
+       /**
+        * Gets an FunctionBuilder used for object-oriented construction of query functions.
+        * This producer method is intended for convenient inline usage. Example:
+        *
+        * <code>
+        *     $qb = $conn->getQueryBuilder()
+        *         ->select('u')
+        *         ->from('users', 'u')
+        *         ->where($qb->fun()->md5('u.id'));
+        * </code>
+        *
+        * For more complex function construction, consider storing the function
+        * builder object in a local variable.
+        *
+        * @return \OCP\DB\QueryBuilder\IFunctionBuilder
+        * @since 12.0.0
+        */
+       public function fun();
+
        /**
         * Gets the type of the currently built query.
         *
diff --git a/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php b/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php
new file mode 100644 (file)
index 0000000..b1ef3d7
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @author Robin Appelman <robin@icewind.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace Test\DB\QueryBuilder;
+
+use OC\DB\QueryBuilder\Literal;
+use Test\TestCase;
+
+/**
+ * Class FunctionBuilderTest
+ *
+ * @group DB
+ *
+ * @package Test\DB\QueryBuilder
+ */
+class FunctionBuilderTest extends TestCase {
+       /** @var \Doctrine\DBAL\Connection|\OCP\IDBConnection */
+       protected $connection;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->connection = \OC::$server->getDatabaseConnection();
+       }
+
+       public function testConcat() {
+               $query = $this->connection->getQueryBuilder();
+
+               $query->select($query->fun()->concat($query->createNamedParameter('foo'), new Literal("'bar'")));
+
+               $this->assertEquals('foobar', $query->execute()->fetchColumn());
+       }
+
+       public function testMd5() {
+               $query = $this->connection->getQueryBuilder();
+
+               $query->select($query->fun()->md5($query->createNamedParameter('foobar')));
+
+               $this->assertEquals(md5('foobar'), $query->execute()->fetchColumn());
+       }
+
+       public function testSubstring() {
+               $query = $this->connection->getQueryBuilder();
+
+               $query->select($query->fun()->substring($query->createNamedParameter('foobar'), new Literal(2), $query->createNamedParameter(2)));
+
+               $this->assertEquals('oo', $query->execute()->fetchColumn());
+       }
+
+       public function testSubstringNoLength() {
+               $query = $this->connection->getQueryBuilder();
+
+               $query->select($query->fun()->substring($query->createNamedParameter('foobar'), new Literal(2)));
+
+               $this->assertEquals('oobar', $query->execute()->fetchColumn());
+       }
+}