Browse Source

Add day of week ORM function

Ladislav Gallay 10 years ago
parent
commit
4ee00d9923

+ 7 - 1
src/Database/Dialect/PostgresDialectTrait.php

@@ -134,13 +134,19 @@ trait PostgresDialectTrait
                     ->name('')
                     ->type(' + INTERVAL')
                     ->iterateParts(function ($p, $key) {
-                        if ($key === 1) {
+                    if ($key === 1) {
                             $interval = sprintf("'%s'", key($p));
                             $p = [$interval => 'literal'];
                         }
                         return $p;
                     });
                 break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->name('EXTRACT')
+                    ->add(['DOW' => 'literal'], [], true)
+                    ->type(' FROM');
+                break;
         }
     }
 

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

@@ -138,6 +138,13 @@ trait SqliteDialectTrait
                         }
                         return $p;
                     });
+                break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->name('STRFTIME')
+                    ->type(' ,')
+                    ->add(["'%w'" => 'literal'], [], true);
+                break;
         }
     }
 

+ 10 - 3
src/Database/Dialect/SqlserverDialectTrait.php

@@ -241,7 +241,7 @@ trait SqlserverDialectTrait
                 break;
             case 'DATE_ADD':
                 $params = [];
-                $visitor = function ($p, $key) (&$params) {
+                $visitor = function ($p, $key) use (&$params) {
                     if ($key === 0) {
                         $params[2] = $value;
                     } else {
@@ -250,8 +250,8 @@ trait SqlserverDialectTrait
                         $params[1] = $valueUnit[0];
                     }
                     return $p;
-                });
-                $manipulator = function ($p, $key) ($params) {
+                };
+                $manipulator = function ($p, $key) use ($params) {
                     return $params[$key];
                 };
 
@@ -262,6 +262,13 @@ trait SqlserverDialectTrait
                     ->iterateParts($manipulator)
                     ->add($params[2]);
                 break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->name('DATEPART')
+                    ->type(' ')
+                    ->add(['weekday, ' => 'literal'], [], true)
+                    ->add([') - (1' => 'literal']); // SqlServer starts on index 1
+                break;
         }
     }
 

+ 26 - 0
src/Database/FunctionsBuilder.php

@@ -200,6 +200,32 @@ class FunctionsBuilder
     }
 
     /**
+     * Returns a FunctionExpression representing a call to SQL WEEKDAY function.
+     * 0 - Sunday, 1 - Monday, 2 - Tuesday...
+     *
+     * @param mixed $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return FunctionExpression
+     */
+    public function dayOfWeek($expression, $types = [])
+    {
+        return $this->_literalArgumentFunction('DAYOFWEEK', $expression, $types);
+    }
+
+    /**
+     * Returns a FunctionExpression representing a call to SQL WEEKDAY function.
+     * 0 - Sunday, 1 - Monday, 2 - Tuesday...
+     *
+     * @param mixed $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return FunctionExpression
+     */
+    public function weekday($expression, $types = [])
+    {
+        return $this->dayOfWeek($expression, $types);
+    }
+
+    /**
      * Returns a FunctionExpression representing a call that will return the current
      * date and time. By default it returns both date and time, but you can also
      * make it generate only the date or only the time.

+ 17 - 1
tests/TestCase/Database/FunctionsBuilderTest.php

@@ -173,10 +173,26 @@ class FunctionsBuilderTest extends TestCase
      *
      * @return void
      */
-    public function testExtract()
+    public function testDateAdd()
     {
         $function = $this->functions->dateAdd('created', -3, 'day');
         $this->assertInstanceOf('Cake\Database\Expression\FunctionExpression', $function);
         $this->assertEquals("DATE_ADD(created, INTERVAL -3 day)", $function->sql(new ValueBinder));
     }
+
+    /**
+     * Tests generating a DAYOFWEEK() function
+     *
+     * @return void
+     */
+    public function testDayOfWeek()
+    {
+        $function = $this->functions->dayOfWeek('created');
+        $this->assertInstanceOf('Cake\Database\Expression\FunctionExpression', $function);
+        $this->assertEquals("DAYOFWEEK(created)", $function->sql(new ValueBinder));
+
+        $function = $this->functions->weekday('created');
+        $this->assertInstanceOf('Cake\Database\Expression\FunctionExpression', $function);
+        $this->assertEquals("DAYOFWEEK(created)", $function->sql(new ValueBinder));
+    }
 }