Adding a filterToParams method on the HTTP protocol. This allows you to specify how a filter is serialized in HTTP feature requests (using CQL for example). By default, we use the OpenLayers.Protocol.simpleFilterSerializer method. r=crschmidt (closes #3032)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11673 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2011-03-08 15:45:18 +00:00
parent f5769b8097
commit 49e96f352f
6 changed files with 487 additions and 424 deletions

View File

@@ -245,6 +245,7 @@
"OpenLayers/Filter/Spatial.js", "OpenLayers/Filter/Spatial.js",
"OpenLayers/Protocol.js", "OpenLayers/Protocol.js",
"OpenLayers/Protocol/HTTP.js", "OpenLayers/Protocol/HTTP.js",
"OpenLayers/Protocol/SimpleFilterSerializer.js",
"OpenLayers/Protocol/SQL.js", "OpenLayers/Protocol/SQL.js",
"OpenLayers/Protocol/SQL/Gears.js", "OpenLayers/Protocol/SQL/Gears.js",
"OpenLayers/Protocol/WFS.js", "OpenLayers/Protocol/WFS.js",

View File

@@ -13,6 +13,11 @@
* @requires OpenLayers/Request/XMLHttpRequest.js * @requires OpenLayers/Request/XMLHttpRequest.js
*/ */
/**
* TODO: remove this dependency in 3.0
* @requires OpenLayers/Protocol/SimpleFilterSerializer.js
*/
/** /**
* Class: OpenLayers.Protocol.HTTP * Class: OpenLayers.Protocol.HTTP
* A basic HTTP protocol for vector layers. Create a new instance with the * A basic HTTP protocol for vector layers. Create a new instance with the
@@ -109,6 +114,12 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
this.params = {}; this.params = {};
this.headers = {}; this.headers = {};
OpenLayers.Protocol.prototype.initialize.apply(this, arguments); OpenLayers.Protocol.prototype.initialize.apply(this, arguments);
if (!this.filterToParams && OpenLayers.Protocol.simpleFilterSerializer) {
this.filterToParams = OpenLayers.Function.bind(
OpenLayers.Protocol.simpleFilterSerializer, this
);
}
}, },
/** /**
@@ -121,6 +132,21 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
OpenLayers.Protocol.prototype.destroy.apply(this); OpenLayers.Protocol.prototype.destroy.apply(this);
}, },
/**
* APIMethod: filterToParams
* Optional method to translate an <OpenLayers.Filter> object into an object
* that can be serialized as request query string provided. If a custom
* method is not provided, the filter will be serialized using the
* <OpenLayers.Protocol.simpleFilterSerializer> method.
*
* Parameters:
* filter - {<OpenLayers.Filter>} filter to convert.
* params - {Object} The parameters object.
*
* Returns:
* {Object} The resulting parameters object.
*/
/** /**
* APIMethod: read * APIMethod: read
* Construct a request for reading new features. * Construct a request for reading new features.
@@ -148,9 +174,10 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
options = OpenLayers.Util.applyDefaults(options, this.options); options = OpenLayers.Util.applyDefaults(options, this.options);
options.params = OpenLayers.Util.applyDefaults( options.params = OpenLayers.Util.applyDefaults(
options.params, this.options.params); options.params, this.options.params);
if(options.filter) { if (options.filter && this.filterToParams) {
options.params = this.filterToParams( options.params = this.filterToParams(
options.filter, options.params); options.filter, options.params
);
} }
var readWithPOST = (options.readWithPOST !== undefined) ? var readWithPOST = (options.readWithPOST !== undefined) ?
options.readWithPOST : this.readWithPOST; options.readWithPOST : this.readWithPOST;
@@ -189,124 +216,6 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
this.handleResponse(resp, options); this.handleResponse(resp, options);
}, },
/**
* Method: filterToParams
* Convert an <OpenLayers.Filter> object to parameters.
*
* Parameters:
* filter - {OpenLayers.Filter} filter to convert.
* params - {Object} The parameters object.
*
* Returns:
* {Object} The resulting parameters object.
*/
filterToParams: function(filter, params) {
params = params || {};
var className = filter.CLASS_NAME;
var filterType = className.substring(className.lastIndexOf(".") + 1);
switch(filterType) {
case "Spatial":
switch(filter.type) {
case OpenLayers.Filter.Spatial.BBOX:
params.bbox = filter.value.toArray();
if (this.srsInBBOX && filter.projection) {
params.bbox.push(filter.projection.getCode());
}
break;
case OpenLayers.Filter.Spatial.DWITHIN:
params.tolerance = filter.distance;
// no break here
case OpenLayers.Filter.Spatial.WITHIN:
params.lon = filter.value.x;
params.lat = filter.value.y;
break;
default:
OpenLayers.Console.warn(
"Unknown spatial filter type " + filter.type);
}
break;
case "Comparison":
var op = OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type];
if(op !== undefined) {
var value = filter.value;
if(filter.type == OpenLayers.Filter.Comparison.LIKE) {
value = this.regex2value(value);
if(this.wildcarded) {
value = "%" + value + "%";
}
}
params[filter.property + "__" + op] = value;
params.queryable = params.queryable || [];
params.queryable.push(filter.property);
} else {
OpenLayers.Console.warn(
"Unknown comparison filter type " + filter.type);
}
break;
case "Logical":
if(filter.type === OpenLayers.Filter.Logical.AND) {
for(var i=0,len=filter.filters.length; i<len; i++) {
params = this.filterToParams(filter.filters[i], params);
}
} else {
OpenLayers.Console.warn(
"Unsupported logical filter type " + filter.type);
}
break;
default:
OpenLayers.Console.warn("Unknown filter type " + filterType);
}
return params;
},
/**
* Method: regex2value
* Convert the value from a regular expression string to a LIKE/ILIKE
* string known to the web service.
*
* Parameters:
* value - {String} The regex string.
*
* Returns:
* {String} The converted string.
*/
regex2value: function(value) {
// highly sensitive!! Do not change this without running the
// Protocol/HTTP.html unit tests
// convert % to \%
value = value.replace(/%/g, "\\%");
// convert \\. to \\_ (\\.* occurences converted later)
value = value.replace(/\\\\\.(\*)?/g, function($0, $1) {
return $1 ? $0 : "\\\\_";
});
// convert \\.* to \\%
value = value.replace(/\\\\\.\*/g, "\\\\%");
// convert . to _ (\. and .* occurences converted later)
value = value.replace(/(\\)?\.(\*)?/g, function($0, $1, $2) {
return $1 || $2 ? $0 : "_";
});
// convert .* to % (\.* occurnces converted later)
value = value.replace(/(\\)?\.\*/g, function($0, $1) {
return $1 ? $0 : "%";
});
// convert \. to .
value = value.replace(/\\\./g, ".");
// replace \* with * (watching out for \\*)
value = value.replace(/(\\)?\\\*/g, function($0, $1) {
return $1 ? $0 : "*";
});
return value;
},
/** /**
* APIMethod: create * APIMethod: create
* Construct a request for writing newly created features. * Construct a request for writing newly created features.
@@ -648,21 +557,3 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
CLASS_NAME: "OpenLayers.Protocol.HTTP" CLASS_NAME: "OpenLayers.Protocol.HTTP"
}); });
/**
* Property: OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR
* {Object} A private class-level property mapping the
* OpenLayers.Filter.Comparison types to the operation
* strings of the protocol.
*/
(function() {
var o = OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR = {};
o[OpenLayers.Filter.Comparison.EQUAL_TO] = "eq";
o[OpenLayers.Filter.Comparison.NOT_EQUAL_TO] = "ne";
o[OpenLayers.Filter.Comparison.LESS_THAN] = "lt";
o[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO] = "lte";
o[OpenLayers.Filter.Comparison.GREATER_THAN] = "gt";
o[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO] = "gte";
o[OpenLayers.Filter.Comparison.LIKE] = "ilike";
})();

