Browse Source

Removing extra paging result that ends up because of SQLserver 10 workarounds.

Mark Story 14 years ago
parent
commit
4deedf6da2

+ 12 - 5
lib/Cake/Model/Datasource/Database/Sqlserver.php

@@ -114,6 +114,8 @@ class Sqlserver extends DboSource {
  */
 	private $__lastQueryHadError = false;
 
+	const ROW_COUNTER = '_cake_page_rownum_';
+
 /**
  * Connects to the database using options in the given configuration array.
  *
@@ -522,13 +524,14 @@ class Sqlserver extends DboSource {
 						$order = 'ORDER BY (SELECT NULL)';
 					}
 
+					$rowCounter = self::ROW_COUNTER;
 					$pagination = "
 						SELECT {$limit} * FROM (
-							SELECT {$fields}, ROW_NUMBER() OVER ({$order}) AS ssma\$rownum
+							SELECT {$fields}, ROW_NUMBER() OVER ({$order}) AS {$rowCounter}
 							FROM {$table} {$alias} {$joins} {$conditions} {$group}
-						) AS ssma\$sub1
-						WHERE ssma\$sub1.[ssma\$rownum] > {$limit2}
-						ORDER BY ssma\$sub1.[ssma\$rownum]
+						) AS _cake_paging_
+						WHERE _cake_paging_.{$rowCounter} > {$limit2}
+						ORDER BY _cake_paging_.{$rowCounter}
 					";
 					return $pagination;
 				} else {
@@ -602,7 +605,8 @@ class Sqlserver extends DboSource {
 	}
 
 /**
- * Fetches the next row from the current result set
+ * Fetches the next row from the current result set.
+ * Eats the magic ROW_COUNTER variable.
  *
  * @return mixed
  */
@@ -611,6 +615,9 @@ class Sqlserver extends DboSource {
 			$resultRow = array();
 			foreach ($this->map as $col => $meta) {
 				list($table, $column, $type) = $meta;
+				if ($table === 0 && $column === self::ROW_COUNTER) {
+					continue;
+				}
 				$resultRow[$table][$column] = $row[$col];
 				if ($type === 'boolean' && !is_null($row[$col])) {
 					$resultRow[$table][$column] = $this->boolean($resultRow[$table][$column]);

+ 31 - 14
lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php

@@ -170,19 +170,6 @@ class SqlserverTestModel extends Model {
 	public function find($conditions = null, $fields = null, $order = null, $recursive = null) {
 		return $conditions;
 	}
-
-/**
- * findAll method
- *
- * @param mixed $conditions
- * @param mixed $fields
- * @param mixed $order
- * @param mixed $recursive
- * @return array
- */
-	public function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
-		return $conditions;
-	}
 }
 
 /**
@@ -259,7 +246,7 @@ class SqlserverTest extends CakeTestCase {
  *
  * @var array
  */
-	public $fixtures = array('core.category');
+	public $fixtures = array('core.category', 'core.post');
 
 /**
  * Sets up a Dbo class instance for testing
@@ -575,4 +562,34 @@ class SqlserverTest extends CakeTestCase {
 		);
 		$this->assertEqual($expected, $result);
 	}
+
+/**
+ * SQL server < 11 doesn't have proper limit/offset support, test that our hack works.
+ *
+ * @return void
+ */
+	public function testLimitOffsetHack() {
+		$this->loadFixtures('Post');
+		$query = array(
+			'limit' => 1,
+			'page' => 1,
+			'order' => 'Post.title ASC',
+		);
+		$Post = ClassRegistry::init('Post');
+		$results = $Post->find('all', $query);
+
+		$this->assertEquals(1, count($results));
+		$this->assertEquals('First Post', $results[0]['Post']['title']);
+
+		$query = array(
+			'limit' => 1,
+			'page' => 2,
+			'order' => 'Post.title ASC',
+		);
+		$Post = ClassRegistry::init('Post');
+		$results = $Post->find('all', $query);
+		$this->assertEquals(1, count($results));
+		$this->assertFalse(isset($results[0][0]));
+		$this->assertEquals('Second Post', $results[0]['Post']['title']);
+	}
 }