[Mapbender-commits] r6768 - in trunk/mapbender: http/classes lib test/http/classes

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Thu Aug 19 12:02:21 EDT 2010


Author: christoph
Date: 2010-08-19 16:02:21 +0000 (Thu, 19 Aug 2010)
New Revision: 6768

Added:
   trunk/mapbender/lib/class_Filter.php
   trunk/mapbender/test/http/classes/FilterTest.php
Modified:
   trunk/mapbender/http/classes/class_RPCEndpoint.php
Log:
added class Filter

Modified: trunk/mapbender/http/classes/class_RPCEndpoint.php
===================================================================
--- trunk/mapbender/http/classes/class_RPCEndpoint.php	2010-08-19 15:59:06 UTC (rev 6767)
+++ trunk/mapbender/http/classes/class_RPCEndpoint.php	2010-08-19 16:02:21 UTC (rev 6768)
@@ -1,4 +1,5 @@
 <?php
+require_once dirname(__FILE__)."/../../lib/class_Filter.php";
 
 interface RPCObject{
 

Added: trunk/mapbender/lib/class_Filter.php
===================================================================
--- trunk/mapbender/lib/class_Filter.php	                        (rev 0)
+++ trunk/mapbender/lib/class_Filter.php	2010-08-19 16:02:21 UTC (rev 6768)
@@ -0,0 +1,119 @@
+<?php
+# License:
+# Copyright (c) 2009, Open Source Geospatial Foundation
+# This program is dual licensed under the GNU General Public License 
+# and Simplified BSD license.  
+# http://svn.osgeo.org/mapbender/trunk/mapbender/license/license.txt
+
+class Filter {
+	// simple filter
+	protected $operator;
+	protected $key;
+	protected $value;
+
+	// complex filter
+	protected $booleanOperator;
+	protected $filterArray;
+
+	const OPERATORS = "=,>,>=,<,<=,<>,LIKE,ILIKE,IN";
+	const BOOLEAN_OPERATORS = "AND,OR";
+
+	public function __construct () {
+		if (func_num_args() === 3) {
+			if (!in_array(func_get_arg(0), explode(",", Filter::OPERATORS))) {
+				throw new Exception ("Filter: Invalid operator " . func_get_arg(0)); 
+			}
+			$this->operator = func_get_arg(0);
+			
+			if (!is_string(func_get_arg(1)) || func_get_arg(1) === "") {
+				throw new Exception ("Filter: Invalid key " . func_get_arg(1)); 
+			}
+			$this->key = func_get_arg(1);
+			
+			$this->value = func_get_arg(2);
+		}
+		if (func_num_args() === 2) {
+			if (!in_array(func_get_arg(0), explode(",", Filter::BOOLEAN_OPERATORS))) {
+				throw new Exception ("Filter: Invalid boolean operator " . func_get_arg(0)); 
+			}
+			$this->booleanOperator = func_get_arg(0);
+			
+			if (is_array(func_get_arg(1))) {
+				foreach (func_get_arg(1) as $filter) {
+					if (!is_a($filter, "Filter")) {
+						throw new Exception("Filter: Not a valid filter.");
+					}
+				}
+				$this->filterArray = func_get_arg(1);
+			}
+		}
+	}
+	
+	protected function isComplex () {
+		if (in_array($this->booleanOperator, explode(",", Filter::BOOLEAN_OPERATORS)) &&
+			is_array($this->filterArray)
+		) {
+			foreach ($this->filterArray as $filter) {
+				if (!is_a($filter, "Filter")) {
+					throw new Exception("Filter: Not a valid filter.");
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	private function getType ($v) {
+		if (is_float($v) || is_integer($v)) {
+			return "i";
+		}
+		return "s";
+	}
+	
+	public function toSql ($parameterCount = 1) {
+		$sqlObject = new stdClass();
+		$sqlObject->sql = "";
+		$sqlObject->v = array();
+		$sqlObject->t = array();			
+		
+		if ($this->isComplex()) {
+			$i = $parameterCount;
+			foreach ($this->filterArray as $filter) {
+				$currentSqlObject = $filter->toSql($i);
+				$currentBooleanOperator = ($i === $parameterCount) ? 
+					"" : " " . $this->booleanOperator . " ";
+				$sqlObject->sql .= $currentBooleanOperator . 
+					$currentSqlObject->sql;
+				$sqlObject->v = array_merge($sqlObject->v, $currentSqlObject->v);
+				$sqlObject->t = array_merge($sqlObject->t, $currentSqlObject->t);
+				$i += count($currentSqlObject->v);
+			}
+			$sqlObject->sql = "(" . $sqlObject->sql . ")";
+			return $sqlObject;
+		}
+		else {
+			if (is_array($this->value)) {
+				if ($this->operator === "IN") {
+					$parameters = array();
+					foreach ($this->value as $value) {
+						$parameters[]= "$" . $parameterCount++;
+						$sqlObject->v[]= $value;
+						$sqlObject->t[]= $this->getType($value);			
+					}
+					$sqlObject->sql = $this->key . " " . $this->operator . 
+						" (" . implode(",", $parameters) . ")";
+				}
+				else {
+					throw new Exception("Filter: Multiple values only supported for IN.");
+				}
+			}
+			else {
+				$sqlObject->sql = $this->key . $this->operator . "$" . $parameterCount;
+				$sqlObject->v = array($this->value);
+				$sqlObject->t = array($this->getType($this->value));			
+			}
+			return $sqlObject;			
+		}
+	}
+}
+?>
\ No newline at end of file

Added: trunk/mapbender/test/http/classes/FilterTest.php
===================================================================
--- trunk/mapbender/test/http/classes/FilterTest.php	                        (rev 0)
+++ trunk/mapbender/test/http/classes/FilterTest.php	2010-08-19 16:02:21 UTC (rev 6768)
@@ -0,0 +1,54 @@
+<?php
+require_once 'PHPUnit/Framework.php';
+require_once dirname(__FILE__) . "/../../../lib/class_Filter.php";
+
+class FilterTest extends PHPUnit_Framework_TestCase {
+
+	public function testConstructorOperatorKeyValue () {
+		$filter = new Filter("=", "a", "b");
+		$sqlObject = new stdClass();
+		$sqlObject->sql = "a=$1";
+		$sqlObject->v = array("b");
+		$sqlObject->t = array("s");
+		$this->assertEquals($sqlObject, $filter->toSql());
+	}
+
+	public function testConstructorOperatorKeyValueArray () {
+		$filter = new Filter("IN", "a", array("a", "b", "c"));
+		$sqlObject = new stdClass();
+		$sqlObject->sql = "a IN ($1,$2,$3)";
+		$sqlObject->v = array("a", "b", "c");
+		$sqlObject->t = array("s", "s", "s");
+		$this->assertEquals($sqlObject, $filter->toSql());
+	}
+
+	public function testConstructorOperatorFilterArray () {
+		$filterA = new Filter("=", "a", "b");
+		$filterB = new Filter(">=", "b", 3);
+
+		$filter = new Filter("AND", array($filterA, $filterB));
+		$sqlObject = new stdClass();
+		$sqlObject->sql = "(a=$1 AND b>=$2)";
+		$sqlObject->v = array("b", 3);
+		$sqlObject->t = array("s", "i");
+		$this->assertEquals($sqlObject, $filter->toSql());
+	}
+	
+	public function testConstructorRecursive() {
+		$filterA1 = new Filter("=", "a", "b");
+		$filterB1 = new Filter(">=", "b", 3);
+		$filter1all = new Filter("AND",array($filterA1,$filterB1));
+		
+		$filterA2 = new Filter("=", "c", "d");
+		$filterB2 = new Filter(">=", "e", 4);
+		$filter2all = new Filter("AND",array($filterA2,$filterB2));
+
+		$filter = new Filter("AND", array($filter1all, $filter2all));
+		$sqlObject = new stdClass();
+		$sqlObject->sql = "((a=$1 AND b>=$2) AND (c=$3 AND e>=$4))";
+		$sqlObject->v = array("b", 3, "d", 4);
+		$sqlObject->t = array("s", "i","s", "i");
+		$this->assertEquals($sqlObject, $filter->toSql());
+	}
+}
+?>
\ No newline at end of file



More information about the Mapbender_commits mailing list