View File

@@ -0,0 +1,145 @@
/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Protocol.js
*/
/**
* Function: OpenLayers.Protocol.simpleFilterSerializer
* Serialize an <OpenLayers.Filter> objects using the "simple" filter syntax for
* query string parameters. This function must be called as a method of
* a protocol instance.
*
* Parameters:
* filter - {<OpenLayers.Filter>} filter to convert.
* params - {Object} The parameters object.
*
* Returns:
* {Object} The resulting parameters object.
*/
OpenLayers.Protocol.simpleFilterSerializer = (function() {
/**
* Map the OpenLayers.Filter.Comparison types to the operation strings of
* the protocol.
*/
var cmpToStr = {};
cmpToStr[OpenLayers.Filter.Comparison.EQUAL_TO] = "eq";
cmpToStr[OpenLayers.Filter.Comparison.NOT_EQUAL_TO] = "ne";
cmpToStr[OpenLayers.Filter.Comparison.LESS_THAN] = "lt";
cmpToStr[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO] = "lte";
cmpToStr[OpenLayers.Filter.Comparison.GREATER_THAN] = "gt";
cmpToStr[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO] = "gte";
cmpToStr[OpenLayers.Filter.Comparison.LIKE] = "ilike";
/**
* Function: regex2value
* Convert the value from a regular expression string to a LIKE/ILIKE
* string known to the web service.
*
* Parameters:
* value - {String} The regex string.
*
* Returns:
* {String} The converted string.
*/
function regex2value(value) {
// highly sensitive!! Do not change this without running the
// Protocol/HTTP.html unit tests
// convert % to \%
value = value.replace(/%/g, "\\%");
// convert \\. to \\_ (\\.* occurences converted later)
value = value.replace(/\\\\\.(\*)?/g, function($0, $1) {
return $1 ? $0 : "\\\\_";
});
// convert \\.* to \\%
value = value.replace(/\\\\\.\*/g, "\\\\%");
// convert . to _ (\. and .* occurences converted later)
value = value.replace(/(\\)?\.(\*)?/g, function($0, $1, $2) {
return $1 || $2 ? $0 : "_";
});
// convert .* to % (\.* occurnces converted later)
value = value.replace(/(\\)?\.\*/g, function($0, $1) {
return $1 ? $0 : "%";
});
// convert \. to .
value = value.replace(/\\\./g, ".");
// replace \* with * (watching out for \\*)
value = value.replace(/(\\)?\\\*/g, function($0, $1) {
return $1 ? $0 : "*";
});
return value;
}
return function simpleFilterSerializer(filter, params) {
params = params || {};
var className = filter.CLASS_NAME;
var filterType = className.substring(className.lastIndexOf(".") + 1);
switch (filterType) {
case "Spatial":
switch (filter.type) {
case OpenLayers.Filter.Spatial.BBOX:
params.bbox = filter.value.toArray();
if (this.srsInBBOX && filter.projection) {
params.bbox.push(filter.projection.getCode());
}
break;
case OpenLayers.Filter.Spatial.DWITHIN:
params.tolerance = filter.distance;
// no break here
case OpenLayers.Filter.Spatial.WITHIN:
params.lon = filter.value.x;
params.lat = filter.value.y;
break;
default:
OpenLayers.Console.warn(
"Unknown spatial filter type " + filter.type);
}
break;
case "Comparison":
var op = cmpToStr[filter.type];
if (op !== undefined) {
var value = filter.value;
if (filter.type == OpenLayers.Filter.Comparison.LIKE) {
value = regex2value(value);
if (this.wildcarded) {
value = "%" + value + "%";
}
}
params[filter.property + "__" + op] = value;
params.queryable = params.queryable || [];
params.queryable.push(filter.property);
} else {
OpenLayers.Console.warn(
"Unknown comparison filter type " + filter.type);
}
break;
case "Logical":
if (filter.type === OpenLayers.Filter.Logical.AND) {
for (var i=0,len=filter.filters.length; i<len; i++) {
params = this.filterToParams(filter.filters[i], params);
}
} else {
OpenLayers.Console.warn(
"Unsupported logical filter type " + filter.type);
}
break;
default:
OpenLayers.Console.warn("Unknown filter type " + filterType);
}
return params;
};
})();

