Compare commits
48 Commits
python-0.1
...
python-0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1936374124 | ||
|
|
988a0c31dc | ||
|
|
0cd01ee9c9 | ||
|
|
3ed41b065a | ||
|
|
6c3260b6ee | ||
|
|
5005572f89 | ||
|
|
27fde5a910 | ||
|
|
b8e1120169 | ||
|
|
8e33cf9723 | ||
|
|
7b988e3f78 | ||
|
|
f79ac9297d | ||
|
|
854fbb803c | ||
|
|
d029ad7041 | ||
|
|
24c29c0847 | ||
|
|
31e79cb626 | ||
|
|
98eef7ae02 | ||
|
|
445d4cf97d | ||
|
|
3a86ffba71 | ||
|
|
f0a3249b4e | ||
|
|
ef7c5d9218 | ||
|
|
bd63346c50 | ||
|
|
c878384955 | ||
|
|
475df918c7 | ||
|
|
937440c79a | ||
|
|
cb39640179 | ||
|
|
727e5c09a9 | ||
|
|
c13dba71a4 | ||
|
|
55cd62f6dc | ||
|
|
00424a0314 | ||
|
|
2ed183a05c | ||
|
|
9971a0aeed | ||
|
|
e30b081cbc | ||
|
|
797a2dbd24 | ||
|
|
a297504c63 | ||
|
|
5f499c0d1c | ||
|
|
3eee68c56e | ||
|
|
c982c6e4fb | ||
|
|
f5037aab5e | ||
|
|
0e7a777787 | ||
|
|
0cd0087f3f | ||
|
|
13a876b854 | ||
|
|
82b7a95af6 | ||
|
|
928d1111f3 | ||
|
|
e11bc698c3 | ||
|
|
6d802c72be | ||
|
|
1ffbba2a03 | ||
|
|
acd385dc82 | ||
|
|
7281c4a0e3 |
35
NEWS.md
35
NEWS.md
@@ -1,3 +1,38 @@
|
|||||||
|
October 6th, 2017
|
||||||
|
=================
|
||||||
|
* Version `0.15.5` of the python library
|
||||||
|
* googlemaps dependency updated to v2.5.1
|
||||||
|
* Google geocoder performance boost: client connections are now reused between queries. See #401
|
||||||
|
* Fixed issue with Google keys validity check. See #382
|
||||||
|
* Fixed inconsistency in service usage failed requests tracking. See f0a3249
|
||||||
|
* Client extension tests are now compatible with PostgreSQL 9.5 and 9.6
|
||||||
|
|
||||||
|
August 30th, 2017
|
||||||
|
=============
|
||||||
|
* Version `0.15.4` of the python library
|
||||||
|
* Fixed invalid geometries for isochrones due to `generalize` option. See #397
|
||||||
|
|
||||||
|
August 24th, 2017
|
||||||
|
=============
|
||||||
|
* Improved the documentation
|
||||||
|
* Version `0.15.3` of the python library
|
||||||
|
* Disabled DO quota check for users that have it configured . See #395
|
||||||
|
|
||||||
|
August 23th, 2017
|
||||||
|
=============
|
||||||
|
* Version `0.27.0` of the server
|
||||||
|
* New public DO function to perform metadata validation, `obs_metadatavalidation`. See #392
|
||||||
|
* Version `0.20.0` of the client
|
||||||
|
* New private function to precheck the DO requests, `_obs_precheck`. See #392
|
||||||
|
* New public DO function to perform metadata validation, `obs_metadatavalidation`. See #392
|
||||||
|
|
||||||
|
July 20th, 2017
|
||||||
|
=============
|
||||||
|
* Version `0.26.0` of the server
|
||||||
|
* New private function to be used by the UI, `_obs_getnumerators`. See #386
|
||||||
|
* Version `0.19.0` of the client
|
||||||
|
* New private function to be used by the UI, `_obs_getnumerators`. See #386
|
||||||
|
|
||||||
July 13th, 2017
|
July 13th, 2017
|
||||||
=============
|
=============
|
||||||
* Version `0.25.0` of the server
|
* Version `0.25.0` of the server
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -92,7 +92,7 @@ Steps to deploy a new Data Services API version :
|
|||||||
```
|
```
|
||||||
- Give permission to execute and select to the `dataservices_user` user:
|
- Give permission to execute and select to the `dataservices_user` user:
|
||||||
```
|
```
|
||||||
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS observatory; COMMIT" -e
|
psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS observatory VERSION 'dev'; COMMIT" -e
|
||||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
||||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO dataservices_user; COMMIT" -e
|
||||||
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA observatory TO dataservices_user; COMMIT" -e
|
psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA observatory TO dataservices_user; COMMIT" -e
|
||||||
@@ -254,14 +254,16 @@ jsonb_set(
|
|||||||
```
|
```
|
||||||
### User database configuration
|
### User database configuration
|
||||||
|
|
||||||
|
#### Option 1 (manually)
|
||||||
|
|
||||||
User (client) databases need also some configuration so that the client extension can access the server:
|
User (client) databases need also some configuration so that the client extension can access the server:
|
||||||
#### Users/Organizations
|
##### Users/Organizations
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT CDB_Conf_SetConf('user_config', '{"is_organization": false, "entity_name": "<YOUR_USERNAME>"}');
|
SELECT CDB_Conf_SetConf('user_config', '{"is_organization": false, "entity_name": "<YOUR_USERNAME>"}');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Dataservices server
|
##### Dataservices server
|
||||||
|
|
||||||
The `geocoder_server_config` (the name is not accurate for historical reasons) entry points
|
The `geocoder_server_config` (the name is not accurate for historical reasons) entry points
|
||||||
to the dataservices server DB (you can use a specific database for the server or your same user's):
|
to the dataservices server DB (you can use a specific database for the server or your same user's):
|
||||||
@@ -272,10 +274,14 @@ SELECT CDB_Conf_SetConf(
|
|||||||
'{ "connection_str": "host=localhost port=5432 dbname=<SERVER_DB_NAME> user=postgres"}'
|
'{ "connection_str": "host=localhost port=5432 dbname=<SERVER_DB_NAME> user=postgres"}'
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
#### Search path
|
##### Search path
|
||||||
|
|
||||||
The search path must be configured in order to be able to execute the functions without using the schema:
|
The search path must be configured in order to be able to execute the functions without using the schema:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER ROLE "<USER_ROLE>" SET search_path="$user", public, cartodb, cdb_dataservices_client;
|
ALTER ROLE "<USER_ROLE>" SET search_path="$user", public, cartodb, cdb_dataservices_client;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Option 2 (from builder)
|
||||||
|
|
||||||
|
See [the **Configuring Dataservices** documentation](http://cartodb.readthedocs.io/en/latest/operations/configure_data_services.html)
|
||||||
@@ -21,7 +21,7 @@ DATA = $(NEW_EXTENSION_ARTIFACT) \
|
|||||||
SOURCES_DATA_DIR = sql/
|
SOURCES_DATA_DIR = sql/
|
||||||
|
|
||||||
|
|
||||||
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
REGRESS = $(notdir $(basename $(sort $(wildcard test/sql/*test.sql))))
|
||||||
TEST_DIR = test/
|
TEST_DIR = test/
|
||||||
REGRESS_OPTS = --inputdir='$(TEST_DIR)' --outputdir='$(TEST_DIR)' --user='postgres'
|
REGRESS_OPTS = --inputdir='$(TEST_DIR)' --outputdir='$(TEST_DIR)' --user='postgres'
|
||||||
|
|
||||||
|
|||||||
122
client/cdb_dataservices_client--0.19.0--0.20.0.sql
Normal file
122
client/cdb_dataservices_client--0.19.0--0.20.0.sql
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.20.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- Make sure we have a sane search path to create/update the extension
|
||||||
|
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._OBS_PreCheck(
|
||||||
|
source_query text,
|
||||||
|
parameters json
|
||||||
|
) RETURNS boolean AS $$
|
||||||
|
DECLARE
|
||||||
|
errors text[];
|
||||||
|
validator_errors text[];
|
||||||
|
validator_error text;
|
||||||
|
valid boolean;
|
||||||
|
geoms record;
|
||||||
|
BEGIN
|
||||||
|
errors := (ARRAY[])::TEXT[];
|
||||||
|
FOR geoms IN EXECUTE format('SELECT ST_GeometryType(the_geom) as geom_type,
|
||||||
|
bool_and(st_isvalid(the_geom)) as valid,
|
||||||
|
avg(st_npoints(the_geom)) as avg_vertex,
|
||||||
|
ST_SetSRID(ST_Extent(the_geom), 4326) as extent,
|
||||||
|
count(*)::INT as numgeoms
|
||||||
|
FROM (%s) as _source
|
||||||
|
GROUP BY ST_GeometryType(the_geom)', source_query)
|
||||||
|
LOOP
|
||||||
|
IF geoms.geom_type NOT IN ('ST_Polygon', 'ST_MultiPolygon', 'ST_Point') THEN
|
||||||
|
errors := array_append(errors, format($data$'Geometry type %s not supported'$data$, geoms.geom_type));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF geoms.valid IS FALSE THEN
|
||||||
|
errors := array_append(errors, 'There are invalid geometries in the input data, please review them');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 1000 vertex for a geometry is a limit we have in the obs_getdata function. You can check here
|
||||||
|
-- https://github.com/CartoDB/observatory-extension/blob/1.6.0/src/pg/sql/41_observatory_augmentation.sql#L813
|
||||||
|
IF geoms.avg_vertex > 1000 THEN
|
||||||
|
errors := array_append(errors, 'The average number of geometries vertex is greater than 1000, please try to simplify them');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- OBS specific part
|
||||||
|
EXECUTE 'SELECT valid, errors
|
||||||
|
FROM cdb_dataservices_client.OBS_MetadataValidation($1, $2, $3, $4)'
|
||||||
|
INTO valid, validator_errors
|
||||||
|
USING geoms.extent, geoms.geom_type, parameters, geoms.numgeoms;
|
||||||
|
IF valid is FALSE THEN
|
||||||
|
FOR validator_error IN EXECUTE 'SELECT unnest($1)' USING validator_errors
|
||||||
|
LOOP
|
||||||
|
errors := array_append(errors, validator_error);
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
IF CARDINALITY(errors) > 0 THEN
|
||||||
|
RAISE EXCEPTION '%', errors;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN TRUE;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_metadatavalidation (username text, orgname text, geom_extent Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
CONNECT cdb_dataservices_client._server_conn_str();
|
||||||
|
SELECT * FROM cdb_dataservices_server.obs_metadatavalidation (username, orgname, geom_extent, geom_type, params, target_geoms);
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_metadatavalidation (geom_extent Geometry(Geometry, 4326) ,geom_type text ,params json ,target_geoms integer DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
DECLARE
|
||||||
|
username text;
|
||||||
|
orgname text;
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN
|
||||||
|
RAISE EXCEPTION 'The api_key must be provided';
|
||||||
|
END IF;
|
||||||
|
SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text);
|
||||||
|
-- JSON value stored "" is taken as literal
|
||||||
|
IF username IS NULL OR username = '' OR username = '""' THEN
|
||||||
|
RAISE EXCEPTION 'Username is a mandatory argument, check it out';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_metadatavalidation(username, orgname, geom_extent, geom_type, params, target_geoms);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_metadatavalidation_exception_safe (geom_extent Geometry(Geometry, 4326) ,geom_type text ,params json ,target_geoms integer DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
DECLARE
|
||||||
|
username text;
|
||||||
|
orgname text;
|
||||||
|
_returned_sqlstate TEXT;
|
||||||
|
_message_text TEXT;
|
||||||
|
_pg_exception_context TEXT;
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN
|
||||||
|
RAISE EXCEPTION 'The api_key must be provided';
|
||||||
|
END IF;
|
||||||
|
SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text);
|
||||||
|
-- JSON value stored "" is taken as literal
|
||||||
|
IF username IS NULL OR username = '' OR username = '""' THEN
|
||||||
|
RAISE EXCEPTION 'Username is a mandatory argument, check it out';
|
||||||
|
END IF;
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_metadatavalidation(username, orgname, geom_extent, geom_type, params, target_geoms);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE,
|
||||||
|
_message_text = MESSAGE_TEXT,
|
||||||
|
_pg_exception_context = PG_EXCEPTION_CONTEXT;
|
||||||
|
RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context;
|
||||||
|
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._OBS_PreCheck(source_query text, params JSON) TO publicuser;
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_metadatavalidation(geom_extent Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer) TO publicuser;
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_metadatavalidation_exception_safe(geom_extent Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer ) TO publicuser;
|
||||||
|
|
||||||
12
client/cdb_dataservices_client--0.20.0--0.19.0.sql
Normal file
12
client/cdb_dataservices_client--0.20.0--0.19.0.sql
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.19.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- Make sure we have a sane search path to create/update the extension
|
||||||
|
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
DROP FUNCTION IF EXISTS _OBS_PreCheck(text, json);
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_metadatavalidation (Geometry(Geometry, 4326), text, json);
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_metadatavalidation_exception_safe (Geometry(Geometry, 4326), text, json);
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_metadatavalidation (text, text, Geometry(Geometry, 4326), text, json);
|
||||||
4469
client/cdb_dataservices_client--0.20.0.sql
Normal file
4469
client/cdb_dataservices_client--0.20.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices client API extension'
|
comment = 'CartoDB dataservices client API extension'
|
||||||
default_version = '0.18.0'
|
default_version = '0.20.0'
|
||||||
requires = 'plproxy, cartodb'
|
requires = 'plproxy, cartodb'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_client
|
schema = cdb_dataservices_client
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.19.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- Make sure we have a sane search path to create/update the extension
|
||||||
|
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getnumerators (bounds geometry(Geometry, 4326) DEFAULT NULL ,section_tags text[] DEFAULT ARRAY[]::TEXT[] ,subsection_tags text[] DEFAULT ARRAY[]::TEXT[] ,other_tags text[] DEFAULT ARRAY[]::TEXT[] ,ids text[] DEFAULT ARRAY[]::TEXT[] ,name text DEFAULT NULL ,denom_id text DEFAULT '' ,geom_id text DEFAULT '' ,timespan text DEFAULT '')
|
||||||
|
RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$
|
||||||
|
DECLARE
|
||||||
|
|
||||||
|
username text;
|
||||||
|
orgname text;
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN
|
||||||
|
RAISE EXCEPTION 'The api_key must be provided';
|
||||||
|
END IF;
|
||||||
|
SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text);
|
||||||
|
-- JSON value stored "" is taken as literal
|
||||||
|
IF username IS NULL OR username = '' OR username = '""' THEN
|
||||||
|
RAISE EXCEPTION 'Username is a mandatory argument, check it out';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN QUERY SELECT * FROM cdb_dataservices_client.__obs_getnumerators(username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe (bounds geometry(Geometry, 4326) DEFAULT NULL ,section_tags text[] DEFAULT ARRAY[]::TEXT[] ,subsection_tags text[] DEFAULT ARRAY[]::TEXT[] ,other_tags text[] DEFAULT ARRAY[]::TEXT[] ,ids text[] DEFAULT ARRAY[]::TEXT[] ,name text DEFAULT NULL ,denom_id text DEFAULT '' ,geom_id text DEFAULT '' ,timespan text DEFAULT '')
|
||||||
|
RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$
|
||||||
|
DECLARE
|
||||||
|
|
||||||
|
username text;
|
||||||
|
orgname text;
|
||||||
|
_returned_sqlstate TEXT;
|
||||||
|
_message_text TEXT;
|
||||||
|
_pg_exception_context TEXT;
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN
|
||||||
|
RAISE EXCEPTION 'The api_key must be provided';
|
||||||
|
END IF;
|
||||||
|
SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text);
|
||||||
|
-- JSON value stored "" is taken as literal
|
||||||
|
IF username IS NULL OR username = '' OR username = '""' THEN
|
||||||
|
RAISE EXCEPTION 'Username is a mandatory argument, check it out';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY SELECT * FROM cdb_dataservices_client.__obs_getnumerators(username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE,
|
||||||
|
_message_text = MESSAGE_TEXT,
|
||||||
|
_pg_exception_context = PG_EXCEPTION_CONTEXT;
|
||||||
|
RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context;
|
||||||
|
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client.__obs_getnumerators (username text, orgname text, bounds geometry(Geometry, 4326) DEFAULT NULL, section_tags text[] DEFAULT ARRAY[]::TEXT[], subsection_tags text[] DEFAULT ARRAY[]::TEXT[], other_tags text[] DEFAULT ARRAY[]::TEXT[], ids text[] DEFAULT ARRAY[]::TEXT[], name text DEFAULT NULL, denom_id text DEFAULT '', geom_id text DEFAULT '', timespan text DEFAULT '')
|
||||||
|
RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$
|
||||||
|
CONNECT cdb_dataservices_client._server_conn_str();
|
||||||
|
|
||||||
|
SELECT * FROM cdb_dataservices_server._obs_getnumerators (username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan);
|
||||||
|
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getnumerators(bounds geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text) TO publicuser;
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe(bounds geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text ) TO publicuser;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_client UPDATE TO '0.18.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- Make sure we have a sane search path to create/update the extension
|
||||||
|
SET search_path = "$user",cartodb,public,cdb_dataservices_client;
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
DROP IF EXISTS FUNCTION cdb_dataservices_client._obs_getnumerators (geometry(Geometry, 4326), text[], text[] , text[], text[] , text, text, text,text);
|
||||||
|
DROP IF EXISTS FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe (geometry(Geometry, 4326), text[], text[] , text[], text[] , text, text, text,text);
|
||||||
|
DROP IF EXISTS FUNCTION cdb_dataservices_client.__obs_getnumerators (text, text, geometry(Geometry, 4326), text[], text[] , text[], text[] , text, text, text,text);
|
||||||
4343
client/old_versions/cdb_dataservices_client--0.19.0.sql
Normal file
4343
client/old_versions/cdb_dataservices_client--0.19.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -305,6 +305,16 @@
|
|||||||
- { name: max_score_rank, type: integer, default: 'NULL' }
|
- { name: max_score_rank, type: integer, default: 'NULL' }
|
||||||
- { name: target_geoms, type: integer, default: 'NULL' }
|
- { name: target_geoms, type: integer, default: 'NULL' }
|
||||||
|
|
||||||
|
- name: obs_metadatavalidation
|
||||||
|
return_type: TABLE(valid boolean, errors text[])
|
||||||
|
multi_row: true
|
||||||
|
multi_field: true
|
||||||
|
params:
|
||||||
|
- { name: geom_extent, type: "Geometry(Geometry, 4326)" }
|
||||||
|
- { name: geom_type, type: text }
|
||||||
|
- { name: params, type: json }
|
||||||
|
- { name: target_geoms, type: integer, default: 'NULL' }
|
||||||
|
|
||||||
- name: obs_getcategory
|
- name: obs_getcategory
|
||||||
return_type: text
|
return_type: text
|
||||||
params:
|
params:
|
||||||
@@ -381,6 +391,21 @@
|
|||||||
- { name: geom_id, type: text, default: 'NULL' }
|
- { name: geom_id, type: text, default: 'NULL' }
|
||||||
- { name: timespan, type: text, default: 'NULL'}
|
- { name: timespan, type: text, default: 'NULL'}
|
||||||
|
|
||||||
|
- name: _obs_getnumerators
|
||||||
|
return_type: SETOF cdb_dataservices_client.obs_meta_numerator
|
||||||
|
multi_row: true
|
||||||
|
multi_field: true
|
||||||
|
params:
|
||||||
|
- { name: bounds, type: "geometry(Geometry, 4326)", default: 'NULL' }
|
||||||
|
- { name: section_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' }
|
||||||
|
- { name: subsection_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' }
|
||||||
|
- { name: other_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' }
|
||||||
|
- { name: ids, type: "text[]", default: 'ARRAY[]::TEXT[]' }
|
||||||
|
- { name: name, type: text, default: 'NULL' }
|
||||||
|
- { name: denom_id, type: text, default: "''" }
|
||||||
|
- { name: geom_id, type: text, default: "''" }
|
||||||
|
- { name: timespan, type: text, default: "''"}
|
||||||
|
|
||||||
- name: obs_getavailabledenominators
|
- name: obs_getavailabledenominators
|
||||||
return_type: SETOF cdb_dataservices_client.obs_meta_denominator
|
return_type: SETOF cdb_dataservices_client.obs_meta_denominator
|
||||||
multi_row: true
|
multi_row: true
|
||||||
|
|||||||
54
client/sql/35_precheck_functions.sql
Normal file
54
client/sql/35_precheck_functions.sql
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._OBS_PreCheck(
|
||||||
|
source_query text,
|
||||||
|
parameters json
|
||||||
|
) RETURNS boolean AS $$
|
||||||
|
DECLARE
|
||||||
|
errors text[];
|
||||||
|
validator_errors text[];
|
||||||
|
validator_error text;
|
||||||
|
valid boolean;
|
||||||
|
geoms record;
|
||||||
|
BEGIN
|
||||||
|
errors := (ARRAY[])::TEXT[];
|
||||||
|
FOR geoms IN EXECUTE format('SELECT ST_GeometryType(the_geom) as geom_type,
|
||||||
|
bool_and(st_isvalid(the_geom)) as valid,
|
||||||
|
avg(st_npoints(the_geom)) as avg_vertex,
|
||||||
|
ST_SetSRID(ST_Extent(the_geom), 4326) as extent,
|
||||||
|
count(*)::INT as numgeoms
|
||||||
|
FROM (%s) as _source
|
||||||
|
GROUP BY ST_GeometryType(the_geom)', source_query)
|
||||||
|
LOOP
|
||||||
|
IF geoms.geom_type NOT IN ('ST_Polygon', 'ST_MultiPolygon', 'ST_Point') THEN
|
||||||
|
errors := array_append(errors, format($data$'Geometry type %s not supported'$data$, geoms.geom_type));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF geoms.valid IS FALSE THEN
|
||||||
|
errors := array_append(errors, 'There are invalid geometries in the input data, please try to fix them');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 1000 vertex for a geometry is a limit we have in the obs_getdata function. You can check here
|
||||||
|
-- https://github.com/CartoDB/observatory-extension/blob/1.6.0/src/pg/sql/41_observatory_augmentation.sql#L813
|
||||||
|
IF geoms.avg_vertex > 1000 THEN
|
||||||
|
errors := array_append(errors, 'The average number of vertices per geometry is greater than 1000, please try to simplify them');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- OBS specific part
|
||||||
|
EXECUTE 'SELECT valid, errors
|
||||||
|
FROM cdb_dataservices_client.OBS_MetadataValidation($1, $2, $3, $4)'
|
||||||
|
INTO valid, validator_errors
|
||||||
|
USING geoms.extent, geoms.geom_type, parameters, geoms.numgeoms;
|
||||||
|
IF valid is FALSE THEN
|
||||||
|
FOR validator_error IN EXECUTE 'SELECT unnest($1)' USING validator_errors
|
||||||
|
LOOP
|
||||||
|
errors := array_append(errors, validator_error);
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
IF CARDINALITY(errors) > 0 THEN
|
||||||
|
RAISE EXCEPTION '%', errors;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN TRUE;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure(output_table_name text, params json) TO publicuser;
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure(output_table_name text, params json) TO publicuser;
|
||||||
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure(table_name text, output_table_name text, params json) TO publicuser;
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure(table_name text, output_table_name text, params json) TO publicuser;
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client._OBS_PreCheck(source_query text, params JSON) TO publicuser;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
-- Install dependencies
|
-- Install dependencies
|
||||||
CREATE EXTENSION postgis;
|
CREATE EXTENSION postgis;
|
||||||
CREATE EXTENSION schema_triggers;
|
|
||||||
CREATE EXTENSION plpythonu;
|
CREATE EXTENSION plpythonu;
|
||||||
CREATE EXTENSION cartodb;
|
CREATE EXTENSION cartodb;
|
||||||
CREATE EXTENSION plproxy;
|
CREATE EXTENSION plproxy;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server function
|
-- Mock the server function
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
SET client_min_messages TO warning;
|
SET client_min_messages TO warning;
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions to raise exceptions
|
-- Mock the server functions to raise exceptions
|
||||||
@@ -31,8 +32,6 @@ SET ROLE test_regular_user;
|
|||||||
-- Exercise the exception safe and the proxied functions
|
-- Exercise the exception safe and the proxied functions
|
||||||
SELECT _cdb_geocode_street_point_exception_safe('One street, 1');
|
SELECT _cdb_geocode_street_point_exception_safe('One street, 1');
|
||||||
WARNING: cdb_dataservices_client._cdb_geocode_street_point(6): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
WARNING: cdb_dataservices_client._cdb_geocode_street_point(6): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
||||||
DETAIL: SQL statement "SELECT cdb_dataservices_client._cdb_geocode_street_point(username, orgname, searchtext, city, state_province, country)"
|
|
||||||
PL/pgSQL function _cdb_geocode_street_point_exception_safe(text,text,text,text) line 21 at SQL statement
|
|
||||||
_cdb_geocode_street_point_exception_safe
|
_cdb_geocode_street_point_exception_safe
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
@@ -40,15 +39,12 @@ PL/pgSQL function _cdb_geocode_street_point_exception_safe(text,text,text,text)
|
|||||||
|
|
||||||
SELECT * FROM _cdb_isodistance_exception_safe('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300]::integer[]);
|
SELECT * FROM _cdb_isodistance_exception_safe('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300]::integer[]);
|
||||||
WARNING: cdb_dataservices_client._cdb_isodistance(6): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
WARNING: cdb_dataservices_client._cdb_isodistance(6): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
||||||
DETAIL: PL/pgSQL function _cdb_isodistance_exception_safe(geometry,text,integer[],text[]) line 21 at RETURN QUERY
|
|
||||||
center | data_range | the_geom
|
center | data_range | the_geom
|
||||||
--------+------------+----------
|
--------+------------+----------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
SELECT * FROM _cdb_route_point_to_point_exception_safe('POINT(-3.70237112 40.41706163)'::geometry,'POINT(-3.69909883 40.41236875)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]);
|
SELECT * FROM _cdb_route_point_to_point_exception_safe('POINT(-3.70237112 40.41706163)'::geometry,'POINT(-3.69909883 40.41236875)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]);
|
||||||
WARNING: cdb_dataservices_client._cdb_route_point_to_point(7): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
WARNING: cdb_dataservices_client._cdb_route_point_to_point(7): [contrib_regression] REMOTE ERROR: Not enough quota or any other exception whatsoever.
|
||||||
DETAIL: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_point_to_point(username, orgname, origin, destination, mode, options, units)"
|
|
||||||
PL/pgSQL function _cdb_route_point_to_point_exception_safe(geometry,geometry,text,text[],text) line 21 at SQL statement
|
|
||||||
shape | length | duration
|
shape | length | duration
|
||||||
-------+--------+----------
|
-------+--------+----------
|
||||||
| |
|
| |
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
-- Mock the server functions
|
-- Mock the server functions
|
||||||
@@ -194,6 +195,13 @@ BEGIN
|
|||||||
RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data;
|
RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE 'plpgsql';
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_metadatavalidation(username text, orgname text, geom_extent geometry(Geometry, 4326), geom_type text, params JSON, target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE (valid boolean, errors text[]) AS $$
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'cdb_dataservices_server.obs_metadatavalidation invoked with params (%, %, %, %, %, %)', username, orgname, geom_extent, geom_type, params, target_geoms;
|
||||||
|
RETURN QUERY SELECT true AS valid, ARRAY[]::TEXT[] AS errors;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
-- Exercise the public and the proxied function
|
-- Exercise the public and the proxied function
|
||||||
SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text);
|
SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text);
|
||||||
NOTICE: cdb_dataservices_client._obs_get_demographic_snapshot(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_get_demographic_snapshot invoked with params (test_user, <NULL>, 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 2009 - 2013, "us.census.tiger".block_group)
|
NOTICE: cdb_dataservices_client._obs_get_demographic_snapshot(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_get_demographic_snapshot invoked with params (test_user, <NULL>, 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 2009 - 2013, "us.census.tiger".block_group)
|
||||||
@@ -351,3 +359,10 @@ NOTICE: cdb_dataservices_client._obs_getdata(5): [contrib_regression] REMOTE NO
|
|||||||
(36047,"[{""value"" : 10349.1547875017}]")
|
(36047,"[{""value"" : 10349.1547875017}]")
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000);
|
||||||
|
NOTICE: cdb_dataservices_client._obs_metadatavalidation(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_metadatavalidation invoked with params (test_user, <NULL>, 0101000020E61000009A999999997952C09A99999999594440, ST_Polygon, [{"numer_id": "us.census.acs.B01003001"}], 1000)
|
||||||
|
obs_metadatavalidation
|
||||||
|
------------------------
|
||||||
|
(t,{})
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Use regular user role
|
-- Use regular user role
|
||||||
SET ROLE test_regular_user;
|
SET ROLE test_regular_user;
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
-- Install dependencies
|
-- Install dependencies
|
||||||
CREATE EXTENSION postgis;
|
CREATE EXTENSION postgis;
|
||||||
CREATE EXTENSION schema_triggers;
|
|
||||||
CREATE EXTENSION plpythonu;
|
CREATE EXTENSION plpythonu;
|
||||||
CREATE EXTENSION cartodb;
|
CREATE EXTENSION cartodb;
|
||||||
CREATE EXTENSION plproxy;
|
CREATE EXTENSION plproxy;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
SET client_min_messages TO warning;
|
SET client_min_messages TO warning;
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Add to the search path the schema
|
-- Add to the search path the schema
|
||||||
SET search_path TO public,cartodb,cdb_dataservices_client;
|
SET search_path TO public,cartodb,cdb_dataservices_client;
|
||||||
|
|
||||||
@@ -218,6 +219,14 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$ LANGUAGE 'plpgsql';
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_metadatavalidation(username text, orgname text, geom_extent geometry(Geometry, 4326), geom_type text, params JSON, target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE (valid boolean, errors text[]) AS $$
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'cdb_dataservices_server.obs_metadatavalidation invoked with params (%, %, %, %, %, %)', username, orgname, geom_extent, geom_type, params, target_geoms;
|
||||||
|
RETURN QUERY SELECT true AS valid, ARRAY[]::TEXT[] AS errors;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
|
||||||
-- Exercise the public and the proxied function
|
-- Exercise the public and the proxied function
|
||||||
SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text);
|
SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text);
|
||||||
SELECT obs_get_segment_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text);
|
SELECT obs_get_segment_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text);
|
||||||
@@ -241,4 +250,5 @@ SELECT obs_getavailableboundaries(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4
|
|||||||
SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000);
|
SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000);
|
||||||
SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000));
|
SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000));
|
||||||
SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]'));
|
SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]'));
|
||||||
|
SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
\set VERBOSITY terse
|
||||||
-- Use regular user role
|
-- Use regular user role
|
||||||
SET ROLE test_regular_user;
|
SET ROLE test_regular_user;
|
||||||
|
|
||||||
|
|||||||
50
server/extension/cdb_dataservices_server--0.26.0--0.27.0.sql
Normal file
50
server/extension/cdb_dataservices_server--0.26.0--0.27.0.sql
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.27.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_MetadataValidation(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
geometry_extent Geometry(Geometry, 4326),
|
||||||
|
geometry_type text,
|
||||||
|
params JSON,
|
||||||
|
target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
|
||||||
|
SELECT * FROM cdb_observatory.OBS_MetadataValidation(geometry_extent, geometry_type, params, target_geoms);
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_MetadataValidation(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
geometry_extent Geometry(Geometry, 4326),
|
||||||
|
geometry_type text,
|
||||||
|
params JSON,
|
||||||
|
target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
from cartodb_services.metrics import metrics
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||||
|
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
with metrics('obs_metadatavalidation', user_obs_config, logger):
|
||||||
|
try:
|
||||||
|
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_MetadataValidation($1, $2, $3, $4, $5, $6);", ["text", "text", "Geometry (Geometry, 4326)", "text", "json", "integer"])
|
||||||
|
result = plpy.execute(obs_plan, [username, orgname, geometry_extent, geometry_type, params, target_geoms])
|
||||||
|
if result:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
logger.error('Error trying to OBS_MetadataValidation', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to OBS_MetadataValidation')
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.26.0'" to load this file. \quit
|
||||||
|
|
||||||
|
-- HERE goes your code to upgrade/downgrade
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_MetadataValidation(TEXT, TEXT, Geometry(Geometry, 4326), text, JSON, INTEGER);
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_MetadataValidation(Geometry(Geometry, 4326), text, JSON, INTEGER);
|
||||||
3067
server/extension/cdb_dataservices_server--0.27.0.sql
Normal file
3067
server/extension/cdb_dataservices_server--0.27.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices server extension'
|
comment = 'CartoDB dataservices server extension'
|
||||||
default_version = '0.25.0'
|
default_version = '0.27.0'
|
||||||
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_server
|
schema = cdb_dataservices_server
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.25.0'" to load this file. \quit
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetNumerators(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
bounds geometry(Geometry, 4326) DEFAULT NULL,
|
||||||
|
section_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
subsection_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
other_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
ids TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
name TEXT DEFAULT NULL,
|
||||||
|
denom_id TEXT DEFAULT '',
|
||||||
|
geom_id TEXT DEFAULT '',
|
||||||
|
timespan TEXT DEFAULT '')
|
||||||
|
RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$
|
||||||
|
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
|
||||||
|
SELECT * FROM cdb_observatory._OBS_GetNumerators(bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan);
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.2'" to load this file. \quit
|
||||||
|
|
||||||
|
DROP IF EXISTS FUNCTION cdb_dataservices_server._OBS_GetNumerators (text, text, geometry(Geometry, 4326), text[], text[] , text[], text[] , text, text, text,text);
|
||||||
3021
server/extension/old_versions/cdb_dataservices_server--0.26.0.sql
Normal file
3021
server/extension/old_versions/cdb_dataservices_server--0.26.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -737,3 +737,49 @@ RETURNS JSON AS $$
|
|||||||
logger.error('Error trying to OBS_GetMeta', sys.exc_info(), data={"username": username, "orgname": orgname})
|
logger.error('Error trying to OBS_GetMeta', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
raise Exception('Error trying to OBS_GetMeta')
|
raise Exception('Error trying to OBS_GetMeta')
|
||||||
$$ LANGUAGE plpythonu;
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_MetadataValidation(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
geometry_extent Geometry(Geometry, 4326),
|
||||||
|
geometry_type text,
|
||||||
|
params JSON,
|
||||||
|
target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
|
||||||
|
SELECT * FROM cdb_observatory.OBS_MetadataValidation(geometry_extent, geometry_type, params, target_geoms);
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_MetadataValidation(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
geometry_extent Geometry(Geometry, 4326),
|
||||||
|
geometry_type text,
|
||||||
|
params JSON,
|
||||||
|
target_geoms INTEGER DEFAULT NULL)
|
||||||
|
RETURNS TABLE(valid boolean, errors text[]) AS $$
|
||||||
|
from cartodb_services.metrics import metrics
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||||
|
user_obs_config = GD["user_obs_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
with metrics('obs_metadatavalidation', user_obs_config, logger):
|
||||||
|
try:
|
||||||
|
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_MetadataValidation($1, $2, $3, $4, $5, $6);", ["text", "text", "Geometry (Geometry, 4326)", "text", "json", "integer"])
|
||||||
|
result = plpy.execute(obs_plan, [username, orgname, geometry_extent, geometry_type, params, target_geoms])
|
||||||
|
if result:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
logger.error('Error trying to OBS_MetadataValidation', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to OBS_MetadataValidation')
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|||||||
@@ -20,6 +20,23 @@ RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$
|
|||||||
SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(bounds, filter_tags, denom_id, geom_id, timespan);
|
SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(bounds, filter_tags, denom_id, geom_id, timespan);
|
||||||
$$ LANGUAGE plproxy;
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetNumerators(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
bounds geometry(Geometry, 4326) DEFAULT NULL,
|
||||||
|
section_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
subsection_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
other_tags TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
ids TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||||
|
name TEXT DEFAULT NULL,
|
||||||
|
denom_id TEXT DEFAULT '',
|
||||||
|
geom_id TEXT DEFAULT '',
|
||||||
|
timespan TEXT DEFAULT '')
|
||||||
|
RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$
|
||||||
|
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
|
||||||
|
SELECT * FROM cdb_observatory._OBS_GetNumerators(bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan);
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
CREATE TYPE cdb_dataservices_server.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean);
|
CREATE TYPE cdb_dataservices_server.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean);
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableDenominators(
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableDenominators(
|
||||||
|
|||||||
@@ -273,3 +273,14 @@ SELECT exists(SELECT *
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT exists(SELECT *
|
||||||
|
FROM pg_proc p
|
||||||
|
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||||
|
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||||
|
AND proname = 'obs_metadatavalidation'
|
||||||
|
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, json, integer');
|
||||||
|
exists
|
||||||
|
--------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
|||||||
@@ -172,3 +172,10 @@ SELECT exists(SELECT *
|
|||||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||||
AND proname = 'obs_legacybuildermetadata'
|
AND proname = 'obs_legacybuildermetadata'
|
||||||
AND oidvectortypes(p.proargtypes) = 'text, text, text');
|
AND oidvectortypes(p.proargtypes) = 'text, text, text');
|
||||||
|
|
||||||
|
SELECT exists(SELECT *
|
||||||
|
FROM pg_proc p
|
||||||
|
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||||
|
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||||
|
AND proname = 'obs_metadatavalidation'
|
||||||
|
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, json, integer');
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/local/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import googlemaps
|
||||||
|
import base64
|
||||||
|
from exceptions import InvalidGoogleCredentials
|
||||||
|
|
||||||
|
class GoogleMapsClientFactory():
|
||||||
|
clients = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get(cls, client_id, client_secret):
|
||||||
|
cache_key = "{}:{}".format(client_id, client_secret)
|
||||||
|
client = cls.clients.get(cache_key)
|
||||||
|
if not client:
|
||||||
|
cls.assert_valid_crendentials(client_secret)
|
||||||
|
client = googlemaps.Client(
|
||||||
|
client_id=client_id,
|
||||||
|
client_secret=client_secret)
|
||||||
|
cls.clients[cache_key] = client
|
||||||
|
return client
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def assert_valid_crendentials(cls, client_secret):
|
||||||
|
if not cls.valid_credentials(client_secret):
|
||||||
|
raise InvalidGoogleCredentials
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def valid_credentials(client_secret):
|
||||||
|
try:
|
||||||
|
# Only fails if the string dont have a correct padding for b64
|
||||||
|
# but this way we could provide a more clear error than
|
||||||
|
# TypeError: Incorrect padding
|
||||||
|
b64_secret = client_secret.replace('-', '+').replace('_', '/')
|
||||||
|
base64.b64decode(b64_secret)
|
||||||
|
return True
|
||||||
|
except TypeError:
|
||||||
|
return False
|
||||||
@@ -1,22 +1,19 @@
|
|||||||
#!/usr/local/bin/python
|
#!/usr/local/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import base64
|
|
||||||
import googlemaps
|
import googlemaps
|
||||||
|
|
||||||
from exceptions import MalformedResult, InvalidGoogleCredentials
|
from exceptions import MalformedResult
|
||||||
|
from client_factory import GoogleMapsClientFactory
|
||||||
|
|
||||||
|
|
||||||
class GoogleMapsGeocoder:
|
class GoogleMapsGeocoder:
|
||||||
"""A Google Maps Geocoder wrapper for python"""
|
"""A Google Maps Geocoder wrapper for python"""
|
||||||
|
|
||||||
def __init__(self, client_id, client_secret, logger):
|
def __init__(self, client_id, client_secret, logger):
|
||||||
if not self._valid_credentials(client_secret):
|
|
||||||
raise InvalidGoogleCredentials('Invalid google secret key')
|
|
||||||
self.client_id = self._clean_client_id(client_id)
|
self.client_id = self._clean_client_id(client_id)
|
||||||
self.client_secret = client_secret
|
self.client_secret = client_secret
|
||||||
self.geocoder = googlemaps.Client(
|
self.geocoder = GoogleMapsClientFactory.get(self.client_id, self.client_secret)
|
||||||
client_id=self.client_id, client_secret=self.client_secret)
|
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
|
||||||
def geocode(self, searchtext, city=None, state=None,
|
def geocode(self, searchtext, city=None, state=None,
|
||||||
@@ -52,13 +49,3 @@ class GoogleMapsGeocoder:
|
|||||||
def _clean_client_id(self, client_id):
|
def _clean_client_id(self, client_id):
|
||||||
# Consistency with how the client_id is saved in metadata
|
# Consistency with how the client_id is saved in metadata
|
||||||
return client_id.replace('client=', '')
|
return client_id.replace('client=', '')
|
||||||
|
|
||||||
def _valid_credentials(self, private_key):
|
|
||||||
try:
|
|
||||||
# Only fails if the string dont have a correct padding for b64
|
|
||||||
# but this way we could provide a more clear error than
|
|
||||||
# TypeError: Incorrect padding
|
|
||||||
base64.b64decode(private_key)
|
|
||||||
return True
|
|
||||||
except TypeError:
|
|
||||||
return False
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def coordinates_to_polygon(coordinates):
|
|||||||
wkt_coordinates = ','.join(result_coordinates)
|
wkt_coordinates = ','.join(result_coordinates)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sql = "SELECT ST_MakePolygon(ST_GeomFromText('LINESTRING({0})', 4326)) as geom".format(wkt_coordinates)
|
sql = "SELECT ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(ST_GeomFromText('LINESTRING({0})', 4326))),3) as geom".format(wkt_coordinates)
|
||||||
geometry = plpy.execute(sql, 1)[0]['geom']
|
geometry = plpy.execute(sql, 1)[0]['geom']
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
plpy.warning("Can't generate POLYGON from coordinates: {0}".format(e))
|
plpy.warning("Can't generate POLYGON from coordinates: {0}".format(e))
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class MetricsLogger(object):
|
|||||||
json.dump(data, logfile)
|
json.dump(data, logfile)
|
||||||
logfile.write('\n')
|
logfile.write('\n')
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
self._logger("Error dumping metrics to file {0}".format(log_path),
|
self._logger.error("Error dumping metrics to file {0}".format(log_path),
|
||||||
exception=e)
|
exception=e)
|
||||||
|
|
||||||
def collect_data(self, data):
|
def collect_data(self, data):
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class QuotaService:
|
|||||||
|
|
||||||
def increment_failed_service_use(self, amount=1):
|
def increment_failed_service_use(self, amount=1):
|
||||||
self._user_service.increment_service_use(
|
self._user_service.increment_service_use(
|
||||||
self._user_service_config.service_type, "fail_responses",
|
self._user_service_config.service_type, "failed_responses",
|
||||||
amount=amount)
|
amount=amount)
|
||||||
self._log_service_process("fail")
|
self._log_service_process("fail")
|
||||||
|
|
||||||
@@ -134,7 +134,10 @@ class QuotaChecker:
|
|||||||
service_type = self._user_service_config.service_type
|
service_type = self._user_service_config.service_type
|
||||||
current_used = self._user_service.used_quota(service_type, today)
|
current_used = self._user_service.used_quota(service_type, today)
|
||||||
|
|
||||||
if soft_limit or (user_quota > 0 and current_used < user_quota):
|
# Quick workaround so we don't take into account numer of credits
|
||||||
|
# spent for users that have defined the quota.
|
||||||
|
# See https://github.com/CartoDB/bigmetadata/issues/215
|
||||||
|
if soft_limit or (user_quota > 0):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
redis==2.10.5
|
redis==2.10.5
|
||||||
hiredis==0.1.5
|
hiredis==0.1.5
|
||||||
python-dateutil==2.2
|
python-dateutil==2.2
|
||||||
googlemaps==2.4.2
|
googlemaps==2.5.1
|
||||||
rollbar==0.13.2
|
rollbar==0.13.2
|
||||||
# Dependency for googlemaps package
|
# Dependency for googlemaps package
|
||||||
requests==2.9.1
|
requests==2.9.1
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from setuptools import setup, find_packages
|
|||||||
setup(
|
setup(
|
||||||
name='cartodb_services',
|
name='cartodb_services',
|
||||||
|
|
||||||
version='0.15.2',
|
version='0.15.5',
|
||||||
|
|
||||||
description='CartoDB Services API Python Library',
|
description='CartoDB Services API Python Library',
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/local/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import googlemaps
|
||||||
|
import unittest
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from cartodb_services.google.client_factory import GoogleMapsClientFactory
|
||||||
|
from cartodb_services.google.exceptions import InvalidGoogleCredentials
|
||||||
|
|
||||||
|
class GoogleMapsClientFactoryTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# reset client cache
|
||||||
|
GoogleMapsClientFactory.clients = {}
|
||||||
|
|
||||||
|
def test_consecutive_calls_with_same_params_return_same_client(self):
|
||||||
|
id = 'any_id'
|
||||||
|
key = base64.b64encode('any_key')
|
||||||
|
client1 = GoogleMapsClientFactory.get(id, key)
|
||||||
|
client2 = GoogleMapsClientFactory.get(id, key)
|
||||||
|
self.assertEqual(client1, client2)
|
||||||
|
|
||||||
|
def test_consecutive_calls_with_different_key_return_different_clients(self):
|
||||||
|
"""
|
||||||
|
This requirement is important for security reasons as well as not to
|
||||||
|
cache a wrong key accidentally.
|
||||||
|
"""
|
||||||
|
id = 'any_id'
|
||||||
|
key1 = base64.b64encode('any_key')
|
||||||
|
key2 = base64.b64encode('another_key')
|
||||||
|
client1 = GoogleMapsClientFactory.get(id, key1)
|
||||||
|
client2 = GoogleMapsClientFactory.get(id, key2)
|
||||||
|
self.assertNotEqual(client1, client2)
|
||||||
|
|
||||||
|
def test_consecutive_calls_with_different_ids_return_different_clients(self):
|
||||||
|
"""
|
||||||
|
This requirement is important for security reasons as well as not to
|
||||||
|
cache a wrong key accidentally.
|
||||||
|
"""
|
||||||
|
id1 = 'any_id'
|
||||||
|
id2 = 'another_id'
|
||||||
|
key = base64.b64encode('any_key')
|
||||||
|
client1 = GoogleMapsClientFactory.get(id1, key)
|
||||||
|
client2 = GoogleMapsClientFactory.get(id2, key)
|
||||||
|
self.assertNotEqual(client1, client2)
|
||||||
|
|
||||||
|
def test_invalid_credentials(self):
|
||||||
|
with self.assertRaises(InvalidGoogleCredentials):
|
||||||
|
GoogleMapsClientFactory.get('dummy_client_id', 'lalala')
|
||||||
|
|
||||||
|
def test_credentials_with_dashes_can_be_valid(self):
|
||||||
|
client = GoogleMapsClientFactory.get('yet_another_dummy_client_id', 'Ola-k-ase---')
|
||||||
|
self.assertIsInstance(client, googlemaps.Client)
|
||||||
|
|
||||||
|
def test_credentials_with_underscores_can_be_valid(self):
|
||||||
|
client = GoogleMapsClientFactory.get('yet_another_dummy_client_id', 'Ola_k_ase___')
|
||||||
|
self.assertIsInstance(client, googlemaps.Client)
|
||||||
@@ -6,7 +6,7 @@ import requests_mock
|
|||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
from cartodb_services.google import GoogleMapsGeocoder
|
from cartodb_services.google import GoogleMapsGeocoder
|
||||||
from cartodb_services.google.exceptions import MalformedResult, InvalidGoogleCredentials
|
from cartodb_services.google.exceptions import MalformedResult
|
||||||
|
|
||||||
requests_mock.Mocker.TEST_PREFIX = 'test_'
|
requests_mock.Mocker.TEST_PREFIX = 'test_'
|
||||||
|
|
||||||
@@ -118,9 +118,3 @@ class GoogleGeocoderTestCase(unittest.TestCase):
|
|||||||
searchtext='Calle Eloy Gonzalo 27',
|
searchtext='Calle Eloy Gonzalo 27',
|
||||||
city='Madrid',
|
city='Madrid',
|
||||||
country='España')
|
country='España')
|
||||||
|
|
||||||
def test_invalid_credentials(self, req_mock):
|
|
||||||
with self.assertRaises(InvalidGoogleCredentials):
|
|
||||||
GoogleMapsGeocoder('dummy_client_id',
|
|
||||||
'lalala',
|
|
||||||
None)
|
|
||||||
|
|||||||
@@ -126,12 +126,15 @@ class TestQuotaService(TestCase):
|
|||||||
qs.increment_isolines_service_use(amount=1500000)
|
qs.increment_isolines_service_use(amount=1500000)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
|
# Quick workaround so we don't take into account numer of credits
|
||||||
|
# spent for users that have defined the quota.
|
||||||
|
# See https://github.com/CartoDB/bigmetadata/issues/215
|
||||||
def test_should_check_user_obs_snapshot_quota_correctly(self):
|
def test_should_check_user_obs_snapshot_quota_correctly(self):
|
||||||
qs = self.__build_obs_snapshot_quota_service('test_user')
|
qs = self.__build_obs_snapshot_quota_service('test_user')
|
||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=100000)
|
qs.increment_success_service_use(amount=100000)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_check_org_obs_snapshot_quota_correctly(self):
|
def test_should_check_org_obs_snapshot_quota_correctly(self):
|
||||||
qs = self.__build_obs_snapshot_quota_service('test_user',
|
qs = self.__build_obs_snapshot_quota_service('test_user',
|
||||||
@@ -139,14 +142,14 @@ class TestQuotaService(TestCase):
|
|||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=100000)
|
qs.increment_success_service_use(amount=100000)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_check_user_obs_quota_correctly(self):
|
def test_should_check_user_obs_quota_correctly(self):
|
||||||
qs = self.__build_obs_snapshot_quota_service('test_user')
|
qs = self.__build_obs_snapshot_quota_service('test_user')
|
||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=100000)
|
qs.increment_success_service_use(amount=100000)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_check_org_obs_quota_correctly(self):
|
def test_should_check_org_obs_quota_correctly(self):
|
||||||
qs = self.__build_obs_quota_service('test_user',
|
qs = self.__build_obs_quota_service('test_user',
|
||||||
@@ -154,7 +157,7 @@ class TestQuotaService(TestCase):
|
|||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=100000)
|
qs.increment_success_service_use(amount=100000)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def __prepare_quota_service(self, username, service, quota, provider,
|
def __prepare_quota_service(self, username, service, quota, provider,
|
||||||
orgname, soft_limit, end_date):
|
orgname, soft_limit, end_date):
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class TestUserService(TestCase):
|
|||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
|
||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
|
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
|
us.increment_service_use(self.NOKIA_GEOCODER, 'failed_responses')
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
|
|
||||||
def test_should_increment_org_used_quota(self):
|
def test_should_increment_org_used_quota(self):
|
||||||
@@ -61,7 +61,7 @@ class TestUserService(TestCase):
|
|||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
|
||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
|
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
|
us.increment_service_use(self.NOKIA_GEOCODER, 'failed_responses')
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
|
|
||||||
def test_should_increment_user_used_quota_in_for_multiples_dates(self):
|
def test_should_increment_user_used_quota_in_for_multiples_dates(self):
|
||||||
@@ -81,7 +81,7 @@ class TestUserService(TestCase):
|
|||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
|
us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
|
||||||
date=one_day_after)
|
date=one_day_after)
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
|
us.increment_service_use(self.NOKIA_GEOCODER, 'failed_responses')
|
||||||
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
|
||||||
|
|
||||||
@freeze_time("2015-06-01")
|
@freeze_time("2015-06-01")
|
||||||
|
|||||||
Reference in New Issue
Block a user