Browse Source

Added SQL RAND() function.

Dmitrii Romanov 7 years ago
parent
commit
102ed1a644

+ 3 - 0
src/Database/Dialect/PostgresDialectTrait.php

@@ -132,6 +132,9 @@ trait PostgresDialectTrait
             case 'NOW':
                 $expression->setName('LOCALTIMESTAMP')->add([' 0 ' => 'literal']);
                 break;
+            case 'RAND':
+                $expression->setName('RANDOM');
+                break;
             case 'DATE_ADD':
                 $expression
                     ->setName('')

+ 5 - 0
src/Database/Dialect/SqliteDialectTrait.php

@@ -108,6 +108,11 @@ trait SqliteDialectTrait
             case 'NOW':
                 $expression->setName('DATETIME')->add(["'now'" => 'literal']);
                 break;
+            case 'RAND':
+                $expression
+                    ->setName('ABS')
+                    ->add(["RANDOM() % 1" => 'literal'], [], true);
+                break;
             case 'CURRENT_DATE':
                 $expression->setName('DATE')->add(["'now'" => 'literal']);
                 break;

+ 10 - 0
src/Database/FunctionsBuilder.php

@@ -61,6 +61,16 @@ class FunctionsBuilder
     }
 
     /**
+     * Returns a FunctionExpression representing a call to SQL RAND function.
+     *
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function rand()
+    {
+        return $this->_build('RAND', [], [], 'float');
+    }
+
+    /**
      * Returns a FunctionExpression representing a call to SQL SUM function.
      *
      * @param mixed $expression the function argument

+ 13 - 0
tests/TestCase/Database/FunctionsBuilderTest.php

@@ -217,4 +217,17 @@ class FunctionsBuilderTest extends TestCase
         $this->assertEquals('DAYOFWEEK(created)', $function->sql(new ValueBinder));
         $this->assertEquals('integer', $function->getReturnType());
     }
+
+    /**
+     * Tests generating a RAND() function
+     *
+     * @return void
+     */
+    public function testRand()
+    {
+        $function = $this->functions->rand();
+        $this->assertInstanceOf('Cake\Database\Expression\FunctionExpression', $function);
+        $this->assertEquals('RAND()', $function->sql(new ValueBinder));
+        $this->assertEquals('float', $function->getReturnType());
+    }
 }

+ 20 - 0
tests/TestCase/ORM/QueryTest.php

@@ -1700,6 +1700,26 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Test that RAND() returns correct results.
+     *
+     * @return void
+     */
+    public function testSelectRandom()
+    {
+        $table = $this->getTableLocator()->get('articles');
+        $query = $table
+            ->query();
+
+        $query->select(['s' => $query->func()->rand()]);
+        $result = $query
+            ->extract('s')
+            ->first();
+
+        $this->assertGreaterThanOrEqual(0, $result);
+        $this->assertLessThan(1, $result);
+    }
+
+    /**
      * Test update method.
      *
      * @return void