예제 #1
0
 function testSelectWithLimitClause()
 {
     // numeric limit
     $query = new SQLQuery();
     $query->from[] = "MyTable";
     $query->limit("99");
     $this->assertEquals("SELECT * FROM MyTable LIMIT 99", $query->sql());
     // array limit
     $query = new SQLQuery();
     $query->from[] = "MyTable";
     $query->limit(array('limit' => 99));
     $this->assertEquals("SELECT * FROM MyTable LIMIT 99", $query->sql());
     // array limit with start (MySQL specific)
     $query = new SQLQuery();
     $query->from[] = "MyTable";
     $query->limit(array('limit' => 99, 'start' => 97));
     $this->assertEquals("SELECT * FROM MyTable LIMIT 97,99", $query->sql());
 }
예제 #2
0
	/**
	 * Build a {@link SQLQuery} object to perform the given query.
	 *
	 * @param string $filter A filter to be inserted into the WHERE clause.
	 * @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used.
	 * @param string|array $limit A limit expression to be inserted into the LIMIT clause.
	 * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned.
	 * @param boolean $restictClasses Restrict results to only objects of either this class of a subclass of this class
	 * @param string $having A filter to be inserted into the HAVING clause.
	 *
	 * @return SQLQuery Query built.
	 */
	public function buildSQL($filter = "", $sort = "", $limit = "", $join = "", $restrictClasses = true, $having = "") {
		// Find a default sort
		if(!$sort) {
			$sort = $this->stat('default_sort');
		}

		// Get the tables to join to
		$tableClasses = ClassInfo::dataClassesFor($this->class);
		if(!$tableClasses) {
			if(!ManifestBuilder::has_been_included()) {
				user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not querying the database in _config.php.", E_USER_ERROR);
			} else {
				user_error("DataObject::buildSQL: Can't find data classes (classes linked to tables) for $this->class. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
			}
		}

		$baseClass = array_shift($tableClasses);
		$select = array("`$baseClass`.*");

		// Build our intial query
		$query = new SQLQuery($select);
		$query->from("`$baseClass`");
		$query->where($filter);
		$query->orderby($sort);
		$query->limit($limit);

		// Add SQL for multi-value fields on the base table
		$databaseFields = $this->databaseFields();
		if($databaseFields) foreach($databaseFields as $k => $v) {
			if(!in_array($k, array('ClassName', 'LastEdited', 'Created'))) {
				if(ClassInfo::classImplements($v, 'CompositeDBField')) {
					$this->dbObject($k)->addToQuery($query);
				}
			}
		}
		// Join all the tables
		if($tableClasses && self::$subclass_access) {
			foreach($tableClasses as $tableClass) {
				$query->from[$tableClass] = "LEFT JOIN `$tableClass` ON `$tableClass`.ID = `$baseClass`.ID";
				$query->select[] = "`$tableClass`.*";

				// Add SQL for multi-value fields
				$SNG = singleton($tableClass);
				$databaseFields = $SNG->databaseFields();
				if($databaseFields) foreach($databaseFields as $k => $v) {
					if(!in_array($k, array('ClassName', 'LastEdited', 'Created'))) {
						if(ClassInfo::classImplements($v, 'CompositeDBField')) {
							$SNG->dbObject($k)->addToQuery($query);
						}
					}
				}
			}
		}

		$query->select[] = "`$baseClass`.ID";
		$query->select[] = "if(`$baseClass`.ClassName,`$baseClass`.ClassName,'$baseClass') AS RecordClassName";

		// Get the ClassName values to filter to
		$classNames = ClassInfo::subclassesFor($this->class);

		if(!$classNames) {
			user_error("DataObject::get() Can't find data sub-classes for '$callerClass'");
		}

		// If querying the base class, don't bother filtering on class name
		if($restrictClasses && $this->class != $baseClass) {
			// Get the ClassName values to filter to
			$classNames = ClassInfo::subclassesFor($this->class);
			if(!$classNames) {
				user_error("DataObject::get() Can't find data sub-classes for '$callerClass'");
			}

			$query->where[] = "`$baseClass`.ClassName IN ('" . implode("','", $classNames) . "')";
		}

		if($having) {
			$query->having[] = $having;
		}

		if($join) {
			$query->from[] = $join;
			$query->groupby[] = reset($query->from) . ".ID";
		}

		return $query;
	}
예제 #3
0
 function testSelectWithLimitClause()
 {
     // These are MySQL specific :-S
     if (DB::getConn() instanceof MySQLDatabase) {
         // numeric limit
         $query = new SQLQuery();
         $query->from[] = "MyTable";
         $query->limit("99");
         $this->assertEquals("SELECT * FROM MyTable LIMIT 99", $query->sql());
         // array limit
         $query = new SQLQuery();
         $query->from[] = "MyTable";
         $query->limit(array('limit' => 99));
         $this->assertEquals("SELECT * FROM MyTable LIMIT 99", $query->sql());
         // array limit with start (MySQL specific)
         $query = new SQLQuery();
         $query->from[] = "MyTable";
         $query->limit(array('limit' => 99, 'start' => 97));
         $this->assertEquals("SELECT * FROM MyTable LIMIT 99 OFFSET 97", $query->sql());
     }
 }
 /**
  * Test {@link DataObjectSet->parseQueryLimit()}
  */
 function testParseQueryLimit()
 {
     // Create empty objects, because they don't need to have contents
     $sql = new SQLQuery('*', '"Member"');
     $max = $sql->unlimitedRowCount();
     $set = new DataObjectSet();
     // Test handling an array
     $set->parseQueryLimit($sql->limit(array('limit' => 5, 'start' => 2)));
     $expected = array('pageStart' => 2, 'pageLength' => 5, 'totalSize' => $max);
     $this->assertEquals($expected, $set->getPageLimits(), 'The page limits match expected values.');
     // Test handling OFFSET string
     // uppercase
     $set->parseQueryLimit($sql->limit('3 OFFSET   1'));
     $expected = array('pageStart' => 1, 'pageLength' => 3, 'totalSize' => $max);
     $this->assertEquals($expected, $set->getPageLimits(), 'The page limits match expected values.');
     // and lowercase
     $set->parseQueryLimit($sql->limit('32   offset   3'));
     $expected = array('pageStart' => 3, 'pageLength' => 32, 'totalSize' => $max);
     $this->assertEquals($expected, $set->getPageLimits(), 'The page limits match expected values.');
     // Finally check MySQL LIMIT syntax
     $set->parseQueryLimit($sql->limit('7, 7'));
     $expected = array('pageStart' => 7, 'pageLength' => 7, 'totalSize' => $max);
     $this->assertEquals($expected, $set->getPageLimits(), 'The page limits match expected values.');
 }