View File

@@ -287,291 +287,6 @@
t.eq(ret, null, 'parseFeatures returns expected value'); t.eq(ret, null, 'parseFeatures returns expected value');
} }
function test_filterToParams(t) {
t.plan(30);
// setup
var protocol, filter, params;
protocol = new OpenLayers.Protocol.HTTP();
// 1 test
var filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 1, 2, 3)
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 1, 2, 3],
"filterToParams sets correct bbox param if passed a BBOX filter");
// 3 tests
var lon = 100, lat = 200, tolerance = 10;
filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.DWITHIN,
value: new OpenLayers.Geometry.Point(lon, lat),
distance: tolerance
});
params = protocol.filterToParams(filter);
t.eq(params.lon, lon,
"filterToParams sets correct lon param if passed a DWITHIN filter");
t.eq(params.lat, lat,
"filterToParams sets correct lat param if passed a DWITHIN filter");
t.eq(params.tolerance, tolerance,
"filterToParams sets correct tolerance param if passed a DWITHIN filter");
// 2 tests
filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.WITHIN,
value: new OpenLayers.Geometry.Point(lon, lat)
});
params = protocol.filterToParams(filter);
t.eq(params.lon, lon,
"filterToParams sets correct lon param if passed a WITHIN filter");
t.eq(params.lat, lat,
"filterToParams sets correct lat param if passed a WITHIN filter");
// Some bbox filters used in the next tests.
var bboxFilter1 = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 0, 10, 10)
});
var bboxFilter2 = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 0, 20, 20)
});
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: []
});
params = protocol.filterToParams(filter);
t.eq(params, {},
"filterToParams returns empty object if given empty AND Logical filter");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.OR,
filters: [
bboxFilter1
]
});
params = protocol.filterToParams(filter);
t.eq(params, {},
"filterToParams does not support OR Logical filter");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
bboxFilter1
]
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 0, 10, 10],
"filterToParams sets correct bbox param if passed " +
"a Logical filter containing a BBOX");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
bboxFilter1, bboxFilter2
]
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 0, 20, 20],
"filterToParams sets correct bbox param if passed " +
"multiple BBOX filter in a Logical filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an EQUAL_TO filter");
t.eq(params["foo__eq"], "bar",
"filterToParams sets correct param key and value if passed an EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an NOT_EQUAL_TO filter");
t.eq(params["foo__ne"], "bar",
"filterToParams sets correct param key and value if passed an NOT_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: "foo",
value: "bar"
});
var params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an LESS_THAN filter");
t.eq(params["foo__lt"], "bar",
"filterToParams sets correct param key and value if passed an LESS_THAN filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,
property: "foo",
value: "bar"
});
var params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an LESS_THAN_OR_EQUAL_TO filter");
t.eq(params["foo__lte"], "bar",
"filterToParams sets correct param key and value if passed an LESS_THAN_OR_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an GREATER_THAN filter");
t.eq(params["foo__gt"], "bar",
"filterToParams sets correct param key and value if passed an GREATER_THAN filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an GREATER_THAN_OR_EQUAL_TO filter");
t.eq(params["foo__gte"], "bar",
"filterToParams sets correct param key and value if passed an GREATER_THAN_OR_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed a LIKE filter");
t.eq(params["foo__ilike"], "bar",
"filterToParams sets correct param key and value if passed an LIKE filter");
// 4 tests
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "foo",
value: "bar"
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: "foo2",
value: "baz"
})
]
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an EQUAL_TO filter within a AND filter");
t.eq(params["foo__eq"], "bar",
"filterToParams sets correct param key and value if passed an EQUAL_TO filter within a AND filter");
t.eq(params.queryable[1], "foo2",
"filterToParams sets correct queryable param if passed a LESS_THAN filter within a AND filter");
t.eq(params["foo2__lt"], "baz",
"filterToParams sets correct param key and value if passed a LESS_THAN filter within a AND filter");
// 2 tests
protocol = new OpenLayers.Protocol.HTTP({wildcarded: true});
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed a LIKE filter (wildcarded true)");
t.eq(params["foo__ilike"], "%bar%",
"filterToParams sets correct param key and value if passed an LIKE filter (wildcarded true)");
}
function test_regex2value(t) {
t.plan(16);
// setup
var protocol = new OpenLayers.Protocol.HTTP();
var value;
// test
value = protocol.regex2value("foo");
t.eq(value, "foo", 'regex2value converts "foo" to "foo"');
value = protocol.regex2value("foo%");
t.eq(value, "foo\\%", 'regex2value converts "foo%" to "foo\\%"');
value = protocol.regex2value("foo.*");
t.eq(value, "foo%", 'regex2value converts "foo.*" to "foo%"');
value = protocol.regex2value("f.*oo.*");
t.eq(value, "f%oo%", 'regex2value converts "f.*oo.*" to "f%oo%"');
value = protocol.regex2value("foo.");
t.eq(value, "foo_", 'regex2value converts "foo." to "foo_"');
value = protocol.regex2value("f.oo.");
t.eq(value, "f_oo_", 'regex2value converts "f.oo." to "f_oo_"');
value = protocol.regex2value("f.oo.*");
t.eq(value, "f_oo%", 'regex2value converts "f.oo.*" to "f_oo%"');
value = protocol.regex2value("foo\\\\");
t.eq(value, "foo\\\\", 'regex2value converts "foo\\\\" to "foo\\\\"');
value = protocol.regex2value("foo\\.");
t.eq(value, "foo.", 'regex2value converts "foo\\." to "foo."');
value = protocol.regex2value("foo\\\\.");
t.eq(value, "foo\\\\_", 'regex2value converts "foo\\\\." to "foo\\\\_"');
value = protocol.regex2value("foo\\*");
t.eq(value, "foo*", 'regex2value converts "foo\\*" to "foo*"');
value = protocol.regex2value("foo\\\\*");
t.eq(value, "foo\\\\*", 'regex2value converts "foo\\\\*" to "foo\\\\*"');
value = protocol.regex2value("foo\\\\.*");
t.eq(value, "foo\\\\%", 'regex2value converts "foo\\\\.*" to "foo\\\\%"');
value = protocol.regex2value("fo\\.o.*");
t.eq(value, "fo.o%", 'regex2value converts from "fo\\.o.*" to "fo.o%"');
value = protocol.regex2value("fo.*o\\.");
t.eq(value, "fo%o.", 'regex2value converts from "fo.*o\\." to "to%o."');
value = protocol.regex2value("\\*\\..*.\\\\.*\\\\.%");
t.eq(value, "*.%_\\\\%\\\\_\\%",
'regex2value converts from "\\*\\..*.\\\\.*\\\\.%" ' +
'to "*.%_\\\\%\\\\_\\%"');
}
function test_create(t) { function test_create(t) {
t.plan(10); t.plan(10);
var protocol = new OpenLayers.Protocol.HTTP({ var protocol = new OpenLayers.Protocol.HTTP({

View File

@@ -0,0 +1,310 @@
<html>
<head>
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
function test_filterToParams(t) {
t.plan(30);
// setup
var protocol, filter, params;
protocol = new OpenLayers.Protocol.HTTP({
filterToParams: OpenLayers.Protocol.simpleFilterSerializer
});
// 1 test
var filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 1, 2, 3)
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 1, 2, 3],
"filterToParams sets correct bbox param if passed a BBOX filter");
// 3 tests
var lon = 100, lat = 200, tolerance = 10;
filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.DWITHIN,
value: new OpenLayers.Geometry.Point(lon, lat),
distance: tolerance
});
params = protocol.filterToParams(filter);
t.eq(params.lon, lon,
"filterToParams sets correct lon param if passed a DWITHIN filter");
t.eq(params.lat, lat,
"filterToParams sets correct lat param if passed a DWITHIN filter");
t.eq(params.tolerance, tolerance,
"filterToParams sets correct tolerance param if passed a DWITHIN filter");
// 2 tests
filter = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.WITHIN,
value: new OpenLayers.Geometry.Point(lon, lat)
});
params = protocol.filterToParams(filter);
t.eq(params.lon, lon,
"filterToParams sets correct lon param if passed a WITHIN filter");
t.eq(params.lat, lat,
"filterToParams sets correct lat param if passed a WITHIN filter");
// Some bbox filters used in the next tests.
var bboxFilter1 = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 0, 10, 10)
});
var bboxFilter2 = new OpenLayers.Filter.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(0, 0, 20, 20)
});
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: []
});
params = protocol.filterToParams(filter);
t.eq(params, {},
"filterToParams returns empty object if given empty AND Logical filter");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.OR,
filters: [
bboxFilter1
]
});
params = protocol.filterToParams(filter);
t.eq(params, {},
"filterToParams does not support OR Logical filter");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
bboxFilter1
]
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 0, 10, 10],
"filterToParams sets correct bbox param if passed " +
"a Logical filter containing a BBOX");
// 1 test
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
bboxFilter1, bboxFilter2
]
});
params = protocol.filterToParams(filter);
t.eq(params.bbox, [0, 0, 20, 20],
"filterToParams sets correct bbox param if passed " +
"multiple BBOX filter in a Logical filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an EQUAL_TO filter");
t.eq(params["foo__eq"], "bar",
"filterToParams sets correct param key and value if passed an EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an NOT_EQUAL_TO filter");
t.eq(params["foo__ne"], "bar",
"filterToParams sets correct param key and value if passed an NOT_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: "foo",
value: "bar"
});
var params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an LESS_THAN filter");
t.eq(params["foo__lt"], "bar",
"filterToParams sets correct param key and value if passed an LESS_THAN filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,
property: "foo",
value: "bar"
});
var params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an LESS_THAN_OR_EQUAL_TO filter");
t.eq(params["foo__lte"], "bar",
"filterToParams sets correct param key and value if passed an LESS_THAN_OR_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an GREATER_THAN filter");
t.eq(params["foo__gt"], "bar",
"filterToParams sets correct param key and value if passed an GREATER_THAN filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an GREATER_THAN_OR_EQUAL_TO filter");
t.eq(params["foo__gte"], "bar",
"filterToParams sets correct param key and value if passed an GREATER_THAN_OR_EQUAL_TO filter");
// 2 tests
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed a LIKE filter");
t.eq(params["foo__ilike"], "bar",
"filterToParams sets correct param key and value if passed an LIKE filter");
// 4 tests
filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "foo",
value: "bar"
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: "foo2",
value: "baz"
})
]
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed an EQUAL_TO filter within a AND filter");
t.eq(params["foo__eq"], "bar",
"filterToParams sets correct param key and value if passed an EQUAL_TO filter within a AND filter");
t.eq(params.queryable[1], "foo2",
"filterToParams sets correct queryable param if passed a LESS_THAN filter within a AND filter");
t.eq(params["foo2__lt"], "baz",
"filterToParams sets correct param key and value if passed a LESS_THAN filter within a AND filter");
// 2 tests
protocol = new OpenLayers.Protocol.HTTP({wildcarded: true});
filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: "foo",
value: "bar"
});
params = protocol.filterToParams(filter);
t.eq(params.queryable[0], "foo",
"filterToParams sets correct queryable param if passed a LIKE filter (wildcarded true)");
t.eq(params["foo__ilike"], "%bar%",
"filterToParams sets correct param key and value if passed an LIKE filter (wildcarded true)");
}
function test_regex2value(t) {
t.plan(16);
// setup
var protocol = new OpenLayers.Protocol.HTTP({
filterToParams: OpenLayers.Protocol.simpleFilterSerializer
});
var value;
var filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: "prop"
});
function serialize(value) {
filter.value = value;
return protocol.filterToParams(filter).prop__ilike;
}
// test
value = serialize("foo");
t.eq(value, "foo", 'regex2value converts "foo" to "foo"');
value = serialize("foo%");
t.eq(value, "foo\\%", 'regex2value converts "foo%" to "foo\\%"');
value = serialize("foo.*");
t.eq(value, "foo%", 'regex2value converts "foo.*" to "foo%"');
value = serialize("f.*oo.*");
t.eq(value, "f%oo%", 'regex2value converts "f.*oo.*" to "f%oo%"');
value = serialize("foo.");
t.eq(value, "foo_", 'regex2value converts "foo." to "foo_"');
value = serialize("f.oo.");
t.eq(value, "f_oo_", 'regex2value converts "f.oo." to "f_oo_"');
value = serialize("f.oo.*");
t.eq(value, "f_oo%", 'regex2value converts "f.oo.*" to "f_oo%"');
value = serialize("foo\\\\");
t.eq(value, "foo\\\\", 'regex2value converts "foo\\\\" to "foo\\\\"');
value = serialize("foo\\.");
t.eq(value, "foo.", 'regex2value converts "foo\\." to "foo."');
value = serialize("foo\\\\.");
t.eq(value, "foo\\\\_", 'regex2value converts "foo\\\\." to "foo\\\\_"');
value = serialize("foo\\*");
t.eq(value, "foo*", 'regex2value converts "foo\\*" to "foo*"');
value = serialize("foo\\\\*");
t.eq(value, "foo\\\\*", 'regex2value converts "foo\\\\*" to "foo\\\\*"');
value = serialize("foo\\\\.*");
t.eq(value, "foo\\\\%", 'regex2value converts "foo\\\\.*" to "foo\\\\%"');
value = serialize("fo\\.o.*");
t.eq(value, "fo.o%", 'regex2value converts from "fo\\.o.*" to "fo.o%"');
value = serialize("fo.*o\\.");
t.eq(value, "fo%o.", 'regex2value converts from "fo.*o\\." to "to%o."');
value = serialize("\\*\\..*.\\\\.*\\\\.%");
t.eq(value, "*.%_\\\\%\\\\_\\%",
'regex2value converts from "\\*\\..*.\\\\.*\\\\.%" ' +
'to "*.%_\\\\%\\\\_\\%"');
}
</script>
</head>
<body>
</body>
</html>

View File

@@ -177,6 +177,7 @@
<li>Projection.html</li> <li>Projection.html</li>
<li>Protocol.html</li> <li>Protocol.html</li>
<li>Protocol/HTTP.html</li> <li>Protocol/HTTP.html</li>
<li>Protocol/SimpleFilterSerializer.html</li>
<li>Protocol/SQL.html</li> <li>Protocol/SQL.html</li>
<li>Protocol/SQL/Gears.html</li> <li>Protocol/SQL/Gears.html</li>
<li>Protocol/WFS.html</li> <li>Protocol/WFS.html</li>