diff --git a/client/Makefile b/client/Makefile index 6049479..167cac5 100644 --- a/client/Makefile +++ b/client/Makefile @@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql) # @see http://www.postgresql.org/docs/current/static/extend-pgxs.html DATA = $(NEW_EXTENSION_ARTIFACT) \ $(OLD_VERSIONS) \ - cdb_dataservices_client--0.3.0--0.4.0.sql \ - cdb_dataservices_client--0.4.0--0.3.0.sql + cdb_dataservices_client--0.4.0--0.5.0.sql \ + cdb_dataservices_client--0.5.0--0.4.0.sql REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql))) diff --git a/client/cdb_dataservices_client--0.4.0--0.5.0.sql b/client/cdb_dataservices_client--0.4.0--0.5.0.sql new file mode 100644 index 0000000..d200158 --- /dev/null +++ b/client/cdb_dataservices_client--0.4.0--0.5.0.sql @@ -0,0 +1,597 @@ +--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.5.0'" to load this file. \quit + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getdemographicsnapshot (geom geometry(Geometry, 4326), time_span text DEFAULT NULL, geometry_level text DEFAULT NULL) +RETURNS SETOF JSON 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_getdemographicsnapshot(username, orgname, geom, time_span, geometry_level); + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getsegmentsnapshot (geom geometry(Geometry, 4326), geometry_level text DEFAULT NULL) +RETURNS SETOF JSON 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_getsegmentsnapshot(username, orgname, geom, geometry_level); + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getboundary (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry AS $$ +DECLARE + ret Geometry; + 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; + + SELECT cdb_dataservices_client._obs_getboundary(username, orgname, geom, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getboundaryid (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + 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; + + SELECT cdb_dataservices_client._obs_getboundaryid(username, orgname, geom, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getboundarybyid (geometry_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry AS $$ +DECLARE + ret Geometry; + 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; + + SELECT cdb_dataservices_client._obs_getboundarybyid(username, orgname, geometry_id, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getboundariesbygeometry (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs 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_getboundariesbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getboundariesbypointandradius (geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs 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_getboundariesbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getpointsbygeometry (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs 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_getpointsbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getpointsbypointandradius (geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs 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_getpointsbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getmeasure (geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + 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; + + SELECT cdb_dataservices_client._obs_getmeasure(username, orgname, geom, measure_id, normalize, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getcategory (geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + 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; + + SELECT cdb_dataservices_client._obs_getcategory(username, orgname, geom, category_id, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getuscensusmeasure (geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + 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; + + SELECT cdb_dataservices_client._obs_getuscensusmeasure(username, orgname, geom, name, normalize, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getuscensuscategory (geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + 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; + + SELECT cdb_dataservices_client._obs_getuscensuscategory(username, orgname, geom, name, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getpopulation (geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + 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; + + SELECT cdb_dataservices_client._obs_getpopulation(username, orgname, geom, normalize, boundary_id, time_span) INTO ret; + RETURN ret; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_search (search_term text, relevant_boundary text DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source 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_search(username, orgname, search_term, relevant_boundary) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + +-- +-- Public dataservices API function +-- +-- These are the only ones with permissions to publicuser role +-- and should also be the only ones with SECURITY DEFINER + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_getavailableboundaries (geom Geometry, timespan text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename 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_getavailableboundaries(username, orgname, geom, timespan) AS query; + +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot (username text, organization_name text, geom geometry(Geometry, 4326), time_span text DEFAULT NULL, geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getdemographicsnapshot (username, organization_name, geom, time_span, geometry_level); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot (username text, organization_name text, geom geometry(Geometry, 4326), geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getsegmentsnapshot (username, organization_name, geom, geometry_level); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundary (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getboundary (username, organization_name, geom, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundaryid (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS text AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getboundaryid (username, organization_name, geom, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundarybyid (username text, organization_name text, geometry_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getboundarybyid (username, organization_name, geometry_id, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getboundariesbygeometry (username, organization_name, geom, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius (username text, organization_name text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getboundariesbypointandradius (username, organization_name, geom, radius, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbygeometry (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getpointsbygeometry (username, organization_name, geom, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius (username text, organization_name text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getpointsbypointandradius (username, organization_name, geom, radius, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasure (username text, organization_name text, geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getmeasure (username, organization_name, geom, measure_id, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getcategory (username text, organization_name text, geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getcategory (username, organization_name, geom, category_id, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensusmeasure (username text, organization_name text, geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getuscensusmeasure (username, organization_name, geom, name, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensuscategory (username text, organization_name text, geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getuscensuscategory (username, organization_name, geom, name, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpopulation (username text, organization_name text, geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getpopulation (username, organization_name, geom, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_search (username text, organization_name text, search_term text, relevant_boundary text DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_search (username, organization_name, search_term, relevant_boundary); + +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailableboundaries (username text, organization_name text, geom Geometry, time_span text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getavailableboundaries (username, organization_name, geom, time_span); + +$$ LANGUAGE plproxy; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdemographicsnapshot(geom geometry(Geometry, 4326), time_span text, geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getsegmentsnapshot(geom geometry(Geometry, 4326), geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundary(geom geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundaryid(geom geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundarybyid(geometry_id text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbygeometry(geom geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbypointandradius(geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbygeometry(geom geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbypointandradius(geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeasure(geom Geometry, measure_id text, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getcategory(geom Geometry, category_id text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensusmeasure(geom Geometry, name text, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensuscategory(geom Geometry, name text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpopulation(geom Geometry, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_search(search_term text, relevant_boundary text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailableboundaries(geom Geometry, time_span text) TO publicuser; diff --git a/client/cdb_dataservices_client--0.5.0--0.4.0.sql b/client/cdb_dataservices_client--0.5.0--0.4.0.sql new file mode 100644 index 0000000..c412da1 --- /dev/null +++ b/client/cdb_dataservices_client--0.5.0--0.4.0.sql @@ -0,0 +1,40 @@ +--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.4.0'" to load this file. \quit +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdemographicsnapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getsegmentsnapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundary(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundaryid(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundarybyid(text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbygeometry(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbypointandradius(geometry, numeric, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbygeometry(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbypointandradius(geometry, numeric, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasure(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getcategory(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensusmeasure(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensuscategory(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpopulation(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_search(text); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailableboundaries(geometry); + +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_demographic_snapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_segment_snapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getdemographicsnapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getsegmentsnapshot(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundary(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundaryid(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundarybyid(text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbygeometry(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbypointandradius(geometry, numeric, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbygeometry(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbypointandradius(geometry, numeric, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getmeasure(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getcategory(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensusmeasure(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensuscategory(geometry, text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpopulation(geometry); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_search(text); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailableboundaries(geometry); \ No newline at end of file diff --git a/client/cdb_dataservices_client.control b/client/cdb_dataservices_client.control index e8811fd..022051c 100644 --- a/client/cdb_dataservices_client.control +++ b/client/cdb_dataservices_client.control @@ -1,5 +1,5 @@ comment = 'CartoDB dataservices client API extension' -default_version = '0.4.0' +default_version = '0.5.0' requires = 'plproxy, cartodb' superuser = true schema = cdb_dataservices_client diff --git a/client/cdb_dataservices_client--0.3.0--0.4.0.sql b/client/old_versions/cdb_dataservices_client--0.3.0--0.4.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.3.0--0.4.0.sql rename to client/old_versions/cdb_dataservices_client--0.3.0--0.4.0.sql diff --git a/client/cdb_dataservices_client--0.4.0--0.3.0.sql b/client/old_versions/cdb_dataservices_client--0.4.0--0.3.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.4.0--0.3.0.sql rename to client/old_versions/cdb_dataservices_client--0.4.0--0.3.0.sql diff --git a/client/cdb_dataservices_client--0.4.0.sql b/client/old_versions/cdb_dataservices_client--0.4.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.4.0.sql rename to client/old_versions/cdb_dataservices_client--0.4.0.sql diff --git a/client/renderer/interface.yaml b/client/renderer/interface.yaml index 6496b5b..bb5de02 100644 --- a/client/renderer/interface.yaml +++ b/client/renderer/interface.yaml @@ -100,4 +100,163 @@ return_type: json params: - { name: geom, type: "geometry(Geometry, 4326)" } - - { name: geometry_level, type: text, default: "'\"us.census.tiger\".census_tract'::text" } \ No newline at end of file + - { name: geometry_level, type: text, default: "'\"us.census.tiger\".census_tract'::text" } + +- name: obs_getdemographicsnapshot + return_type: SETOF JSON + multi_row: true + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: time_span, type: "text", default: 'NULL' } + - { name: geometry_level, type: text, default: 'NULL' } + +- name: obs_getsegmentsnapshot + return_type: SETOF JSON + multi_row: true + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: geometry_level, type: text, default: 'NULL' } + +- name: obs_getboundary + return_type: Geometry + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getboundaryid + return_type: text + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getboundarybyid + return_type: Geometry + params: + - { name: geometry_id, type: text } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getboundariesbygeometry + return_type: TABLE(the_geom geometry, geom_refs text) + multi_row: true + multi_field: true + table_fields: + - { name: the_geom, type: geometry } + - { name: geom_refs, type: text } + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + - { name: overlap_type, type: text, default: "'intersects'"} + +- name: obs_getboundariesbypointandradius + return_type: TABLE(the_geom geometry, geom_refs text) + multi_row: true + multi_field: true + table_fields: + - { name: the_geom, type: geometry } + - { name: geom_refs, type: text } + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: radius, type: numeric } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + - { name: overlap_type, type: text, default: "'intersects'"} + +- name: obs_getpointsbygeometry + return_type: TABLE(the_geom geometry, geom_refs text) + multi_row: true + multi_field: true + table_fields: + - { name: the_geom, type: geometry } + - { name: geom_refs, type: text } + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + - { name: overlap_type, type: text, default: "'intersects'"} + +- name: obs_getpointsbypointandradius + return_type: TABLE(the_geom geometry, geom_refs text) + multi_row: true + multi_field: true + table_fields: + - { name: the_geom, type: geometry } + - { name: geom_refs, type: text } + params: + - { name: geom, type: "geometry(Geometry, 4326)" } + - { name: radius, type: numeric } + - { name: boundary_id, type: text } + - { name: time_span, type: text, default: 'NULL'} + - { name: overlap_type, type: text, default: "'intersects'"} + +- name: obs_getmeasure + return_type: numeric + params: + - { name: geom, type: Geometry } + - { name: measure_id, type: text } + - { name: normalize, type: text, default: "'area'"} + - { name: boundary_id, type: text, default: 'NULL' } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getcategory + return_type: text + params: + - { name: geom, type: Geometry } + - { name: category_id, type: text } + - { name: boundary_id, type: text, default: 'NULL' } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getuscensusmeasure + return_type: numeric + params: + - { name: geom, type: Geometry } + - { name: name, type: text } + - { name: normalize, type: text, default: "'area'"} + - { name: boundary_id, type: text, default: 'NULL' } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getuscensuscategory + return_type: text + params: + - { name: geom, type: Geometry } + - { name: name, type: text } + - { name: boundary_id, type: text, default: 'NULL' } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_getpopulation + return_type: numeric + params: + - { name: geom, type: Geometry } + - { name: normalize, type: text, default: "'area'"} + - { name: boundary_id, type: text, default: 'NULL' } + - { name: time_span, type: text, default: 'NULL'} + +- name: obs_search + return_type: TABLE(id text, description text, name text, aggregate text, source text) + multi_row: true + multi_field: true + table_fields: + - { name: id, type: text } + - { name: description, type: text } + - { name: name, type: text } + - { name: aggregate, type: text } + - { name: source, type: text } + params: + - { name: search_term, type: text } + - { name: relevant_boundary, type: text, default: 'NULL' } + +- name: obs_getavailableboundaries + return_type: TABLE(boundary_id text, description text, time_span text, tablename text) + multi_row: true + multi_field: true + table_fields: + - { name: boundary_id, type: text } + - { name: description, type: text } + - { name: time_span, type: text } + - { name: tablename, type: text } + params: + - { name: geom, type: Geometry } + - { name: timespan, type: text, default: 'NULL'} diff --git a/client/test/expected/90_data_observatory_test.out b/client/test/expected/90_data_observatory_test.out index 44aac0e..dcbed19 100644 --- a/client/test/expected/90_data_observatory_test.out +++ b/client/test/expected/90_data_observatory_test.out @@ -21,9 +21,151 @@ BEGIN RETURN ret; END; $$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdemographicsnapshot (username text, orgname text, geom geometry(Geometry, 4326), time_span text DEFAULT '2009 - 2013', geometry_level text DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ +DECLARE + ret json; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getdemographicsnapshot invoked with params (%, %, %, %, %)', username, orgname, geom, time_span, geometry_level; + SELECT '{"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null}'::json INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getsegmentsnapshot (username text, orgname text, geom geometry(Geometry, 4326), geometry_level text DEFAULT '"us.census.tiger".census_tract') +RETURNS json AS $$ +DECLARE + ret json; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getsegmentsnapshot invoked with params (%, %, %, %)', username, orgname, geom, geometry_level; + SELECT '{"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null}'::json INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundary (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry(Geometry, 4326) AS $$ +DECLARE + ret Geometry; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundary invoked with params (%, %, %, %, %)', username, orgname, geom, boundary_id, time_span; + SELECT '0106000020E6100000010000000103000000010000003500000056EF703B347C52C054FF2092215B44401B9AB2D30F7C52C03FE1ECD6325B4440B14B546F0D7C52C0BBCE86FC335B4440730F09DFFB7B52C0B796C9703C5B4440108FC4CBD37B52C0B96C74CE4F5B444001C0B167CF7B52C0ED0BE8853B5B4440C843DFDDCA7B52C05DDDB1D8265B4440A73D25E7C47B52C0D53BDC0E0D5B4440BB5E9A22C07B52C0F8A3A833F75A4440355F251FBB7B52C0B64604E3E05A444008910C39B67B52C098BF42E6CA5A44405227A089B07B52C0F204C24EB15A444024F1F274AE7B52C069E4F38AA75A44402B4A09C1AA7B52C06B63EC84975A4440E199D024B17B52C0546F0D6C955A44403C873254C57B52C02EAC1BEF8E5A44402593533BC37B52C0588AE42B815A4440973AC8EBC17B52C087890629785A44407A6F0C01C07B52C0E1EB6B5D6A5A44401B9B1DA9BE7B52C03F6F2A52615A444088855AD3BC7B52C088669E5C535A4440E1EA0088BB7B52C0E6E95C514A5A44400CE6AF90B97B52C070D05E7D3C5A44401E85EB51B87B52C0B03A72A4335A4440BAF3C473B67B52C09929ADBF255A4440CD920035B57B52C0454AB3791C5A4440F78DAF3DB37B52C0E09BA6CF0E5A4440DBC2F352B17B52C0703FE081015A444015C440D7BE7B52C05E83BEF4F659444041446ADAC57B52C0EFDFBC38F15944405FB1868BDC7B52C0C03E3A75E559444034BC5983F77B52C0205ED72FD8594440EFFCA204FD7B52C07E384888F25944403ACAC16C027C52C00876FC17085A444056478E74067C52C00FECF82F105A44400FECF82F107C52C0876D8B321B5A4440BB438A01127C52C0DE1CAED51E5A4440B9C15087157C52C034643C4A255A444099F221A81A7C52C0D0EFFB372F5A44404AED45B41D7C52C0785DBF60375A4440373465A71F7C52C065A71FD4455A4440C558A65F227C52C0D80DDB16655A4440F92EA52E197C52C09BA73AE4665A4440DEE522BE137C52C00664AF777F5A44405698BED7107C52C04759BF99985A444012D90759167C52C09430D3F6AF5A444044679945287C52C01F680586AC5A444049F086342A7C52C09CC3B5DAC35A44401FF5D72B2C7C52C0CB811E6ADB5A4440247EC51A2E7C52C0548B8862F25A4440FF59F3E32F7C52C0CB290131095B4440F96871C6307C52C09605137F145B444056EF703B347C52C054FF2092215B4440'::geometry INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundaryid (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundaryid invoked with params (%, %, %, %, %)', username, orgname, geom, boundary_id, time_span; + SELECT '36047048500'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundarybyid (username text, orgname text, geometry_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry(Geometry, 4326) AS $$ +DECLARE + ret Geometry; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundarybyid invoked with params (%, %, %, %, %)', username, orgname, geometry_id, boundary_id, time_span; + SELECT '0106000020E610000001000000010300000001000000930200005051F52B9D8352C042B28009DC50444093C2BCC7998352C0E89E758D965144402EFD4B52998352C09A07B0C8AF514440E75086AA988352C022FAB5F5D351444027874F3A918352C0A46B26DF6C53444018E945ED7E8352C04D81CCCEA25344401346B3B27D8352C05D50DF32A753444068226C787A8352C08D25AC8DB153444015C8EC2C7A8352C004560E2DB2534440DF8618AF798352C00FD07D39B3534440FEB627486C8352C0DC9E20B1DD534440B98C9B1A688352C05D328E91EC5344408B8A389D648352C0929048DBF853444075CAA31B618352C0986A662D05544440EA758BC0588352C0D6C397892254444048DFA469508352C0151DC9E53F544440B67F65A5498352C0F73DEAAF575444401403249A408352C05E2A36E6755444402367614F3B8352C06DE2E47E8754444011FC6F253B8352C0431B800D885444403E7958A8358352C0DD0A6135965444401D739EB12F8352C093DFA293A5544440FB04508C2C8352C035289A07B05444401EA4A7C8218352C0347F4C6BD3544440D7C05609168352C05053CBD6FA544440AC8E1CE90C8352C0C9AA083719554440FC8D76DCF08252C0BD18CA897655444048895DDBDB8252C0C3B7B06EBC554440698995D1C88252C032207BBDFB55444004A73E90BC8252C0DB4C857824564440BC1FB75F3E8252C08F368E588B574440E15D2EE23B8252C066F4A3E194574440C614AC71368252C0381268B0A9574440CEA44DD53D8152C04F1F813FFC564440A51133FB3C8152C0F607CA6DFB56444070D05E7D3C8152C0CB0C1B65FD564440C5C6BC8E388152C0F303577902574440EA043411368152C03F390A1005574440840B7904378152C0D34ECDE506574440390A1005338152C047E350BF0B5744405D143DF0318152C0D53BDC0E0D5744401D59F965308152C00A4966F50E574440236420CF2E8152C00FD253E41057444084EE92382B8152C0AD2D3C2F15574440E23D0796238152C0A304FD851E574440B3EDB435228152C001D9EBDD1F5744401EBE4C14218152C08BDCD3D51D574440A2D0B2EE1F8152C0FC1BB4571F57444007B0C8AF1F8152C0CC9717601F574440F678211D1E8152C0374E0AF31E5744401A69A9BC1D8152C0793D98141F574440102384471B8152C0CB2F833122574440B7EEE6A90E8152C09F1D705D315744405968E7340B8152C02C0E677E355744400E4A9869FB8052C0C91EA166485744401B2C9CA4F98052C05C001AA54B5744401AF8510DFB8052C0C51A2E724F574440925CFE43FA8052C0309DD66D50574440BB9866BAD78052C0035DFB027A574440A04FE449D28052C02920ED7F80574440DC9BDF30D18052C0E8305F5E80574440B43C0FEECE8052C0D8614CFA7B5744404AEEB089CC8052C0950A2AAA7E5744409A5B21ACC68052C032FE7DC6855744406682E15CC38052C01EF7ADD689574440F78DAF3DB38052C020CD58349D5744402FFA0AD28C8052C00919C8B3CB574440D0251C7A8B8052C00EA2B5A2CD57444001DE02098A8052C030444E5FCF5744404A404CC2858052C0992A1895D45744403480B740828052C0A33CF372D857444028ECA2E8818052C0CD0358E4D7574440F3AACE6A818052C074ECA012D75744402920ED7F808052C0DFA293A5D657444036E84B6F7F8052C092054CE0D6574440AD4CF8A57E8052C0E55FCB2BD757444042CA4FAA7D8052C01AA19FA9D7574440A2EC2DE57C8052C0205ED72FD8574440BB6246787B8052C08BE07F2BD95744405C74B2D47A8052C025E7C41EDA5744405CA8FC6B798052C0F52EDE8FDB574440FF0758AB768052C09AAF928FDD574440A60A4625758052C0C442AD69DE574440A73E90BC738052C05E49F25CDF574440BF9A0304738052C046ED7E15E0574440A19BFD81728052C070B4E386DF5744403D0AD7A3708052C0D0F0660DDE574440680586AC6E8052C04D469561DC57444063963D096C8052C0965AEF37DA574440944E24986A8052C0BA641C23D957444059501894698052C014B01D8CD8574440E21FB6F4688052C0614D6551D85744401895D409688052C0205ED72FD85744406379573D608052C0A4A487A1D55744401878EE3D5C8052C041B5C189E85744402F4FE78A528052C0A580B4FF01584440983270404B8052C0EECEDA6D1758444050357A35408052C0E3C281902C58444086C43D963E8052C0DC9DB5DB2E584440C5E061DA378052C0BFF2203D455844409946938B318052C0C4E9245B5D5844407C478D09318052C040A374E95F584440E3A8DC442D8052C0F92AF9D85D584440919C4CDC2A8052C06BD26D895C584440276893C3278052C0E9279CDD5A58444053B131AF238052C061C092AB5858444055336B29208052C068E55E605658444091990B5C1E8052C082C64CA25E584440AA2688BA0F8052C027F6D03E56584440F488D1730B8052C0D21C59F9655844400C1CD0D2158052C0BB96900F7A584440C6A69542208052C0B77BB94F8E584440D3A23EC91D8052C02EC901BB9A584440B6BDDD921C8052C0BF42E6CAA058444082E49D43198052C036902E36AD58444072FBE593158052C0ACA92C0ABB5844402B4F20EC148052C0EC3026FDBD584440E4BCFF8F138052C04E266E15C4584440C26856B60F8052C06E15C440D7584440C404357C0B8052C00F5EBBB4E1584440397CD289048052C0CA87A06AF4584440FB761211FE7F52C090F7AA9509594440D93C0E83F97F52C03561FBC9185944402828452BF77F52C0F06DFAB31F594440F9BD4D7FF67F52C0DC9A745B225944403AADDBA0F67F52C0BE4D7FF62359444093C49272F77F52C0526342CC25594440450DA661F87F52C0798EC87729594440F2CCCB61F77F52C0067FBF982D5944409B030473F47F52C017821C94305944401E300F99F27F52C05609168733594440E57FF277EF7F52C0EDBAB72231594440A3AA09A2EE7F52C0EA1ED95C355944405D18E945ED7F52C0D3F6AFAC345944401C5DA5BBEB7F52C076DB85E63A5944404BADF71BED7F52C0B1D991EA3B5944401F477364E57F52C0E48409A35959444022179CC1DF7F52C001D8800871594440A4703D0AD77F52C02EC6C03A8E594440457F68E6C97F52C061C26856B659444070404B57B07F52C0FCDEA63FFB594440DC10E335AF7F52C048E00F3FFF59444055F7C8E6AA7F52C02DB4739A055A4440A4E2FF8EA87F52C00CFFE9060A5A44407E8AE3C0AB7F52C0EC4960730E5A444006F2ECF2AD7F52C08CD99255115A444042588D25AC7F52C09BA8A5B9155A44405A9A5B21AC7F52C0F4BF5C8B165A44406762BA10AB7F52C0A5BA8097195A4440E5B7E864A97F52C0B6BDDD921C5A44402B4A09C1AA7F52C0499F56D11F5A4440D48041D2A77F52C0177FDB13245A4440C22FF5F3A67F52C0D55B035B255A4440FE7BF0DAA57F52C0F8FD9B17275A44409A046F48A37F52C04FADBEBA2A5A444045F12A6B9B7F52C0AC1919E42E5A44404BE2AC889A7F52C0A75CE15D2E5A4440462575029A7F52C0965984622B5A4440E75086AA987F52C0906802452C5A44400B2769FE987F52C05FB01BB62D5A444004029D499B7F52C0DD2230D6375A44404301DBC1887F52C0CBF10A444F5A4440D6A88768747F52C0B81E85EB515A44407C0C569C6A7F52C0F6CFD380415A4440CB113290677F52C0A9328CBB415A44407905A227657F52C03D7C9928425A44407EA5F3E1597F52C0787AA52C435A444009F7CABC557F52C0A2410A9E425A44408D23D6E2537F52C00EF8FC30425A444029780AB9527F52C08B19E1ED415A44402992AF04527F52C08B19E1ED415A4440C51A2E724F7F52C08B19E1ED415A4440AC36FFAF3A7F52C01AA6B6D4415A444009522976347F52C0A2410A9E425A4440F25D4A5D327F52C0252026E1425A44408252B4722F7F52C05A61FA5E435A444032E202D0287F52C013B534B7425A4440E0BBCD1B277F52C014E97E4E415A44409352D0ED257F52C0151DC9E53F5A444022F94A20257F52C0B08BA2073E5A4440CF9ECBD4247F52C0F3AE7AC03C5A444077A1B94E237F52C0F3AE7AC03C5A4440DDB419A7217F52C097FBE428405A4440666A12BC217F52C016A243E0485A44408EACFC32187F52C0CD8DE9094B5A44404F05DCF3FC7E52C0B952CF82505A4440D2E0B6B6F07E52C0FFCA4A93525A44404F029B73F07E52C0A7E7DD58505A4440EA3C2AFEEF7E52C020B41EBE4C5A44404A5F0839EF7E52C01AF7E6374C5A4440D462F030ED7E52C055F5F23B4D5A4440825660C8EA7E52C0B5FD2B2B4D5A4440825660C8EA7E52C072DA53724E5A44403C2CD49AE67E52C030B77BB94F5A44400DDC813AE57E52C0D76B7A50505A4440670DDE57E57E52C0072461DF4E5A4440C77DAB75E27E52C0A25EF0694E5A4440ABB2EF8AE07E52C04F04711E4E5A44403A3FC571E07E52C03C65355D4F5A4440643A747ADE7E52C04ED026874F5A444077F35487DC7E52C08A027D224F5A4440F0A5F0A0D97E52C031EBC5504E5A444068588CBAD67E52C0D8D30E7F4D5A444046B3B27DC87E52C06FB9FAB1495A4440B85A272EC77E52C03C821B295B5A444039CE6DC2BD7E52C097016729595A44409A07B0C8AF7E52C07FD93D79585A44407E8AE3C0AB7E52C0EBC37AA3565A4440C1E10511A97E52C0D097DEFE5C5A44401B82E3326E7E52C03F170D198F5A44408A3C49BA667E52C0D619DF17975A444026DF6C73637E52C07A32FFE89B5A4440E78BBD175F7E52C000FE2955A25A4440594DD7135D7E52C040852348A55A4440E36A64575A7E52C03EE94482A95A4440E603029D497E52C067B62BF4C15A4440ED42739D467E52C04701A260C65A4440253ACB2C427E52C03E40F7E5CC5A4440D026874F3A7E52C061C5A9D6C25A44405C5837DE1D7E52C0868F8829915A4440162EABB0197E52C007B5DFDA895A4440B859BC58187E52C083A279008B5A44408FE046CA167E52C011FB04508C5A4440B131AF230E7E52C0D2C43BC0935A44401A4CC3F0117E52C0F0FACC599F5A44401A321EA5127E52C06631B1F9B85A44402B836A83137E52C0E55C8AABCA5A4440C9737D1F0E7E52C0B376DB85E65A4440D3687231067E52C07405DB88275B444009DE9046057E52C09A94826E2F5B4440158C4AEA047E52C08D7E349C325B4440C808A870047E52C0B6114F76335B4440634337FB037E52C00F290648345B4440DAA7E331037E52C03E7958A8355B444082902C60027E52C0DE3CD521375B4440AB5791D1017E52C048BF7D1D385B4440942F6821017E52C095287B4B395B4440268C6665FB7D52C0548A1D8D435B44405C1B2AC6F97D52C065187783685B4440FA0B3D62F47D52C03FE08101845B4440E2E313B2F37D52C03196E997885B444038F4160FEF7D52C05D50DF32A75B4440109546CCEC7D52C07FDB1324B65B44401C261AA4E07D52C0BA641C23D95B444076BF0AF0DD7D52C06AF7AB00DF5B4440DCB8C5FCDC7D52C0B06F2711E15B44405A0EF450DB7D52C0081F4AB4E45B444084D558C2DA7D52C0F57F0EF3E55B4440BBB20B06D77D52C06E693524EE5B4440CE6BEC12D57D52C0FB592C45F25B444073672618CE7D52C09A0645F3005C4440BB7B80EECB7D52C0C7BAB88D065C4440F5F411F8C37D52C057E9EE3A1B5C44407B8670CCB27D52C09AB4A9BA475C4440240B98C0AD7D52C0282A1BD6545C4440E4839ECDAA7D52C0FA5E43705C5C4440E4805D4D9E7D52C08AAA5FE97C5C44401B2AC6F99B7D52C01C2444F9825C4440D3122BA3917D52C059F8FA5A975C4440A7ACA6EB897D52C0FD2D01F8A75C444007B5DFDA897D52C04818062CB95C44401EF7ADD6897D52C0399A232BBF5C444036397CD2897D52C0904946CEC25C444001DE02098A7D52C08A58C4B0C35C4440CB68E4F38A7D52C0527B116DC75C4440AD4F39268B7D52C0AB92C83EC85C4440531EDD088B7D52C0EB19C231CB5C4440C5C551B9897D52C070EB6E9EEA5C444090847D3B897D52C02E5393E00D5D44409C4CDC2A887D52C01D39D219185D4440FC6EBA65877D52C00D87A5811F5D4440D9CC21A9857D52C0641F6459305D44402D7590D7837D52C0DB4FC6F8305D44409354A698837D52C03FE1ECD6325D44402D5BEB8B847D52C05CC64D0D345D44403A3DEFC6827D52C02C0E677E355D44405299620E827D52C0938C9C853D5D444011AAD4EC817D52C0CE8AA8893E5D44407689EAAD817D52C045BB0A293F5D444094A2957B817D52C02C5F97E13F5D4440EDED96E4807D52C060048D99445D44407C7A6CCB807D52C00551F701485D4440BE69FAEC807D52C0999A046F485D44401781B1BE817D52C0ECF483BA485D444028ECA2E8817D52C0F6D214014E5D44403480B740827D52C07024D060535D4440BD35B055827D52C0CEF8BEB8545D44401C3EE944827D52C03F389F3A565D4440FF243E77827D52C0B534B742585D44407B2C7DE8827D52C02AFD84B35B5D44406F7EC344837D52C0535C55F65D5D4440DA006C40847D52C041F163CC5D5D4440459DB987847D52C0CE15A584605D4440FDBCA948857D52C0F4A44C6A685D44408658FD11867D52C097A608707A5D44404FAF9465887D52C03EC91D36915D4440BD38F1D58E7D52C0CFF753E3A55D44406876DD5B917D52C0F1B6D26BB35D44405B7A34D5937D52C0E4F1B4FCC05D4440B6476FB88F7D52C0C0E78711C25D4440743E3C4B907D52C0A5BBEB6CC85D4440D190F128957D52C03A394371C75D4440ADA06989957D52C0512D228AC95D4440D74D29AF957D52C01BB80375CA5D4440307F85CC957D52C0E542E55FCB5D444042EA76F6957D52C049D40B3ECD5D444054556820967D52C0B3226AA2CF5D44408F6D1970967D52C0C189E8D7D65D4440AD6C1FF2967D52C0F71BEDB8E15D4440BED7101C977D52C0C8B4368DED5D4440D47D00529B7D52C0EBE1CB44115E44403F00A94D9C7D52C068774831405E4440F7393E5A9C7D52C04339D1AE425E44409831056B9C7D52C090A2CEDC435E4440984BAAB69B7D52C02384471B475E4440A547533D997D52C04ED026874F5E44403F170D198F7D52C00E661360585E4440545227A0897D52C0E202D0285D5E4440D3139678407D52C026A435069D5E44406C753925207D52C0CA54C1A8A45E44403B1BF2CF0C7D52C0E17CEA58A55E4440FD12F1D6F97C52C078962023A05E444068C9E369F97C52C0A81ABD1AA05E44406FBA6587F87C52C037A79201A05E44407008556AF67C52C0CC24EA059F5E44404CE141B3EB7C52C0F3FE3F4E985E444003CE52B29C7C52C06C239EEC665E44409AB33EE5987C52C020EEEA55645E4440DFC0E446917C52C0CF6394675E5E444014200A664C7C52C07F315BB22A5E44401D8D43FD2E7C52C0D71533C2DB5D4440C4758C2B2E7C52C09C4B7155D95D4440EE08A7052F7C52C0444B1E4FCB5D444091B6F1272A7C52C0A7069ACFB95D444014C95702297C52C0CC785BE9B55D4440807F4A95287C52C0567C43E1B35D44407405DB88277C52C0A0C4E74EB05D44400057B263237C52C07E39B35DA15D4440AC8BDB68007C52C0AB90F2936A5D444025E4839ECD7B52C0395E81E8495D444018265305A37B52C0C2DCEEE53E5D44402781CD39787B52C0685721E5275D4440514832AB777B52C0639AE95E275D4440F2599E07777B52C0EC6987BF265D4440F94A2025767B52C0B16B7BBB255D44409485AFAF757B52C088D860E1245D4440893F8A3A737B52C09622F94A205D44408D0C7217617B52C0BF5E61C1FD5C444026C286A7577B52C0D3DA34B6D75C4440FCDD3B6A4C7B52C0D0967329AE5C444030630AD6387B52C082C64CA25E5C444081E7DEC3257B52C0A33B889D295C4440639AE95E277B52C0D47FD6FCF85B44407EC34483147B52C03A394371C75B4440342A70B20D7B52C0D826158DB55B444099EFE0270E7B52C06762BA10AB5B4440D3F36E2C287B52C0350873BB975B4440D427B9C3267B52C07842AF3F895B4440C4245CC8237B52C030D7A205685B4440880CAB78237B52C08B8A389D645B4440902E36AD147B52C0718C648F505B4440AF928FDD057B52C05169C4CC3E5B44407E8978EBFC7A52C0FC1BB4571F5B44409DF0129CFA7A52C05D86FF74035B4440DCD8EC48F57A52C044A51133FB5A444027BD6F7CED7A52C0D769A4A5F25A44406B9C4D47007B52C0E4F4F57CCD5A4440F29881CAF87A52C095D233BDC45A44403F19E3C3EC7A52C05BEB8B84B65A44403468E89FE07A52C0DF14562AA85A4440E0F08288D47A52C0224F92AE995A44403448C153C87A52C0B8E34D7E8B5A44401155F833BC7A52C06C91B41B7D5A44401DE6CB0BB07A52C050C3B7B06E5A444029779FE3A37A52C0A568E55E605A44400584D6C3977A52C0889AE8F3515A44401215AA9B8B7A52C0DD3F16A2435A4440EE21E17B7F7A52C0C1711937355A4440B3EC4960737A52C0E692AAED265A4440D7BFEB33677A52C0CAC4AD82185A4440E350BF0B5B7A52C04EEE77280A5A4440CE18E6046D7A52C001FA7DFFE6594440DAA9B9DC607A52C0B5A7E49CD8594440B7B6F0BC547A52C0DAC87553CA594440DB899290487A52C0ED7E15E0BB594440CB0EF10F5B7A52C0239D819197594440A25EF0694E7A52C0B340BB438A594440BBEB6CC83F7A52C092E9D0E9795944407F68E6C9357A52C033C4B12E6E594440205D6C5A297A52C05DA27A6B605944401B834E081D7A52C065AA605452594440765089EB187A52C0A27895B54D5944402A357BA0157A52C07B4D0F0A4A5944408A5759DB147A52C0F2B1BB404959444097530262127A52C0D0436D1B465944409E5E29CB107A52C0ADA1D45E445944400A630B410E7A52C07F85CC9541594440DB12B9E00C7A52C00F46EC134059444000378B170B7A52C039419B1C3E5944408A20CEC3097A52C06AF981AB3C59444080423D7D047A52C0670C738236594440CAA48636007A52C034677DCA31594440BF44BC75FE7952C0A051BAF42F594440605628D2FD7952C077BE9F1A2F59444093AAED26F87952C0DF87838428594440CFF6E80DF77952C033164D672759444011346612F57952C07C2AA73D2559444001310917F27952C0E8482EFF21594440730CC85EEF7952C05567B5C01E594440984A3FE1EC7952C0B6D782DE1B5944404CE141B3EB7952C0570394861A594440C91CCBBBEA7952C00B9A9658195944408E1EBFB7E97952C08EACFC3218594440A794D74AE87952C08FE046CA165944409677D503E67952C0B41EBE4C145944402EC55565DF7952C0E2E995B20C5944408F52094FE87952C09DF0129CFA58444052EC681CEA7952C06326512FF8584440E02D90A0F87952C0739EB12FD9584440519E7939EC7952C05C8DEC4ACB584440938AC6DADF7952C0A5846055BD5844401666A19DD37952C07C08AA46AF58444029CE5147C77952C0B3942C27A1584440B2666490BB7952C0AEEE586C935844404E232D95B77952C0EDF0D7648D584440A4198BA6B37952C0FC6EBA65875844401E34BBEEAD7952C0179B560A81584440A297512CB77952C0289831056B5844400DE02D90A07952C0B3D0CE6916584440789961A3AC7952C0A6D1E4620C58444076FEEDB25F7952C015713AC956574440D50627A25F7952C06072A3C85A574440E7A562635E7952C0E08096AE6057444012876C205D7952C05AD2510E6657444072C3EFA65B7952C0C4EC65DB69574440FCC6D79E597952C0374D9F1D7057444051D7DAFB547952C0554FE61F7D574440658D7A88467952C04F1DAB949E57444008556AF6407952C04A7D59DAA95744406F9C14E63D7952C0A5811FD5B0574440A679C7293A7952C09CC0745AB757444061FBC9181F7952C097A608707A574440B0C91AF5107952C03483F8C08E5744402E36AD14027952C0718BF9B9A1574440D4997B48F87852C089D00836AE574440BBD23252EF7852C090BB085394574440EF8E8CD5E67852C01840F850A2574440EACE13CFD97852C0B6847CD0B35744408C48145AD67852C09012BBB6B7574440E690D442C97852C084B53176C257444063F030ED9B7852C090BA9D7DE5574440DFC0E446917852C0DEE2E13D075844403FFD67CD8F7852C0719010E50B5844401C2785798F7852C0764D486B0C584440B1BE81C98D7852C093FE5E0A0F58444037363B527D7852C0093543AA28584440C3D50110777852C09355116E32584440EEE714E4677852C03387A4164A584440717500C45D7852C07EA5F3E1595844407442E8A04B7852C0E108522976584440211CB3EC497852C0CE35CCD0785844405791D101497852C09D7DE5417A584440CB660E492D7852C0056A3178985844401AC1C6F5EF7752C0B9162D40DB5844400F7C0C569C7752C03EE8D9ACFA584440AC1E300F997752C0828AAA5FE9584440A661F888987752C0C2A38D23D6584440DCBC7152987752C042959A3DD0584440A661F888987752C0302AA913D0584440E7FF55478E7752C05DC2A1B7785844402FFA0AD28C7752C0581CCEFC6A584440DCB930D28B7752C021567F8461584440FB20CB82897752C062D7F6764B58444079909E22877752C0D89942E7355844408C63247B847752C0B58993FB1D584440ACE46377817752C0677E350708584440C6C210397D7752C0B2F4A10BEA57444074B680D07A7752C0909DB7B1D9574440DB317557767752C0077767EDB65744409A7631CD747752C02D7B12D89C5744400D6C9560717752C054FEB5BC72574440FC34EECD6F7752C0A3E6ABE4635744409E7AA4C16D7752C0D1949D7E50574440FE9C82FC6C7752C0E046CA16495744401E4FCB0F5C7752C09B53C90050574440D503E621537752C0E063B0E25457444037DC476E4D7752C032569BFF5757444070ED4449487752C0836C59BE2E57444066F50EB7437752C054C554FA0957444032022A1C417752C0713C9F01F55644404487C091407752C01F7EFE7BF05644406E4E2503407752C05D4C33DDEB56444088F546AD307752C03ECBF3E0EE5644401F0F7D772B7752C04835ECF7C4564440A33B889D297752C026AAB706B656444087A4164A267752C0938E72309B5644403B6F63B3237752C050FD834886564440D7F7E120217752C00D6C956071564440132A38BC207752C07A8A1C226E564440315D88D51F7752C07E8E8F1667564440D4F02DAC1B7752C0ADA415DF505644409E95B4E21B7752C09AE8F35146564440B88D06F0167752C0BB46CB811E564440A435069D107752C0C8E88024EC554440C9703C9F017752C0F01307D0EF55444083DE1B43007752C0855D143DF05544404EB4AB90F27652C0A69718CBF45544401ABE8575E37652C0C214E5D2F855444041649126DE7652C0FACE2F4AD0554440293C6876DD7652C0807D74EACA554440FAD170CADC7652C0779FE3A3C55544403FABCC94D67652C0F58079C8945544405AD76839D07652C0B41D537765554440849ECDAACF7652C0272D5C56615544405DA79196CA7652C0D87F9D9B36554440331477BCC97652C06A10E6762F55444060AB048BC37652C062F20698F95444402D23F59ECA7652C05D6919A9F754444011C30E63D27652C0B8E864A9F554444021C9ACDEE17652C073D87DC7F0544440F0F96184F07652C06FB72407EC5444408577B988EF7652C0DFA5D425E3544440A089B0E1E97652C0C8091346B35444403621AD31E87652C0999CDA19A6544440C763062AE37652C0EF3B86C77E5444401F4AB4E4F17652C0E0D4079277544440E2E65432007752C054E4107173544440FF0241800C7752C061FA5E437054444057B26323107752C0F677B6476F5444402026E1421E7752C00FEB8D5A61544440834F73F2227752C0E3361AC05B544440C2F693313E7752C0C05AB56B4254444097900F7A367752C0780C8FFD2C544440F834272F327752C06684B70721544440C4758C2B2E7752C03D0801F9125444408D959867257752C00E4A9869FB534440E68F696D1A7752C02FF99FFCDD53444022C2BF081A7752C0247F30F0DC534440EF1CCA50157752C03599F1B6D2534440C0B2D2A4147752C06551D845D15344409048DBF8137752C09509BFD4CF53444014419C87137752C0FB027AE1CE534440E5F04927127752C01A84B9DDCB53444092B06F27117752C0DAC87553CA5344407EA65EB7087752C0228C9FC6BD534440A3E4D539067752C065170CAEB9534440C2FA3F87F97652C059F5B9DA8A5344408BFA2477D87652C082A62556465344406403E962D37652C03197546D3753444018B49080D17652C0D5928E72305344404A22FB20CB7652C0765089EB185344402A1900AAB87652C0BE0F070951524440E386DF4DB77652C01F63EE5A425244400F7D772B4B7652C005A568E55E524440FB3F87F9F27552C07D224F92AE5144405793A7ACA67552C0D7C0560916514440BEDA519CA37552C0A44FABE80F514440745B22179C7552C0E2CCAFE600514440DCD6169E977552C00B43E4F4F5504440A93121E6927552C05E807D74EA504440D13FC1C58A7552C056ED9A90D6504440096B63EC847552C0AB92C83EC8504440AE80423D7D7552C04127840EBA50444040F7E5CC767552C0D0967329AE50444089CE328B507552C0162D40DB6A504440C8ED974F567552C05646239F57504440211FF46C567552C03674B33F5050444015713AC9567552C059DC7F643A5044404AB20E47577552C028B682A62550444037AB3E575B7552C0F7AE415F7A4F44408D261763607552C0226C787AA54E444045460724617552C0A94885B1854E4440F62686E4647552C02D978DCEF94D444036AE7FD7677552C018AE0E80B84D4440B9E00CFE7E7552C0B01F6283854D4440446B459BE37552C0C5E23785954C444012A27C410B7652C03C1405FA444C4440588B4F01307652C0B058C345EE4B4440A6457D923B7652C07C28D192C74B44402C9CA4F9637652C0A2957B81594B4440A81ABD1AA07652C0300C5872154B4440FBC8AD49B77652C035272F32014B44404127840EBA7652C02AE109BDFE4A44401DCBBBEA017752C02172FA7ABE4A4440130CE71A667752C0C6A2E9EC644A44400A4B3CA06C7752C0BEF8A23D5E4A4440A5D93C0E837752C06473D53C474A4440FDBCA948857752C06B98A1F1444A4440F0C000C2877752C0F0DE5163424A4440D8817346947752C04450357A354A4440BF28417FA17752C08099EFE0274A44400A2DEBFEB17752C0BCAE5FB01B4A44407FF8F9EFC17752C08C0DDDEC0F4A444053C90050C57752C0B14B546F0D4A44402E71E481C87752C0BF61A2410A4A44401EFB592C457852C09F39EB538E494440056D72F8A47852C06D8E739B7049444036AD1402B97852C0D68BA19C68494440F59F353FFE7852C0BAA0BE654E494440289A07B0C87952C0C58F31772D4944406133C005D97952C0D862B7CF2A494440E1783E03EA7952C04DDA54DD2349444046B3B27DC87A52C06A11514CDE4844402F185C73477B52C0FCE25295B6484440A26131EA5A7B52C06A696E85B04844408499B67F657B52C036902E36AD4844404F8F6D19707B52C0C1C760C5A94844402E1D739EB17B52C02BDCF29194484440F9122A38BC7B52C0B5132521914844401021AE9CBD7B52C080D250A39048444081CEA44DD57B52C0431B800D88484440BBB88D06F07B52C076A38FF980484440B5A50EF27A7C52C07780272D5C484440F7C77BD5CA7C52C08AE5965643484440614D6551D87C52C05CFDD8243F484440E84CDA54DD7C52C03F1878EE3D4844409947FE60E07C52C05774EB353D484440AF0793E2E37C52C0FF5C34643C48444065A54929E87C52C0C45E28603B484440EFAB72A1F27C52C01F12BEF737484440D07D39B35D7D52C0075F984C1548444025AB22DC647D52C03D0801F912484440C39E76F86B7D52C0861C5BCF104844401211FE45D07F52C0F2CEA10C55474440B804E09F528252C0785C548B884644407615527E528252C0DB85E63A8D464440E2E5E95C518252C0BB270F0BB546444089B48D3F518252C0A7203F1BB94644400858AB764D8252C0F294D5743D474440CD565EF23F8252C07D7555A0164944401B28F04E3E8252C0E9F010C64F494440AAB4C5353E8252C0BDC117265349444032CB9E04368252C0F6285C8FC24944405111A7936C8252C09FE238F06A4B44402252D32EA68252C0BC02D193324D44404C50C3B7B08252C0F9F36DC1524D444068075C57CC8252C0ECDCB419A74D4440A31F0DA7CC8252C086E3F90CA84D44409D2E8B89CD8252C0438CD7BCAA4D44402BA1BB24CE8252C00726378AAC4D4440DDE9CE13CF8252C035423F53AF4D4440A774B0FECF8252C0C266800BB24D4440A626C11BD28252C007431D56B84D4440EDD286C3D28252C0DC476E4DBA4D44402638F581E48252C04A5F0839EF4D444074779D0DF98252C0E3C281902C4E4440890629780A8352C016DC0F78604E44408315A75A0B8352C0E5EFDE51634E4440EA793716148352C036E84B6F7F4E44404703780B248352C0C24CDBBFB24E44403046240A2D8352C09BE09BA6CF4E4440A4C00298328352C02D776682E14E444055F833BC598352C09F91088D604F4440B3B27DC85B8352C08922A46E674F444075E789E76C8352C066118AADA04F44400D52F014728352C051F355F2B14F4440C5ABAC6D8A8352C0D4D00660035044403D7E6FD39F8352C05C1ABFF04A5044405051F52B9D8352C042B28009DC504440'::geometry INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundariesbypointandradius (username text, orgname text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundariesbypointandradius invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, radius, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0106000020E6100000010000000103000000010000001500000083A3E4D5397C52C09946938B315A44404AED45B41D7C52C0785DBF60375A444099F221A81A7C52C0D0EFFB372F5A4440B9C15087157C52C034643C4A255A4440BB438A01127C52C0DE1CAED51E5A44400FECF82F107C52C0876D8B321B5A4440510FD1E80E7C52C0C4D32B65195A44407FDAA84E077C52C0E0675C38105A444092AD2EA7047C52C08E75711B0D5A4440CF2D7425027C52C0A86DC328085A4440EFFCA204FD7B52C07E384888F259444034BC5983F77B52C0205ED72FD8594440E76F4221027C52C0F3A96395D259444081AD122C0E7C52C00ED6FF39CC594440CB63CDC8207C52C031276893C359444047205ED72F7C52C0287D21E4BC594440BD1C76DF317C52C0F8325184D4594440CD1FD3DA347C52C0B0A9F3A8F8594440C72E51BD357C52C0C3651536035A444043024697377C52C028999CDA195A444083A3E4D5397C52C09946938B315A4440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpointsbygeometry (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpointsbygeometry invoked with params (%, %, %, %, %, %)', username, orgname, geom, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0101000020E610000037CB75821A7C52C0BA8784EFFD594440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpointsbypointandradius (username text, orgname text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpointsbypointandradius invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, radius, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0101000020E610000037CB75821A7C52C0BA8784EFFD594440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getmeasure (username text, orgname text, geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getmeasure invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, measure_id, normalize, boundary_id, time_span; + SELECT 10923.093200390833950::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getcategory (username text, orgname text, geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getcategory invoked with params (%, %, %, %, %, %)', username, orgname, geom, category_id, boundary_id, time_span; + SELECT 'Wealthy, urban without Kids'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getuscensusmeasure (username text, orgname text, geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getuscensusmeasure invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, name, normalize, boundary_id, time_span; + SELECT 6789.5647735060920500::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getuscensuscategory (username text, orgname text, geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getuscensuscategory invoked with params (%, %, %, %, %, %)', username, orgname, geom, name, boundary_id, time_span; + SELECT 'Wealthy, urban without Kids'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpopulation (username text, orgname text, geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpopulation invoked with params (%, %, %, %, %, %)', username, orgname, geom, normalize, boundary_id, time_span; + SELECT 10923.093200390833950::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_search (username text, orgname text, search_term text, relevant_boundary text DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_search invoked with params (%, %, %, %)', username, orgname, search_term, relevant_boundary; + RETURN QUERY SELECT 'es.ine.total_pop'::text as id, 'The total number of all people living in a geographic area.'::text as description, 'Total Population'::text as name, 'sum'::text as aggregate, NULL::text as source; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getavailableboundaries (username text, orgname text, geom geometry(Geometry, 4326), timespan text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getavailableboundaries invoked with params (%, %, %, %)', username, orgname, geom, timespan; + RETURN QUERY SELECT 'us.census.tiger.place'::text as boundary_id, 'Incorporated places are those reported to the Census Bureau as legally in existence as of January 1, 2010, as reported in the latest Boundary and Annexation Survey (BAS), under the laws of their respective states.'::text as description, '2014'::text as timespan, 'obs_7c9493c41fa8f4bd178ab993ea3d5891c1977667'::text as tablename; +END; +$$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundariesbygeometry (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundariesbygeometry invoked with params (%, %, %, %, %, %)', username, orgname, geom, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0106000020E61000000100000001030000000100000019000000DD96C805677C52C0CBD8D0CDFE5A44407A19C5724B7C52C033BF9A03045B4440FF59F3E32F7C52C0CB290131095B4440247EC51A2E7C52C0548B8862F25A44401FF5D72B2C7C52C0CB811E6ADB5A444049F086342A7C52C09CC3B5DAC35A444044679945287C52C01F680586AC5A444012D90759167C52C09430D3F6AF5A44405698BED7107C52C04759BF99985A4440DEE522BE137C52C00664AF777F5A4440F92EA52E197C52C09BA73AE4665A4440C558A65F227C52C0D80DDB16655A4440373465A71F7C52C065A71FD4455A44404AED45B41D7C52C0785DBF60375A444083A3E4D5397C52C09946938B315A4440F2B4FCC0557C52C01FF5D72B2C5A444026C286A7577C52C02BDD5D67435A44405BCF108E597C52C0C651B9895A5A444030D461855B7C52C0D1393FC5715A444065E1EB6B5D7C52C078280AF4895A44403AE63C635F7C52C07D1F0E12A25A44403F6F2A52617C52C05983F755B95A44405C3AE63C637C52C04852D2C3D05A444049810530657C52C0FAEE5696E85A4440DD96C805677C52C0CBD8D0CDFE5A4440'::geometry as the_geom, '36047049300'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; -- Exercise the public and the proxied function -SELECT obs_get_demographic_snapshot('POINT(-87.81406 41.89308)'::geometry); -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, , 0101000000D53E1D8F19F455C0185B087250F24440, 2009 - 2013, "us.census.tiger".block_group) +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, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 2009 - 2013, "us.census.tiger".block_group) CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_get_demographic_snapshot(username, orgname, geom, time_span, geometry_level)" PL/pgSQL function obs_get_demographic_snapshot(geometry,text,text) line 16 at SQL statement obs_get_demographic_snapshot @@ -31,8 +173,8 @@ PL/pgSQL function obs_get_demographic_snapshot(geometry,text,text) line 16 at SQ {"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null} (1 row) -SELECT obs_get_segment_snapshot('POINT(-87.81406 41.89308)'::geometry); -NOTICE: cdb_dataservices_client._obs_get_segment_snapshot(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_get_segment_snapshot invoked with params (test_user, , 0101000000D53E1D8F19F455C0185B087250F24440, "us.census.tiger".census_tract) +SELECT obs_get_segment_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); +NOTICE: cdb_dataservices_client._obs_get_segment_snapshot(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_get_segment_snapshot invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, "us.census.tiger".block_group) CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_get_segment_snapshot(username, orgname, geom, geometry_level)" PL/pgSQL function obs_get_segment_snapshot(geometry,text) line 16 at SQL statement obs_get_segment_snapshot @@ -40,3 +182,139 @@ PL/pgSQL function obs_get_segment_snapshot(geometry,text) line 16 at SQL stateme {"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null} (1 row) +SELECT obs_getdemographicsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013', '"us.census.tiger".block_group'::text); +NOTICE: cdb_dataservices_client._obs_getdemographicsnapshot(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getdemographicsnapshot invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 2009 - 2013, "us.census.tiger".block_group) +CONTEXT: PL/pgSQL function obs_getdemographicsnapshot(geometry,text,text) line 16 at RETURN QUERY + obs_getdemographicsnapshot +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null} +(1 row) + +SELECT obs_getsegmentsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); +NOTICE: cdb_dataservices_client._obs_getsegmentsnapshot(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getsegmentsnapshot invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, "us.census.tiger".block_group) +CONTEXT: PL/pgSQL function obs_getsegmentsnapshot(geometry,text) line 16 at RETURN QUERY + obs_getsegmentsnapshot +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null} +(1 row) + +SELECT obs_getboundary(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getboundary(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getboundary invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, us.census.tiger.census_tract, ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getboundary(username, orgname, geom, boundary_id, time_span)" +PL/pgSQL function obs_getboundary(geometry,text,text) line 16 at SQL statement + obs_getboundary +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 0106000020E6100000010000000103000000010000003500000056EF703B347C52C054FF2092215B44401B9AB2D30F7C52C03FE1ECD6325B4440B14B546F0D7C52C0BBCE86FC335B4440730F09DFFB7B52C0B796C9703C5B4440108FC4CBD37B52C0B96C74CE4F5B444001C0B167CF7B52C0ED0BE8853B5B4440C843DFDDCA7B52C05DDDB1D8265B4440A73D25E7C47B52C0D53BDC0E0D5B4440BB5E9A22C07B52C0F8A3A833F75A4440355F251FBB7B52C0B64604E3E05A444008910C39B67B52C098BF42E6CA5A44405227A089B07B52C0F204C24EB15A444024F1F274AE7B52C069E4F38AA75A44402B4A09C1AA7B52C06B63EC84975A4440E199D024B17B52C0546F0D6C955A44403C873254C57B52C02EAC1BEF8E5A44402593533BC37B52C0588AE42B815A4440973AC8EBC17B52C087890629785A44407A6F0C01C07B52C0E1EB6B5D6A5A44401B9B1DA9BE7B52C03F6F2A52615A444088855AD3BC7B52C088669E5C535A4440E1EA0088BB7B52C0E6E95C514A5A44400CE6AF90B97B52C070D05E7D3C5A44401E85EB51B87B52C0B03A72A4335A4440BAF3C473B67B52C09929ADBF255A4440CD920035B57B52C0454AB3791C5A4440F78DAF3DB37B52C0E09BA6CF0E5A4440DBC2F352B17B52C0703FE081015A444015C440D7BE7B52C05E83BEF4F659444041446ADAC57B52C0EFDFBC38F15944405FB1868BDC7B52C0C03E3A75E559444034BC5983F77B52C0205ED72FD8594440EFFCA204FD7B52C07E384888F25944403ACAC16C027C52C00876FC17085A444056478E74067C52C00FECF82F105A44400FECF82F107C52C0876D8B321B5A4440BB438A01127C52C0DE1CAED51E5A4440B9C15087157C52C034643C4A255A444099F221A81A7C52C0D0EFFB372F5A44404AED45B41D7C52C0785DBF60375A4440373465A71F7C52C065A71FD4455A4440C558A65F227C52C0D80DDB16655A4440F92EA52E197C52C09BA73AE4665A4440DEE522BE137C52C00664AF777F5A44405698BED7107C52C04759BF99985A444012D90759167C52C09430D3F6AF5A444044679945287C52C01F680586AC5A444049F086342A7C52C09CC3B5DAC35A44401FF5D72B2C7C52C0CB811E6ADB5A4440247EC51A2E7C52C0548B8862F25A4440FF59F3E32F7C52C0CB290131095B4440F96871C6307C52C09605137F145B444056EF703B347C52C054FF2092215B4440 +(1 row) + +SELECT obs_getboundaryid(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getboundaryid(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getboundaryid invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, us.census.tiger.census_tract, ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getboundaryid(username, orgname, geom, boundary_id, time_span)" +PL/pgSQL function obs_getboundaryid(geometry,text,text) line 16 at SQL statement + obs_getboundaryid +------------------- + 36047048500 +(1 row) + +SELECT obs_getboundarybyid('36047'::text, 'us.census.tiger.county'::text); +NOTICE: cdb_dataservices_client._obs_getboundarybyid(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getboundarybyid invoked with params (test_user, , 36047, us.census.tiger.county, ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getboundarybyid(username, orgname, geometry_id, boundary_id, time_span)" +PL/pgSQL function obs_getboundarybyid(text,text,text) line 16 at SQL statement + obs_getboundarybyid +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 0106000020E610000001000000010300000001000000930200005051F52B9D8352C042B28009DC50444093C2BCC7998352C0E89E758D965144402EFD4B52998352C09A07B0C8AF514440E75086AA988352C022FAB5F5D351444027874F3A918352C0A46B26DF6C53444018E945ED7E8352C04D81CCCEA25344401346B3B27D8352C05D50DF32A753444068226C787A8352C08D25AC8DB153444015C8EC2C7A8352C004560E2DB2534440DF8618AF798352C00FD07D39B3534440FEB627486C8352C0DC9E20B1DD534440B98C9B1A688352C05D328E91EC5344408B8A389D648352C0929048DBF853444075CAA31B618352C0986A662D05544440EA758BC0588352C0D6C397892254444048DFA469508352C0151DC9E53F544440B67F65A5498352C0F73DEAAF575444401403249A408352C05E2A36E6755444402367614F3B8352C06DE2E47E8754444011FC6F253B8352C0431B800D885444403E7958A8358352C0DD0A6135965444401D739EB12F8352C093DFA293A5544440FB04508C2C8352C035289A07B05444401EA4A7C8218352C0347F4C6BD3544440D7C05609168352C05053CBD6FA544440AC8E1CE90C8352C0C9AA083719554440FC8D76DCF08252C0BD18CA897655444048895DDBDB8252C0C3B7B06EBC554440698995D1C88252C032207BBDFB55444004A73E90BC8252C0DB4C857824564440BC1FB75F3E8252C08F368E588B574440E15D2EE23B8252C066F4A3E194574440C614AC71368252C0381268B0A9574440CEA44DD53D8152C04F1F813FFC564440A51133FB3C8152C0F607CA6DFB56444070D05E7D3C8152C0CB0C1B65FD564440C5C6BC8E388152C0F303577902574440EA043411368152C03F390A1005574440840B7904378152C0D34ECDE506574440390A1005338152C047E350BF0B5744405D143DF0318152C0D53BDC0E0D5744401D59F965308152C00A4966F50E574440236420CF2E8152C00FD253E41057444084EE92382B8152C0AD2D3C2F15574440E23D0796238152C0A304FD851E574440B3EDB435228152C001D9EBDD1F5744401EBE4C14218152C08BDCD3D51D574440A2D0B2EE1F8152C0FC1BB4571F57444007B0C8AF1F8152C0CC9717601F574440F678211D1E8152C0374E0AF31E5744401A69A9BC1D8152C0793D98141F574440102384471B8152C0CB2F833122574440B7EEE6A90E8152C09F1D705D315744405968E7340B8152C02C0E677E355744400E4A9869FB8052C0C91EA166485744401B2C9CA4F98052C05C001AA54B5744401AF8510DFB8052C0C51A2E724F574440925CFE43FA8052C0309DD66D50574440BB9866BAD78052C0035DFB027A574440A04FE449D28052C02920ED7F80574440DC9BDF30D18052C0E8305F5E80574440B43C0FEECE8052C0D8614CFA7B5744404AEEB089CC8052C0950A2AAA7E5744409A5B21ACC68052C032FE7DC6855744406682E15CC38052C01EF7ADD689574440F78DAF3DB38052C020CD58349D5744402FFA0AD28C8052C00919C8B3CB574440D0251C7A8B8052C00EA2B5A2CD57444001DE02098A8052C030444E5FCF5744404A404CC2858052C0992A1895D45744403480B740828052C0A33CF372D857444028ECA2E8818052C0CD0358E4D7574440F3AACE6A818052C074ECA012D75744402920ED7F808052C0DFA293A5D657444036E84B6F7F8052C092054CE0D6574440AD4CF8A57E8052C0E55FCB2BD757444042CA4FAA7D8052C01AA19FA9D7574440A2EC2DE57C8052C0205ED72FD8574440BB6246787B8052C08BE07F2BD95744405C74B2D47A8052C025E7C41EDA5744405CA8FC6B798052C0F52EDE8FDB574440FF0758AB768052C09AAF928FDD574440A60A4625758052C0C442AD69DE574440A73E90BC738052C05E49F25CDF574440BF9A0304738052C046ED7E15E0574440A19BFD81728052C070B4E386DF5744403D0AD7A3708052C0D0F0660DDE574440680586AC6E8052C04D469561DC57444063963D096C8052C0965AEF37DA574440944E24986A8052C0BA641C23D957444059501894698052C014B01D8CD8574440E21FB6F4688052C0614D6551D85744401895D409688052C0205ED72FD85744406379573D608052C0A4A487A1D55744401878EE3D5C8052C041B5C189E85744402F4FE78A528052C0A580B4FF01584440983270404B8052C0EECEDA6D1758444050357A35408052C0E3C281902C58444086C43D963E8052C0DC9DB5DB2E584440C5E061DA378052C0BFF2203D455844409946938B318052C0C4E9245B5D5844407C478D09318052C040A374E95F584440E3A8DC442D8052C0F92AF9D85D584440919C4CDC2A8052C06BD26D895C584440276893C3278052C0E9279CDD5A58444053B131AF238052C061C092AB5858444055336B29208052C068E55E605658444091990B5C1E8052C082C64CA25E584440AA2688BA0F8052C027F6D03E56584440F488D1730B8052C0D21C59F9655844400C1CD0D2158052C0BB96900F7A584440C6A69542208052C0B77BB94F8E584440D3A23EC91D8052C02EC901BB9A584440B6BDDD921C8052C0BF42E6CAA058444082E49D43198052C036902E36AD58444072FBE593158052C0ACA92C0ABB5844402B4F20EC148052C0EC3026FDBD584440E4BCFF8F138052C04E266E15C4584440C26856B60F8052C06E15C440D7584440C404357C0B8052C00F5EBBB4E1584440397CD289048052C0CA87A06AF4584440FB761211FE7F52C090F7AA9509594440D93C0E83F97F52C03561FBC9185944402828452BF77F52C0F06DFAB31F594440F9BD4D7FF67F52C0DC9A745B225944403AADDBA0F67F52C0BE4D7FF62359444093C49272F77F52C0526342CC25594440450DA661F87F52C0798EC87729594440F2CCCB61F77F52C0067FBF982D5944409B030473F47F52C017821C94305944401E300F99F27F52C05609168733594440E57FF277EF7F52C0EDBAB72231594440A3AA09A2EE7F52C0EA1ED95C355944405D18E945ED7F52C0D3F6AFAC345944401C5DA5BBEB7F52C076DB85E63A5944404BADF71BED7F52C0B1D991EA3B5944401F477364E57F52C0E48409A35959444022179CC1DF7F52C001D8800871594440A4703D0AD77F52C02EC6C03A8E594440457F68E6C97F52C061C26856B659444070404B57B07F52C0FCDEA63FFB594440DC10E335AF7F52C048E00F3FFF59444055F7C8E6AA7F52C02DB4739A055A4440A4E2FF8EA87F52C00CFFE9060A5A44407E8AE3C0AB7F52C0EC4960730E5A444006F2ECF2AD7F52C08CD99255115A444042588D25AC7F52C09BA8A5B9155A44405A9A5B21AC7F52C0F4BF5C8B165A44406762BA10AB7F52C0A5BA8097195A4440E5B7E864A97F52C0B6BDDD921C5A44402B4A09C1AA7F52C0499F56D11F5A4440D48041D2A77F52C0177FDB13245A4440C22FF5F3A67F52C0D55B035B255A4440FE7BF0DAA57F52C0F8FD9B17275A44409A046F48A37F52C04FADBEBA2A5A444045F12A6B9B7F52C0AC1919E42E5A44404BE2AC889A7F52C0A75CE15D2E5A4440462575029A7F52C0965984622B5A4440E75086AA987F52C0906802452C5A44400B2769FE987F52C05FB01BB62D5A444004029D499B7F52C0DD2230D6375A44404301DBC1887F52C0CBF10A444F5A4440D6A88768747F52C0B81E85EB515A44407C0C569C6A7F52C0F6CFD380415A4440CB113290677F52C0A9328CBB415A44407905A227657F52C03D7C9928425A44407EA5F3E1597F52C0787AA52C435A444009F7CABC557F52C0A2410A9E425A44408D23D6E2537F52C00EF8FC30425A444029780AB9527F52C08B19E1ED415A44402992AF04527F52C08B19E1ED415A4440C51A2E724F7F52C08B19E1ED415A4440AC36FFAF3A7F52C01AA6B6D4415A444009522976347F52C0A2410A9E425A4440F25D4A5D327F52C0252026E1425A44408252B4722F7F52C05A61FA5E435A444032E202D0287F52C013B534B7425A4440E0BBCD1B277F52C014E97E4E415A44409352D0ED257F52C0151DC9E53F5A444022F94A20257F52C0B08BA2073E5A4440CF9ECBD4247F52C0F3AE7AC03C5A444077A1B94E237F52C0F3AE7AC03C5A4440DDB419A7217F52C097FBE428405A4440666A12BC217F52C016A243E0485A44408EACFC32187F52C0CD8DE9094B5A44404F05DCF3FC7E52C0B952CF82505A4440D2E0B6B6F07E52C0FFCA4A93525A44404F029B73F07E52C0A7E7DD58505A4440EA3C2AFEEF7E52C020B41EBE4C5A44404A5F0839EF7E52C01AF7E6374C5A4440D462F030ED7E52C055F5F23B4D5A4440825660C8EA7E52C0B5FD2B2B4D5A4440825660C8EA7E52C072DA53724E5A44403C2CD49AE67E52C030B77BB94F5A44400DDC813AE57E52C0D76B7A50505A4440670DDE57E57E52C0072461DF4E5A4440C77DAB75E27E52C0A25EF0694E5A4440ABB2EF8AE07E52C04F04711E4E5A44403A3FC571E07E52C03C65355D4F5A4440643A747ADE7E52C04ED026874F5A444077F35487DC7E52C08A027D224F5A4440F0A5F0A0D97E52C031EBC5504E5A444068588CBAD67E52C0D8D30E7F4D5A444046B3B27DC87E52C06FB9FAB1495A4440B85A272EC77E52C03C821B295B5A444039CE6DC2BD7E52C097016729595A44409A07B0C8AF7E52C07FD93D79585A44407E8AE3C0AB7E52C0EBC37AA3565A4440C1E10511A97E52C0D097DEFE5C5A44401B82E3326E7E52C03F170D198F5A44408A3C49BA667E52C0D619DF17975A444026DF6C73637E52C07A32FFE89B5A4440E78BBD175F7E52C000FE2955A25A4440594DD7135D7E52C040852348A55A4440E36A64575A7E52C03EE94482A95A4440E603029D497E52C067B62BF4C15A4440ED42739D467E52C04701A260C65A4440253ACB2C427E52C03E40F7E5CC5A4440D026874F3A7E52C061C5A9D6C25A44405C5837DE1D7E52C0868F8829915A4440162EABB0197E52C007B5DFDA895A4440B859BC58187E52C083A279008B5A44408FE046CA167E52C011FB04508C5A4440B131AF230E7E52C0D2C43BC0935A44401A4CC3F0117E52C0F0FACC599F5A44401A321EA5127E52C06631B1F9B85A44402B836A83137E52C0E55C8AABCA5A4440C9737D1F0E7E52C0B376DB85E65A4440D3687231067E52C07405DB88275B444009DE9046057E52C09A94826E2F5B4440158C4AEA047E52C08D7E349C325B4440C808A870047E52C0B6114F76335B4440634337FB037E52C00F290648345B4440DAA7E331037E52C03E7958A8355B444082902C60027E52C0DE3CD521375B4440AB5791D1017E52C048BF7D1D385B4440942F6821017E52C095287B4B395B4440268C6665FB7D52C0548A1D8D435B44405C1B2AC6F97D52C065187783685B4440FA0B3D62F47D52C03FE08101845B4440E2E313B2F37D52C03196E997885B444038F4160FEF7D52C05D50DF32A75B4440109546CCEC7D52C07FDB1324B65B44401C261AA4E07D52C0BA641C23D95B444076BF0AF0DD7D52C06AF7AB00DF5B4440DCB8C5FCDC7D52C0B06F2711E15B44405A0EF450DB7D52C0081F4AB4E45B444084D558C2DA7D52C0F57F0EF3E55B4440BBB20B06D77D52C06E693524EE5B4440CE6BEC12D57D52C0FB592C45F25B444073672618CE7D52C09A0645F3005C4440BB7B80EECB7D52C0C7BAB88D065C4440F5F411F8C37D52C057E9EE3A1B5C44407B8670CCB27D52C09AB4A9BA475C4440240B98C0AD7D52C0282A1BD6545C4440E4839ECDAA7D52C0FA5E43705C5C4440E4805D4D9E7D52C08AAA5FE97C5C44401B2AC6F99B7D52C01C2444F9825C4440D3122BA3917D52C059F8FA5A975C4440A7ACA6EB897D52C0FD2D01F8A75C444007B5DFDA897D52C04818062CB95C44401EF7ADD6897D52C0399A232BBF5C444036397CD2897D52C0904946CEC25C444001DE02098A7D52C08A58C4B0C35C4440CB68E4F38A7D52C0527B116DC75C4440AD4F39268B7D52C0AB92C83EC85C4440531EDD088B7D52C0EB19C231CB5C4440C5C551B9897D52C070EB6E9EEA5C444090847D3B897D52C02E5393E00D5D44409C4CDC2A887D52C01D39D219185D4440FC6EBA65877D52C00D87A5811F5D4440D9CC21A9857D52C0641F6459305D44402D7590D7837D52C0DB4FC6F8305D44409354A698837D52C03FE1ECD6325D44402D5BEB8B847D52C05CC64D0D345D44403A3DEFC6827D52C02C0E677E355D44405299620E827D52C0938C9C853D5D444011AAD4EC817D52C0CE8AA8893E5D44407689EAAD817D52C045BB0A293F5D444094A2957B817D52C02C5F97E13F5D4440EDED96E4807D52C060048D99445D44407C7A6CCB807D52C00551F701485D4440BE69FAEC807D52C0999A046F485D44401781B1BE817D52C0ECF483BA485D444028ECA2E8817D52C0F6D214014E5D44403480B740827D52C07024D060535D4440BD35B055827D52C0CEF8BEB8545D44401C3EE944827D52C03F389F3A565D4440FF243E77827D52C0B534B742585D44407B2C7DE8827D52C02AFD84B35B5D44406F7EC344837D52C0535C55F65D5D4440DA006C40847D52C041F163CC5D5D4440459DB987847D52C0CE15A584605D4440FDBCA948857D52C0F4A44C6A685D44408658FD11867D52C097A608707A5D44404FAF9465887D52C03EC91D36915D4440BD38F1D58E7D52C0CFF753E3A55D44406876DD5B917D52C0F1B6D26BB35D44405B7A34D5937D52C0E4F1B4FCC05D4440B6476FB88F7D52C0C0E78711C25D4440743E3C4B907D52C0A5BBEB6CC85D4440D190F128957D52C03A394371C75D4440ADA06989957D52C0512D228AC95D4440D74D29AF957D52C01BB80375CA5D4440307F85CC957D52C0E542E55FCB5D444042EA76F6957D52C049D40B3ECD5D444054556820967D52C0B3226AA2CF5D44408F6D1970967D52C0C189E8D7D65D4440AD6C1FF2967D52C0F71BEDB8E15D4440BED7101C977D52C0C8B4368DED5D4440D47D00529B7D52C0EBE1CB44115E44403F00A94D9C7D52C068774831405E4440F7393E5A9C7D52C04339D1AE425E44409831056B9C7D52C090A2CEDC435E4440984BAAB69B7D52C02384471B475E4440A547533D997D52C04ED026874F5E44403F170D198F7D52C00E661360585E4440545227A0897D52C0E202D0285D5E4440D3139678407D52C026A435069D5E44406C753925207D52C0CA54C1A8A45E44403B1BF2CF0C7D52C0E17CEA58A55E4440FD12F1D6F97C52C078962023A05E444068C9E369F97C52C0A81ABD1AA05E44406FBA6587F87C52C037A79201A05E44407008556AF67C52C0CC24EA059F5E44404CE141B3EB7C52C0F3FE3F4E985E444003CE52B29C7C52C06C239EEC665E44409AB33EE5987C52C020EEEA55645E4440DFC0E446917C52C0CF6394675E5E444014200A664C7C52C07F315BB22A5E44401D8D43FD2E7C52C0D71533C2DB5D4440C4758C2B2E7C52C09C4B7155D95D4440EE08A7052F7C52C0444B1E4FCB5D444091B6F1272A7C52C0A7069ACFB95D444014C95702297C52C0CC785BE9B55D4440807F4A95287C52C0567C43E1B35D44407405DB88277C52C0A0C4E74EB05D44400057B263237C52C07E39B35DA15D4440AC8BDB68007C52C0AB90F2936A5D444025E4839ECD7B52C0395E81E8495D444018265305A37B52C0C2DCEEE53E5D44402781CD39787B52C0685721E5275D4440514832AB777B52C0639AE95E275D4440F2599E07777B52C0EC6987BF265D4440F94A2025767B52C0B16B7BBB255D44409485AFAF757B52C088D860E1245D4440893F8A3A737B52C09622F94A205D44408D0C7217617B52C0BF5E61C1FD5C444026C286A7577B52C0D3DA34B6D75C4440FCDD3B6A4C7B52C0D0967329AE5C444030630AD6387B52C082C64CA25E5C444081E7DEC3257B52C0A33B889D295C4440639AE95E277B52C0D47FD6FCF85B44407EC34483147B52C03A394371C75B4440342A70B20D7B52C0D826158DB55B444099EFE0270E7B52C06762BA10AB5B4440D3F36E2C287B52C0350873BB975B4440D427B9C3267B52C07842AF3F895B4440C4245CC8237B52C030D7A205685B4440880CAB78237B52C08B8A389D645B4440902E36AD147B52C0718C648F505B4440AF928FDD057B52C05169C4CC3E5B44407E8978EBFC7A52C0FC1BB4571F5B44409DF0129CFA7A52C05D86FF74035B4440DCD8EC48F57A52C044A51133FB5A444027BD6F7CED7A52C0D769A4A5F25A44406B9C4D47007B52C0E4F4F57CCD5A4440F29881CAF87A52C095D233BDC45A44403F19E3C3EC7A52C05BEB8B84B65A44403468E89FE07A52C0DF14562AA85A4440E0F08288D47A52C0224F92AE995A44403448C153C87A52C0B8E34D7E8B5A44401155F833BC7A52C06C91B41B7D5A44401DE6CB0BB07A52C050C3B7B06E5A444029779FE3A37A52C0A568E55E605A44400584D6C3977A52C0889AE8F3515A44401215AA9B8B7A52C0DD3F16A2435A4440EE21E17B7F7A52C0C1711937355A4440B3EC4960737A52C0E692AAED265A4440D7BFEB33677A52C0CAC4AD82185A4440E350BF0B5B7A52C04EEE77280A5A4440CE18E6046D7A52C001FA7DFFE6594440DAA9B9DC607A52C0B5A7E49CD8594440B7B6F0BC547A52C0DAC87553CA594440DB899290487A52C0ED7E15E0BB594440CB0EF10F5B7A52C0239D819197594440A25EF0694E7A52C0B340BB438A594440BBEB6CC83F7A52C092E9D0E9795944407F68E6C9357A52C033C4B12E6E594440205D6C5A297A52C05DA27A6B605944401B834E081D7A52C065AA605452594440765089EB187A52C0A27895B54D5944402A357BA0157A52C07B4D0F0A4A5944408A5759DB147A52C0F2B1BB404959444097530262127A52C0D0436D1B465944409E5E29CB107A52C0ADA1D45E445944400A630B410E7A52C07F85CC9541594440DB12B9E00C7A52C00F46EC134059444000378B170B7A52C039419B1C3E5944408A20CEC3097A52C06AF981AB3C59444080423D7D047A52C0670C738236594440CAA48636007A52C034677DCA31594440BF44BC75FE7952C0A051BAF42F594440605628D2FD7952C077BE9F1A2F59444093AAED26F87952C0DF87838428594440CFF6E80DF77952C033164D672759444011346612F57952C07C2AA73D2559444001310917F27952C0E8482EFF21594440730CC85EEF7952C05567B5C01E594440984A3FE1EC7952C0B6D782DE1B5944404CE141B3EB7952C0570394861A594440C91CCBBBEA7952C00B9A9658195944408E1EBFB7E97952C08EACFC3218594440A794D74AE87952C08FE046CA165944409677D503E67952C0B41EBE4C145944402EC55565DF7952C0E2E995B20C5944408F52094FE87952C09DF0129CFA58444052EC681CEA7952C06326512FF8584440E02D90A0F87952C0739EB12FD9584440519E7939EC7952C05C8DEC4ACB584440938AC6DADF7952C0A5846055BD5844401666A19DD37952C07C08AA46AF58444029CE5147C77952C0B3942C27A1584440B2666490BB7952C0AEEE586C935844404E232D95B77952C0EDF0D7648D584440A4198BA6B37952C0FC6EBA65875844401E34BBEEAD7952C0179B560A81584440A297512CB77952C0289831056B5844400DE02D90A07952C0B3D0CE6916584440789961A3AC7952C0A6D1E4620C58444076FEEDB25F7952C015713AC956574440D50627A25F7952C06072A3C85A574440E7A562635E7952C0E08096AE6057444012876C205D7952C05AD2510E6657444072C3EFA65B7952C0C4EC65DB69574440FCC6D79E597952C0374D9F1D7057444051D7DAFB547952C0554FE61F7D574440658D7A88467952C04F1DAB949E57444008556AF6407952C04A7D59DAA95744406F9C14E63D7952C0A5811FD5B0574440A679C7293A7952C09CC0745AB757444061FBC9181F7952C097A608707A574440B0C91AF5107952C03483F8C08E5744402E36AD14027952C0718BF9B9A1574440D4997B48F87852C089D00836AE574440BBD23252EF7852C090BB085394574440EF8E8CD5E67852C01840F850A2574440EACE13CFD97852C0B6847CD0B35744408C48145AD67852C09012BBB6B7574440E690D442C97852C084B53176C257444063F030ED9B7852C090BA9D7DE5574440DFC0E446917852C0DEE2E13D075844403FFD67CD8F7852C0719010E50B5844401C2785798F7852C0764D486B0C584440B1BE81C98D7852C093FE5E0A0F58444037363B527D7852C0093543AA28584440C3D50110777852C09355116E32584440EEE714E4677852C03387A4164A584440717500C45D7852C07EA5F3E1595844407442E8A04B7852C0E108522976584440211CB3EC497852C0CE35CCD0785844405791D101497852C09D7DE5417A584440CB660E492D7852C0056A3178985844401AC1C6F5EF7752C0B9162D40DB5844400F7C0C569C7752C03EE8D9ACFA584440AC1E300F997752C0828AAA5FE9584440A661F888987752C0C2A38D23D6584440DCBC7152987752C042959A3DD0584440A661F888987752C0302AA913D0584440E7FF55478E7752C05DC2A1B7785844402FFA0AD28C7752C0581CCEFC6A584440DCB930D28B7752C021567F8461584440FB20CB82897752C062D7F6764B58444079909E22877752C0D89942E7355844408C63247B847752C0B58993FB1D584440ACE46377817752C0677E350708584440C6C210397D7752C0B2F4A10BEA57444074B680D07A7752C0909DB7B1D9574440DB317557767752C0077767EDB65744409A7631CD747752C02D7B12D89C5744400D6C9560717752C054FEB5BC72574440FC34EECD6F7752C0A3E6ABE4635744409E7AA4C16D7752C0D1949D7E50574440FE9C82FC6C7752C0E046CA16495744401E4FCB0F5C7752C09B53C90050574440D503E621537752C0E063B0E25457444037DC476E4D7752C032569BFF5757444070ED4449487752C0836C59BE2E57444066F50EB7437752C054C554FA0957444032022A1C417752C0713C9F01F55644404487C091407752C01F7EFE7BF05644406E4E2503407752C05D4C33DDEB56444088F546AD307752C03ECBF3E0EE5644401F0F7D772B7752C04835ECF7C4564440A33B889D297752C026AAB706B656444087A4164A267752C0938E72309B5644403B6F63B3237752C050FD834886564440D7F7E120217752C00D6C956071564440132A38BC207752C07A8A1C226E564440315D88D51F7752C07E8E8F1667564440D4F02DAC1B7752C0ADA415DF505644409E95B4E21B7752C09AE8F35146564440B88D06F0167752C0BB46CB811E564440A435069D107752C0C8E88024EC554440C9703C9F017752C0F01307D0EF55444083DE1B43007752C0855D143DF05544404EB4AB90F27652C0A69718CBF45544401ABE8575E37652C0C214E5D2F855444041649126DE7652C0FACE2F4AD0554440293C6876DD7652C0807D74EACA554440FAD170CADC7652C0779FE3A3C55544403FABCC94D67652C0F58079C8945544405AD76839D07652C0B41D537765554440849ECDAACF7652C0272D5C56615544405DA79196CA7652C0D87F9D9B36554440331477BCC97652C06A10E6762F55444060AB048BC37652C062F20698F95444402D23F59ECA7652C05D6919A9F754444011C30E63D27652C0B8E864A9F554444021C9ACDEE17652C073D87DC7F0544440F0F96184F07652C06FB72407EC5444408577B988EF7652C0DFA5D425E3544440A089B0E1E97652C0C8091346B35444403621AD31E87652C0999CDA19A6544440C763062AE37652C0EF3B86C77E5444401F4AB4E4F17652C0E0D4079277544440E2E65432007752C054E4107173544440FF0241800C7752C061FA5E437054444057B26323107752C0F677B6476F5444402026E1421E7752C00FEB8D5A61544440834F73F2227752C0E3361AC05B544440C2F693313E7752C0C05AB56B4254444097900F7A367752C0780C8FFD2C544440F834272F327752C06684B70721544440C4758C2B2E7752C03D0801F9125444408D959867257752C00E4A9869FB534440E68F696D1A7752C02FF99FFCDD53444022C2BF081A7752C0247F30F0DC534440EF1CCA50157752C03599F1B6D2534440C0B2D2A4147752C06551D845D15344409048DBF8137752C09509BFD4CF53444014419C87137752C0FB027AE1CE534440E5F04927127752C01A84B9DDCB53444092B06F27117752C0DAC87553CA5344407EA65EB7087752C0228C9FC6BD534440A3E4D539067752C065170CAEB9534440C2FA3F87F97652C059F5B9DA8A5344408BFA2477D87652C082A62556465344406403E962D37652C03197546D3753444018B49080D17652C0D5928E72305344404A22FB20CB7652C0765089EB185344402A1900AAB87652C0BE0F070951524440E386DF4DB77652C01F63EE5A425244400F7D772B4B7652C005A568E55E524440FB3F87F9F27552C07D224F92AE5144405793A7ACA67552C0D7C0560916514440BEDA519CA37552C0A44FABE80F514440745B22179C7552C0E2CCAFE600514440DCD6169E977552C00B43E4F4F5504440A93121E6927552C05E807D74EA504440D13FC1C58A7552C056ED9A90D6504440096B63EC847552C0AB92C83EC8504440AE80423D7D7552C04127840EBA50444040F7E5CC767552C0D0967329AE50444089CE328B507552C0162D40DB6A504440C8ED974F567552C05646239F57504440211FF46C567552C03674B33F5050444015713AC9567552C059DC7F643A5044404AB20E47577552C028B682A62550444037AB3E575B7552C0F7AE415F7A4F44408D261763607552C0226C787AA54E444045460724617552C0A94885B1854E4440F62686E4647552C02D978DCEF94D444036AE7FD7677552C018AE0E80B84D4440B9E00CFE7E7552C0B01F6283854D4440446B459BE37552C0C5E23785954C444012A27C410B7652C03C1405FA444C4440588B4F01307652C0B058C345EE4B4440A6457D923B7652C07C28D192C74B44402C9CA4F9637652C0A2957B81594B4440A81ABD1AA07652C0300C5872154B4440FBC8AD49B77652C035272F32014B44404127840EBA7652C02AE109BDFE4A44401DCBBBEA017752C02172FA7ABE4A4440130CE71A667752C0C6A2E9EC644A44400A4B3CA06C7752C0BEF8A23D5E4A4440A5D93C0E837752C06473D53C474A4440FDBCA948857752C06B98A1F1444A4440F0C000C2877752C0F0DE5163424A4440D8817346947752C04450357A354A4440BF28417FA17752C08099EFE0274A44400A2DEBFEB17752C0BCAE5FB01B4A44407FF8F9EFC17752C08C0DDDEC0F4A444053C90050C57752C0B14B546F0D4A44402E71E481C87752C0BF61A2410A4A44401EFB592C457852C09F39EB538E494440056D72F8A47852C06D8E739B7049444036AD1402B97852C0D68BA19C68494440F59F353FFE7852C0BAA0BE654E494440289A07B0C87952C0C58F31772D4944406133C005D97952C0D862B7CF2A494440E1783E03EA7952C04DDA54DD2349444046B3B27DC87A52C06A11514CDE4844402F185C73477B52C0FCE25295B6484440A26131EA5A7B52C06A696E85B04844408499B67F657B52C036902E36AD4844404F8F6D19707B52C0C1C760C5A94844402E1D739EB17B52C02BDCF29194484440F9122A38BC7B52C0B5132521914844401021AE9CBD7B52C080D250A39048444081CEA44DD57B52C0431B800D88484440BBB88D06F07B52C076A38FF980484440B5A50EF27A7C52C07780272D5C484440F7C77BD5CA7C52C08AE5965643484440614D6551D87C52C05CFDD8243F484440E84CDA54DD7C52C03F1878EE3D4844409947FE60E07C52C05774EB353D484440AF0793E2E37C52C0FF5C34643C48444065A54929E87C52C0C45E28603B484440EFAB72A1F27C52C01F12BEF737484440D07D39B35D7D52C0075F984C1548444025AB22DC647D52C03D0801F912484440C39E76F86B7D52C0861C5BCF104844401211FE45D07F52C0F2CEA10C55474440B804E09F528252C0785C548B884644407615527E528252C0DB85E63A8D464440E2E5E95C518252C0BB270F0BB546444089B48D3F518252C0A7203F1BB94644400858AB764D8252C0F294D5743D474440CD565EF23F8252C07D7555A0164944401B28F04E3E8252C0E9F010C64F494440AAB4C5353E8252C0BDC117265349444032CB9E04368252C0F6285C8FC24944405111A7936C8252C09FE238F06A4B44402252D32EA68252C0BC02D193324D44404C50C3B7B08252C0F9F36DC1524D444068075C57CC8252C0ECDCB419A74D4440A31F0DA7CC8252C086E3F90CA84D44409D2E8B89CD8252C0438CD7BCAA4D44402BA1BB24CE8252C00726378AAC4D4440DDE9CE13CF8252C035423F53AF4D4440A774B0FECF8252C0C266800BB24D4440A626C11BD28252C007431D56B84D4440EDD286C3D28252C0DC476E4DBA4D44402638F581E48252C04A5F0839EF4D444074779D0DF98252C0E3C281902C4E4440890629780A8352C016DC0F78604E44408315A75A0B8352C0E5EFDE51634E4440EA793716148352C036E84B6F7F4E44404703780B248352C0C24CDBBFB24E44403046240A2D8352C09BE09BA6CF4E4440A4C00298328352C02D776682E14E444055F833BC598352C09F91088D604F4440B3B27DC85B8352C08922A46E674F444075E789E76C8352C066118AADA04F44400D52F014728352C051F355F2B14F4440C5ABAC6D8A8352C0D4D00660035044403D7E6FD39F8352C05C1ABFF04A5044405051F52B9D8352C042B28009DC504440 +(1 row) + +SELECT obs_getboundariesbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getboundariesbygeometry(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getboundariesbygeometry invoked with params (test_user, , 0103000020E61000000100000005000000C7F8FFD37E7C52C0F860AE1175594440C7F8FFD37E7C52C0BF0E0D64E55A4440A70300E0647B52C0BF0E0D64E55A4440A70300E0647B52C0F860AE1175594440C7F8FFD37E7C52C0F860AE1175594440, us.census.tiger.census_tract, , intersects) +CONTEXT: PL/pgSQL function obs_getboundariesbygeometry(geometry,text,text,text) line 16 at RETURN QUERY + obs_getboundariesbygeometry +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (0106000020E61000000100000001030000000100000019000000DD96C805677C52C0CBD8D0CDFE5A44407A19C5724B7C52C033BF9A03045B4440FF59F3E32F7C52C0CB290131095B4440247EC51A2E7C52C0548B8862F25A44401FF5D72B2C7C52C0CB811E6ADB5A444049F086342A7C52C09CC3B5DAC35A444044679945287C52C01F680586AC5A444012D90759167C52C09430D3F6AF5A44405698BED7107C52C04759BF99985A4440DEE522BE137C52C00664AF777F5A4440F92EA52E197C52C09BA73AE4665A4440C558A65F227C52C0D80DDB16655A4440373465A71F7C52C065A71FD4455A44404AED45B41D7C52C0785DBF60375A444083A3E4D5397C52C09946938B315A4440F2B4FCC0557C52C01FF5D72B2C5A444026C286A7577C52C02BDD5D67435A44405BCF108E597C52C0C651B9895A5A444030D461855B7C52C0D1393FC5715A444065E1EB6B5D7C52C078280AF4895A44403AE63C635F7C52C07D1F0E12A25A44403F6F2A52617C52C05983F755B95A44405C3AE63C637C52C04852D2C3D05A444049810530657C52C0FAEE5696E85A4440DD96C805677C52C0CBD8D0CDFE5A4440,36047049300) +(1 row) + +SELECT obs_getboundariesbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500, 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getboundariesbypointandradius(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getboundariesbypointandradius invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 500, us.census.tiger.census_tract, , intersects) +CONTEXT: PL/pgSQL function obs_getboundariesbypointandradius(geometry,numeric,text,text,text) line 16 at RETURN QUERY + obs_getboundariesbypointandradius +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (0106000020E6100000010000000103000000010000001500000083A3E4D5397C52C09946938B315A44404AED45B41D7C52C0785DBF60375A444099F221A81A7C52C0D0EFFB372F5A4440B9C15087157C52C034643C4A255A4440BB438A01127C52C0DE1CAED51E5A44400FECF82F107C52C0876D8B321B5A4440510FD1E80E7C52C0C4D32B65195A44407FDAA84E077C52C0E0675C38105A444092AD2EA7047C52C08E75711B0D5A4440CF2D7425027C52C0A86DC328085A4440EFFCA204FD7B52C07E384888F259444034BC5983F77B52C0205ED72FD8594440E76F4221027C52C0F3A96395D259444081AD122C0E7C52C00ED6FF39CC594440CB63CDC8207C52C031276893C359444047205ED72F7C52C0287D21E4BC594440BD1C76DF317C52C0F8325184D4594440CD1FD3DA347C52C0B0A9F3A8F8594440C72E51BD357C52C0C3651536035A444043024697377C52C028999CDA195A444083A3E4D5397C52C09946938B315A4440,36047048900) +(1 row) + +SELECT obs_getpointsbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getpointsbygeometry(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getpointsbygeometry invoked with params (test_user, , 0103000020E61000000100000005000000C7F8FFD37E7C52C0F860AE1175594440C7F8FFD37E7C52C0BF0E0D64E55A4440A70300E0647B52C0BF0E0D64E55A4440A70300E0647B52C0F860AE1175594440C7F8FFD37E7C52C0F860AE1175594440, us.census.tiger.census_tract, , intersects) +CONTEXT: PL/pgSQL function obs_getpointsbygeometry(geometry,text,text,text) line 16 at RETURN QUERY + obs_getpointsbygeometry +------------------------------------------------------------------ + (0101000020E610000037CB75821A7C52C0BA8784EFFD594440,36047048900) +(1 row) + +SELECT obs_getpointsbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500::numeric, 'us.census.tiger.census_tract'::text); +NOTICE: cdb_dataservices_client._obs_getpointsbypointandradius(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getpointsbypointandradius invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, 500, us.census.tiger.census_tract, , intersects) +CONTEXT: PL/pgSQL function obs_getpointsbypointandradius(geometry,numeric,text,text,text) line 16 at RETURN QUERY + obs_getpointsbypointandradius +------------------------------------------------------------------ + (0101000020E610000037CB75821A7C52C0BA8784EFFD594440,36047048900) +(1 row) + +SELECT obs_getmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.acs.B01001001'::text); +NOTICE: cdb_dataservices_client._obs_getmeasure(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getmeasure invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, us.census.acs.B01001001, area, , ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getmeasure(username, orgname, geom, measure_id, normalize, boundary_id, time_span)" +PL/pgSQL function obs_getmeasure(geometry,text,text,text,text) line 16 at SQL statement + obs_getmeasure +----------------------- + 10923.093200390833950 +(1 row) + +SELECT obs_getcategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.spielman_singleton_segments.X10'::text); +NOTICE: cdb_dataservices_client._obs_getcategory(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getcategory invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, us.census.spielman_singleton_segments.X10, , ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getcategory(username, orgname, geom, category_id, boundary_id, time_span)" +PL/pgSQL function obs_getcategory(geometry,text,text,text) line 16 at SQL statement + obs_getcategory +----------------------------- + Wealthy, urban without Kids +(1 row) + +SELECT obs_getuscensusmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'male population'::text); +NOTICE: cdb_dataservices_client._obs_getuscensusmeasure(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getuscensusmeasure invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, male population, area, , ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getuscensusmeasure(username, orgname, geom, name, normalize, boundary_id, time_span)" +PL/pgSQL function obs_getuscensusmeasure(geometry,text,text,text,text) line 16 at SQL statement + obs_getuscensusmeasure +------------------------ + 6789.5647735060920500 +(1 row) + +SELECT obs_getuscensuscategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'Spielman-Singleton Segments: 10 Clusters'::text); +NOTICE: cdb_dataservices_client._obs_getuscensuscategory(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getuscensuscategory invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, Spielman-Singleton Segments: 10 Clusters, , ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getuscensuscategory(username, orgname, geom, name, boundary_id, time_span)" +PL/pgSQL function obs_getuscensuscategory(geometry,text,text,text) line 16 at SQL statement + obs_getuscensuscategory +----------------------------- + Wealthy, urban without Kids +(1 row) + +SELECT obs_getpopulation(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); +NOTICE: cdb_dataservices_client._obs_getpopulation(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getpopulation invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, area, , ) +CONTEXT: SQL statement "SELECT cdb_dataservices_client._obs_getpopulation(username, orgname, geom, normalize, boundary_id, time_span)" +PL/pgSQL function obs_getpopulation(geometry,text,text,text) line 16 at SQL statement + obs_getpopulation +----------------------- + 10923.093200390833950 +(1 row) + +SELECT obs_search('total_pop'::text); +NOTICE: cdb_dataservices_client._obs_search(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_search invoked with params (test_user, , total_pop, ) +CONTEXT: PL/pgSQL function obs_search(text,text) line 16 at RETURN QUERY + obs_search +---------------------------------------------------------------------------------------------------------- + (es.ine.total_pop,"The total number of all people living in a geographic area.","Total Population",sum,) +(1 row) + +SELECT obs_getavailableboundaries(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); +NOTICE: cdb_dataservices_client._obs_getavailableboundaries(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getavailableboundaries invoked with params (test_user, , 0101000020E6100000548B8862F27B52C0DDD1FF722D5A4440, ) +CONTEXT: PL/pgSQL function obs_getavailableboundaries(geometry,text) line 16 at RETURN QUERY + obs_getavailableboundaries +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (us.census.tiger.place,"Incorporated places are those reported to the Census Bureau as legally in existence as of January 1, 2010, as reported in the latest Boundary and Annexation Survey (BAS), under the laws of their respective states.",2014,obs_7c9493c41fa8f4bd178ab993ea3d5891c1977667) +(1 row) + diff --git a/client/test/sql/90_data_observatory_test.sql b/client/test/sql/90_data_observatory_test.sql index dd03800..620c24c 100644 --- a/client/test/sql/90_data_observatory_test.sql +++ b/client/test/sql/90_data_observatory_test.sql @@ -25,7 +25,180 @@ BEGIN END; $$ LANGUAGE 'plpgsql'; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdemographicsnapshot (username text, orgname text, geom geometry(Geometry, 4326), time_span text DEFAULT '2009 - 2013', geometry_level text DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ +DECLARE + ret json; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getdemographicsnapshot invoked with params (%, %, %, %, %)', username, orgname, geom, time_span, geometry_level; + SELECT '{"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null}'::json INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getsegmentsnapshot (username text, orgname text, geom geometry(Geometry, 4326), geometry_level text DEFAULT '"us.census.tiger".census_tract') +RETURNS json AS $$ +DECLARE + ret json; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getsegmentsnapshot invoked with params (%, %, %, %)', username, orgname, geom, geometry_level; + SELECT '{"total_pop":9516.27915900609,"male_pop":6152.51885204623,"female_pop":3363.76030695986,"median_age":28.8,"white_pop":5301.51624447348,"black_pop":149.500458087105,"asian_pop":230.000704749392,"hispanic_pop":3835.26175169611,"amerindian_pop":0,"other_race_pop":0,"two_or_more_races_pop":0,"not_hispanic_pop":5681.01740730998,"households":3323.51018362871,"pop_25_years_over":7107.02177675621,"high_school_diploma":1040.753188991,"less_one_year_college":69.0002114248176,"one_year_more_college":793.502431385402,"associates_degree":327.751004267883,"bachelors_degree":2742.7584041365,"masters_degree":931.502854235037,"median_income":66304,"gini_index":0.3494,"income_per_capita":28291,"housing_units":3662.76122313407,"vacant_housing_units":339.251039505353,"vacant_housing_units_for_rent":120.750369993431,"vacant_housing_units_for_sale":0,"median_rent":1764,"percent_income_spent_on_rent":35.3,"owner_occupied_housing_units":339.251039505353,"million_dollar_housing_units":0,"mortgaged_housing_units":224.250687130657,"commuters_16_over":6549.27006773893,"commute_less_10_mins":327.751004267883,"commute_10_14_mins":28.750088093674,"commute_15_19_mins":201.250616655718,"commute_20_24_mins":621.001902823358,"commute_25_29_mins":373.751145217762,"commute_30_34_mins":1851.5056732326,"commute_35_44_mins":1414.50433420876,"commute_45_59_mins":1115.50341803455,"commute_60_more_mins":615.251885204623,"aggregate_travel_time_to_work":null,"income_less_10000":57.500176187348,"income_10000_14999":0,"income_15000_19999":212.750651893187,"income_20000_24999":408.251250930171,"income_25000_29999":0,"income_30000_34999":155.25047570584,"income_35000_39999":109.250334755961,"income_40000_44999":92.0002818997568,"income_45000_49999":63.2501938060828,"income_50000_59999":184.000563799514,"income_60000_74999":621.001902823358,"income_75000_99999":552.001691398541,"income_100000_124999":327.751004267883,"income_125000_149999":333.501021886618,"income_150000_199999":126.500387612166,"income_200000_or_more":null,"land_area":null}'::json INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundary (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry(Geometry, 4326) AS $$ +DECLARE + ret Geometry; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundary invoked with params (%, %, %, %, %)', username, orgname, geom, boundary_id, time_span; + SELECT '0106000020E6100000010000000103000000010000003500000056EF703B347C52C054FF2092215B44401B9AB2D30F7C52C03FE1ECD6325B4440B14B546F0D7C52C0BBCE86FC335B4440730F09DFFB7B52C0B796C9703C5B4440108FC4CBD37B52C0B96C74CE4F5B444001C0B167CF7B52C0ED0BE8853B5B4440C843DFDDCA7B52C05DDDB1D8265B4440A73D25E7C47B52C0D53BDC0E0D5B4440BB5E9A22C07B52C0F8A3A833F75A4440355F251FBB7B52C0B64604E3E05A444008910C39B67B52C098BF42E6CA5A44405227A089B07B52C0F204C24EB15A444024F1F274AE7B52C069E4F38AA75A44402B4A09C1AA7B52C06B63EC84975A4440E199D024B17B52C0546F0D6C955A44403C873254C57B52C02EAC1BEF8E5A44402593533BC37B52C0588AE42B815A4440973AC8EBC17B52C087890629785A44407A6F0C01C07B52C0E1EB6B5D6A5A44401B9B1DA9BE7B52C03F6F2A52615A444088855AD3BC7B52C088669E5C535A4440E1EA0088BB7B52C0E6E95C514A5A44400CE6AF90B97B52C070D05E7D3C5A44401E85EB51B87B52C0B03A72A4335A4440BAF3C473B67B52C09929ADBF255A4440CD920035B57B52C0454AB3791C5A4440F78DAF3DB37B52C0E09BA6CF0E5A4440DBC2F352B17B52C0703FE081015A444015C440D7BE7B52C05E83BEF4F659444041446ADAC57B52C0EFDFBC38F15944405FB1868BDC7B52C0C03E3A75E559444034BC5983F77B52C0205ED72FD8594440EFFCA204FD7B52C07E384888F25944403ACAC16C027C52C00876FC17085A444056478E74067C52C00FECF82F105A44400FECF82F107C52C0876D8B321B5A4440BB438A01127C52C0DE1CAED51E5A4440B9C15087157C52C034643C4A255A444099F221A81A7C52C0D0EFFB372F5A44404AED45B41D7C52C0785DBF60375A4440373465A71F7C52C065A71FD4455A4440C558A65F227C52C0D80DDB16655A4440F92EA52E197C52C09BA73AE4665A4440DEE522BE137C52C00664AF777F5A44405698BED7107C52C04759BF99985A444012D90759167C52C09430D3F6AF5A444044679945287C52C01F680586AC5A444049F086342A7C52C09CC3B5DAC35A44401FF5D72B2C7C52C0CB811E6ADB5A4440247EC51A2E7C52C0548B8862F25A4440FF59F3E32F7C52C0CB290131095B4440F96871C6307C52C09605137F145B444056EF703B347C52C054FF2092215B4440'::geometry INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundaryid (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundaryid invoked with params (%, %, %, %, %)', username, orgname, geom, boundary_id, time_span; + SELECT '36047048500'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundarybyid (username text, orgname text, geometry_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS Geometry(Geometry, 4326) AS $$ +DECLARE + ret Geometry; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundarybyid invoked with params (%, %, %, %, %)', username, orgname, geometry_id, boundary_id, time_span; + SELECT '0106000020E610000001000000010300000001000000930200005051F52B9D8352C042B28009DC50444093C2BCC7998352C0E89E758D965144402EFD4B52998352C09A07B0C8AF514440E75086AA988352C022FAB5F5D351444027874F3A918352C0A46B26DF6C53444018E945ED7E8352C04D81CCCEA25344401346B3B27D8352C05D50DF32A753444068226C787A8352C08D25AC8DB153444015C8EC2C7A8352C004560E2DB2534440DF8618AF798352C00FD07D39B3534440FEB627486C8352C0DC9E20B1DD534440B98C9B1A688352C05D328E91EC5344408B8A389D648352C0929048DBF853444075CAA31B618352C0986A662D05544440EA758BC0588352C0D6C397892254444048DFA469508352C0151DC9E53F544440B67F65A5498352C0F73DEAAF575444401403249A408352C05E2A36E6755444402367614F3B8352C06DE2E47E8754444011FC6F253B8352C0431B800D885444403E7958A8358352C0DD0A6135965444401D739EB12F8352C093DFA293A5544440FB04508C2C8352C035289A07B05444401EA4A7C8218352C0347F4C6BD3544440D7C05609168352C05053CBD6FA544440AC8E1CE90C8352C0C9AA083719554440FC8D76DCF08252C0BD18CA897655444048895DDBDB8252C0C3B7B06EBC554440698995D1C88252C032207BBDFB55444004A73E90BC8252C0DB4C857824564440BC1FB75F3E8252C08F368E588B574440E15D2EE23B8252C066F4A3E194574440C614AC71368252C0381268B0A9574440CEA44DD53D8152C04F1F813FFC564440A51133FB3C8152C0F607CA6DFB56444070D05E7D3C8152C0CB0C1B65FD564440C5C6BC8E388152C0F303577902574440EA043411368152C03F390A1005574440840B7904378152C0D34ECDE506574440390A1005338152C047E350BF0B5744405D143DF0318152C0D53BDC0E0D5744401D59F965308152C00A4966F50E574440236420CF2E8152C00FD253E41057444084EE92382B8152C0AD2D3C2F15574440E23D0796238152C0A304FD851E574440B3EDB435228152C001D9EBDD1F5744401EBE4C14218152C08BDCD3D51D574440A2D0B2EE1F8152C0FC1BB4571F57444007B0C8AF1F8152C0CC9717601F574440F678211D1E8152C0374E0AF31E5744401A69A9BC1D8152C0793D98141F574440102384471B8152C0CB2F833122574440B7EEE6A90E8152C09F1D705D315744405968E7340B8152C02C0E677E355744400E4A9869FB8052C0C91EA166485744401B2C9CA4F98052C05C001AA54B5744401AF8510DFB8052C0C51A2E724F574440925CFE43FA8052C0309DD66D50574440BB9866BAD78052C0035DFB027A574440A04FE449D28052C02920ED7F80574440DC9BDF30D18052C0E8305F5E80574440B43C0FEECE8052C0D8614CFA7B5744404AEEB089CC8052C0950A2AAA7E5744409A5B21ACC68052C032FE7DC6855744406682E15CC38052C01EF7ADD689574440F78DAF3DB38052C020CD58349D5744402FFA0AD28C8052C00919C8B3CB574440D0251C7A8B8052C00EA2B5A2CD57444001DE02098A8052C030444E5FCF5744404A404CC2858052C0992A1895D45744403480B740828052C0A33CF372D857444028ECA2E8818052C0CD0358E4D7574440F3AACE6A818052C074ECA012D75744402920ED7F808052C0DFA293A5D657444036E84B6F7F8052C092054CE0D6574440AD4CF8A57E8052C0E55FCB2BD757444042CA4FAA7D8052C01AA19FA9D7574440A2EC2DE57C8052C0205ED72FD8574440BB6246787B8052C08BE07F2BD95744405C74B2D47A8052C025E7C41EDA5744405CA8FC6B798052C0F52EDE8FDB574440FF0758AB768052C09AAF928FDD574440A60A4625758052C0C442AD69DE574440A73E90BC738052C05E49F25CDF574440BF9A0304738052C046ED7E15E0574440A19BFD81728052C070B4E386DF5744403D0AD7A3708052C0D0F0660DDE574440680586AC6E8052C04D469561DC57444063963D096C8052C0965AEF37DA574440944E24986A8052C0BA641C23D957444059501894698052C014B01D8CD8574440E21FB6F4688052C0614D6551D85744401895D409688052C0205ED72FD85744406379573D608052C0A4A487A1D55744401878EE3D5C8052C041B5C189E85744402F4FE78A528052C0A580B4FF01584440983270404B8052C0EECEDA6D1758444050357A35408052C0E3C281902C58444086C43D963E8052C0DC9DB5DB2E584440C5E061DA378052C0BFF2203D455844409946938B318052C0C4E9245B5D5844407C478D09318052C040A374E95F584440E3A8DC442D8052C0F92AF9D85D584440919C4CDC2A8052C06BD26D895C584440276893C3278052C0E9279CDD5A58444053B131AF238052C061C092AB5858444055336B29208052C068E55E605658444091990B5C1E8052C082C64CA25E584440AA2688BA0F8052C027F6D03E56584440F488D1730B8052C0D21C59F9655844400C1CD0D2158052C0BB96900F7A584440C6A69542208052C0B77BB94F8E584440D3A23EC91D8052C02EC901BB9A584440B6BDDD921C8052C0BF42E6CAA058444082E49D43198052C036902E36AD58444072FBE593158052C0ACA92C0ABB5844402B4F20EC148052C0EC3026FDBD584440E4BCFF8F138052C04E266E15C4584440C26856B60F8052C06E15C440D7584440C404357C0B8052C00F5EBBB4E1584440397CD289048052C0CA87A06AF4584440FB761211FE7F52C090F7AA9509594440D93C0E83F97F52C03561FBC9185944402828452BF77F52C0F06DFAB31F594440F9BD4D7FF67F52C0DC9A745B225944403AADDBA0F67F52C0BE4D7FF62359444093C49272F77F52C0526342CC25594440450DA661F87F52C0798EC87729594440F2CCCB61F77F52C0067FBF982D5944409B030473F47F52C017821C94305944401E300F99F27F52C05609168733594440E57FF277EF7F52C0EDBAB72231594440A3AA09A2EE7F52C0EA1ED95C355944405D18E945ED7F52C0D3F6AFAC345944401C5DA5BBEB7F52C076DB85E63A5944404BADF71BED7F52C0B1D991EA3B5944401F477364E57F52C0E48409A35959444022179CC1DF7F52C001D8800871594440A4703D0AD77F52C02EC6C03A8E594440457F68E6C97F52C061C26856B659444070404B57B07F52C0FCDEA63FFB594440DC10E335AF7F52C048E00F3FFF59444055F7C8E6AA7F52C02DB4739A055A4440A4E2FF8EA87F52C00CFFE9060A5A44407E8AE3C0AB7F52C0EC4960730E5A444006F2ECF2AD7F52C08CD99255115A444042588D25AC7F52C09BA8A5B9155A44405A9A5B21AC7F52C0F4BF5C8B165A44406762BA10AB7F52C0A5BA8097195A4440E5B7E864A97F52C0B6BDDD921C5A44402B4A09C1AA7F52C0499F56D11F5A4440D48041D2A77F52C0177FDB13245A4440C22FF5F3A67F52C0D55B035B255A4440FE7BF0DAA57F52C0F8FD9B17275A44409A046F48A37F52C04FADBEBA2A5A444045F12A6B9B7F52C0AC1919E42E5A44404BE2AC889A7F52C0A75CE15D2E5A4440462575029A7F52C0965984622B5A4440E75086AA987F52C0906802452C5A44400B2769FE987F52C05FB01BB62D5A444004029D499B7F52C0DD2230D6375A44404301DBC1887F52C0CBF10A444F5A4440D6A88768747F52C0B81E85EB515A44407C0C569C6A7F52C0F6CFD380415A4440CB113290677F52C0A9328CBB415A44407905A227657F52C03D7C9928425A44407EA5F3E1597F52C0787AA52C435A444009F7CABC557F52C0A2410A9E425A44408D23D6E2537F52C00EF8FC30425A444029780AB9527F52C08B19E1ED415A44402992AF04527F52C08B19E1ED415A4440C51A2E724F7F52C08B19E1ED415A4440AC36FFAF3A7F52C01AA6B6D4415A444009522976347F52C0A2410A9E425A4440F25D4A5D327F52C0252026E1425A44408252B4722F7F52C05A61FA5E435A444032E202D0287F52C013B534B7425A4440E0BBCD1B277F52C014E97E4E415A44409352D0ED257F52C0151DC9E53F5A444022F94A20257F52C0B08BA2073E5A4440CF9ECBD4247F52C0F3AE7AC03C5A444077A1B94E237F52C0F3AE7AC03C5A4440DDB419A7217F52C097FBE428405A4440666A12BC217F52C016A243E0485A44408EACFC32187F52C0CD8DE9094B5A44404F05DCF3FC7E52C0B952CF82505A4440D2E0B6B6F07E52C0FFCA4A93525A44404F029B73F07E52C0A7E7DD58505A4440EA3C2AFEEF7E52C020B41EBE4C5A44404A5F0839EF7E52C01AF7E6374C5A4440D462F030ED7E52C055F5F23B4D5A4440825660C8EA7E52C0B5FD2B2B4D5A4440825660C8EA7E52C072DA53724E5A44403C2CD49AE67E52C030B77BB94F5A44400DDC813AE57E52C0D76B7A50505A4440670DDE57E57E52C0072461DF4E5A4440C77DAB75E27E52C0A25EF0694E5A4440ABB2EF8AE07E52C04F04711E4E5A44403A3FC571E07E52C03C65355D4F5A4440643A747ADE7E52C04ED026874F5A444077F35487DC7E52C08A027D224F5A4440F0A5F0A0D97E52C031EBC5504E5A444068588CBAD67E52C0D8D30E7F4D5A444046B3B27DC87E52C06FB9FAB1495A4440B85A272EC77E52C03C821B295B5A444039CE6DC2BD7E52C097016729595A44409A07B0C8AF7E52C07FD93D79585A44407E8AE3C0AB7E52C0EBC37AA3565A4440C1E10511A97E52C0D097DEFE5C5A44401B82E3326E7E52C03F170D198F5A44408A3C49BA667E52C0D619DF17975A444026DF6C73637E52C07A32FFE89B5A4440E78BBD175F7E52C000FE2955A25A4440594DD7135D7E52C040852348A55A4440E36A64575A7E52C03EE94482A95A4440E603029D497E52C067B62BF4C15A4440ED42739D467E52C04701A260C65A4440253ACB2C427E52C03E40F7E5CC5A4440D026874F3A7E52C061C5A9D6C25A44405C5837DE1D7E52C0868F8829915A4440162EABB0197E52C007B5DFDA895A4440B859BC58187E52C083A279008B5A44408FE046CA167E52C011FB04508C5A4440B131AF230E7E52C0D2C43BC0935A44401A4CC3F0117E52C0F0FACC599F5A44401A321EA5127E52C06631B1F9B85A44402B836A83137E52C0E55C8AABCA5A4440C9737D1F0E7E52C0B376DB85E65A4440D3687231067E52C07405DB88275B444009DE9046057E52C09A94826E2F5B4440158C4AEA047E52C08D7E349C325B4440C808A870047E52C0B6114F76335B4440634337FB037E52C00F290648345B4440DAA7E331037E52C03E7958A8355B444082902C60027E52C0DE3CD521375B4440AB5791D1017E52C048BF7D1D385B4440942F6821017E52C095287B4B395B4440268C6665FB7D52C0548A1D8D435B44405C1B2AC6F97D52C065187783685B4440FA0B3D62F47D52C03FE08101845B4440E2E313B2F37D52C03196E997885B444038F4160FEF7D52C05D50DF32A75B4440109546CCEC7D52C07FDB1324B65B44401C261AA4E07D52C0BA641C23D95B444076BF0AF0DD7D52C06AF7AB00DF5B4440DCB8C5FCDC7D52C0B06F2711E15B44405A0EF450DB7D52C0081F4AB4E45B444084D558C2DA7D52C0F57F0EF3E55B4440BBB20B06D77D52C06E693524EE5B4440CE6BEC12D57D52C0FB592C45F25B444073672618CE7D52C09A0645F3005C4440BB7B80EECB7D52C0C7BAB88D065C4440F5F411F8C37D52C057E9EE3A1B5C44407B8670CCB27D52C09AB4A9BA475C4440240B98C0AD7D52C0282A1BD6545C4440E4839ECDAA7D52C0FA5E43705C5C4440E4805D4D9E7D52C08AAA5FE97C5C44401B2AC6F99B7D52C01C2444F9825C4440D3122BA3917D52C059F8FA5A975C4440A7ACA6EB897D52C0FD2D01F8A75C444007B5DFDA897D52C04818062CB95C44401EF7ADD6897D52C0399A232BBF5C444036397CD2897D52C0904946CEC25C444001DE02098A7D52C08A58C4B0C35C4440CB68E4F38A7D52C0527B116DC75C4440AD4F39268B7D52C0AB92C83EC85C4440531EDD088B7D52C0EB19C231CB5C4440C5C551B9897D52C070EB6E9EEA5C444090847D3B897D52C02E5393E00D5D44409C4CDC2A887D52C01D39D219185D4440FC6EBA65877D52C00D87A5811F5D4440D9CC21A9857D52C0641F6459305D44402D7590D7837D52C0DB4FC6F8305D44409354A698837D52C03FE1ECD6325D44402D5BEB8B847D52C05CC64D0D345D44403A3DEFC6827D52C02C0E677E355D44405299620E827D52C0938C9C853D5D444011AAD4EC817D52C0CE8AA8893E5D44407689EAAD817D52C045BB0A293F5D444094A2957B817D52C02C5F97E13F5D4440EDED96E4807D52C060048D99445D44407C7A6CCB807D52C00551F701485D4440BE69FAEC807D52C0999A046F485D44401781B1BE817D52C0ECF483BA485D444028ECA2E8817D52C0F6D214014E5D44403480B740827D52C07024D060535D4440BD35B055827D52C0CEF8BEB8545D44401C3EE944827D52C03F389F3A565D4440FF243E77827D52C0B534B742585D44407B2C7DE8827D52C02AFD84B35B5D44406F7EC344837D52C0535C55F65D5D4440DA006C40847D52C041F163CC5D5D4440459DB987847D52C0CE15A584605D4440FDBCA948857D52C0F4A44C6A685D44408658FD11867D52C097A608707A5D44404FAF9465887D52C03EC91D36915D4440BD38F1D58E7D52C0CFF753E3A55D44406876DD5B917D52C0F1B6D26BB35D44405B7A34D5937D52C0E4F1B4FCC05D4440B6476FB88F7D52C0C0E78711C25D4440743E3C4B907D52C0A5BBEB6CC85D4440D190F128957D52C03A394371C75D4440ADA06989957D52C0512D228AC95D4440D74D29AF957D52C01BB80375CA5D4440307F85CC957D52C0E542E55FCB5D444042EA76F6957D52C049D40B3ECD5D444054556820967D52C0B3226AA2CF5D44408F6D1970967D52C0C189E8D7D65D4440AD6C1FF2967D52C0F71BEDB8E15D4440BED7101C977D52C0C8B4368DED5D4440D47D00529B7D52C0EBE1CB44115E44403F00A94D9C7D52C068774831405E4440F7393E5A9C7D52C04339D1AE425E44409831056B9C7D52C090A2CEDC435E4440984BAAB69B7D52C02384471B475E4440A547533D997D52C04ED026874F5E44403F170D198F7D52C00E661360585E4440545227A0897D52C0E202D0285D5E4440D3139678407D52C026A435069D5E44406C753925207D52C0CA54C1A8A45E44403B1BF2CF0C7D52C0E17CEA58A55E4440FD12F1D6F97C52C078962023A05E444068C9E369F97C52C0A81ABD1AA05E44406FBA6587F87C52C037A79201A05E44407008556AF67C52C0CC24EA059F5E44404CE141B3EB7C52C0F3FE3F4E985E444003CE52B29C7C52C06C239EEC665E44409AB33EE5987C52C020EEEA55645E4440DFC0E446917C52C0CF6394675E5E444014200A664C7C52C07F315BB22A5E44401D8D43FD2E7C52C0D71533C2DB5D4440C4758C2B2E7C52C09C4B7155D95D4440EE08A7052F7C52C0444B1E4FCB5D444091B6F1272A7C52C0A7069ACFB95D444014C95702297C52C0CC785BE9B55D4440807F4A95287C52C0567C43E1B35D44407405DB88277C52C0A0C4E74EB05D44400057B263237C52C07E39B35DA15D4440AC8BDB68007C52C0AB90F2936A5D444025E4839ECD7B52C0395E81E8495D444018265305A37B52C0C2DCEEE53E5D44402781CD39787B52C0685721E5275D4440514832AB777B52C0639AE95E275D4440F2599E07777B52C0EC6987BF265D4440F94A2025767B52C0B16B7BBB255D44409485AFAF757B52C088D860E1245D4440893F8A3A737B52C09622F94A205D44408D0C7217617B52C0BF5E61C1FD5C444026C286A7577B52C0D3DA34B6D75C4440FCDD3B6A4C7B52C0D0967329AE5C444030630AD6387B52C082C64CA25E5C444081E7DEC3257B52C0A33B889D295C4440639AE95E277B52C0D47FD6FCF85B44407EC34483147B52C03A394371C75B4440342A70B20D7B52C0D826158DB55B444099EFE0270E7B52C06762BA10AB5B4440D3F36E2C287B52C0350873BB975B4440D427B9C3267B52C07842AF3F895B4440C4245CC8237B52C030D7A205685B4440880CAB78237B52C08B8A389D645B4440902E36AD147B52C0718C648F505B4440AF928FDD057B52C05169C4CC3E5B44407E8978EBFC7A52C0FC1BB4571F5B44409DF0129CFA7A52C05D86FF74035B4440DCD8EC48F57A52C044A51133FB5A444027BD6F7CED7A52C0D769A4A5F25A44406B9C4D47007B52C0E4F4F57CCD5A4440F29881CAF87A52C095D233BDC45A44403F19E3C3EC7A52C05BEB8B84B65A44403468E89FE07A52C0DF14562AA85A4440E0F08288D47A52C0224F92AE995A44403448C153C87A52C0B8E34D7E8B5A44401155F833BC7A52C06C91B41B7D5A44401DE6CB0BB07A52C050C3B7B06E5A444029779FE3A37A52C0A568E55E605A44400584D6C3977A52C0889AE8F3515A44401215AA9B8B7A52C0DD3F16A2435A4440EE21E17B7F7A52C0C1711937355A4440B3EC4960737A52C0E692AAED265A4440D7BFEB33677A52C0CAC4AD82185A4440E350BF0B5B7A52C04EEE77280A5A4440CE18E6046D7A52C001FA7DFFE6594440DAA9B9DC607A52C0B5A7E49CD8594440B7B6F0BC547A52C0DAC87553CA594440DB899290487A52C0ED7E15E0BB594440CB0EF10F5B7A52C0239D819197594440A25EF0694E7A52C0B340BB438A594440BBEB6CC83F7A52C092E9D0E9795944407F68E6C9357A52C033C4B12E6E594440205D6C5A297A52C05DA27A6B605944401B834E081D7A52C065AA605452594440765089EB187A52C0A27895B54D5944402A357BA0157A52C07B4D0F0A4A5944408A5759DB147A52C0F2B1BB404959444097530262127A52C0D0436D1B465944409E5E29CB107A52C0ADA1D45E445944400A630B410E7A52C07F85CC9541594440DB12B9E00C7A52C00F46EC134059444000378B170B7A52C039419B1C3E5944408A20CEC3097A52C06AF981AB3C59444080423D7D047A52C0670C738236594440CAA48636007A52C034677DCA31594440BF44BC75FE7952C0A051BAF42F594440605628D2FD7952C077BE9F1A2F59444093AAED26F87952C0DF87838428594440CFF6E80DF77952C033164D672759444011346612F57952C07C2AA73D2559444001310917F27952C0E8482EFF21594440730CC85EEF7952C05567B5C01E594440984A3FE1EC7952C0B6D782DE1B5944404CE141B3EB7952C0570394861A594440C91CCBBBEA7952C00B9A9658195944408E1EBFB7E97952C08EACFC3218594440A794D74AE87952C08FE046CA165944409677D503E67952C0B41EBE4C145944402EC55565DF7952C0E2E995B20C5944408F52094FE87952C09DF0129CFA58444052EC681CEA7952C06326512FF8584440E02D90A0F87952C0739EB12FD9584440519E7939EC7952C05C8DEC4ACB584440938AC6DADF7952C0A5846055BD5844401666A19DD37952C07C08AA46AF58444029CE5147C77952C0B3942C27A1584440B2666490BB7952C0AEEE586C935844404E232D95B77952C0EDF0D7648D584440A4198BA6B37952C0FC6EBA65875844401E34BBEEAD7952C0179B560A81584440A297512CB77952C0289831056B5844400DE02D90A07952C0B3D0CE6916584440789961A3AC7952C0A6D1E4620C58444076FEEDB25F7952C015713AC956574440D50627A25F7952C06072A3C85A574440E7A562635E7952C0E08096AE6057444012876C205D7952C05AD2510E6657444072C3EFA65B7952C0C4EC65DB69574440FCC6D79E597952C0374D9F1D7057444051D7DAFB547952C0554FE61F7D574440658D7A88467952C04F1DAB949E57444008556AF6407952C04A7D59DAA95744406F9C14E63D7952C0A5811FD5B0574440A679C7293A7952C09CC0745AB757444061FBC9181F7952C097A608707A574440B0C91AF5107952C03483F8C08E5744402E36AD14027952C0718BF9B9A1574440D4997B48F87852C089D00836AE574440BBD23252EF7852C090BB085394574440EF8E8CD5E67852C01840F850A2574440EACE13CFD97852C0B6847CD0B35744408C48145AD67852C09012BBB6B7574440E690D442C97852C084B53176C257444063F030ED9B7852C090BA9D7DE5574440DFC0E446917852C0DEE2E13D075844403FFD67CD8F7852C0719010E50B5844401C2785798F7852C0764D486B0C584440B1BE81C98D7852C093FE5E0A0F58444037363B527D7852C0093543AA28584440C3D50110777852C09355116E32584440EEE714E4677852C03387A4164A584440717500C45D7852C07EA5F3E1595844407442E8A04B7852C0E108522976584440211CB3EC497852C0CE35CCD0785844405791D101497852C09D7DE5417A584440CB660E492D7852C0056A3178985844401AC1C6F5EF7752C0B9162D40DB5844400F7C0C569C7752C03EE8D9ACFA584440AC1E300F997752C0828AAA5FE9584440A661F888987752C0C2A38D23D6584440DCBC7152987752C042959A3DD0584440A661F888987752C0302AA913D0584440E7FF55478E7752C05DC2A1B7785844402FFA0AD28C7752C0581CCEFC6A584440DCB930D28B7752C021567F8461584440FB20CB82897752C062D7F6764B58444079909E22877752C0D89942E7355844408C63247B847752C0B58993FB1D584440ACE46377817752C0677E350708584440C6C210397D7752C0B2F4A10BEA57444074B680D07A7752C0909DB7B1D9574440DB317557767752C0077767EDB65744409A7631CD747752C02D7B12D89C5744400D6C9560717752C054FEB5BC72574440FC34EECD6F7752C0A3E6ABE4635744409E7AA4C16D7752C0D1949D7E50574440FE9C82FC6C7752C0E046CA16495744401E4FCB0F5C7752C09B53C90050574440D503E621537752C0E063B0E25457444037DC476E4D7752C032569BFF5757444070ED4449487752C0836C59BE2E57444066F50EB7437752C054C554FA0957444032022A1C417752C0713C9F01F55644404487C091407752C01F7EFE7BF05644406E4E2503407752C05D4C33DDEB56444088F546AD307752C03ECBF3E0EE5644401F0F7D772B7752C04835ECF7C4564440A33B889D297752C026AAB706B656444087A4164A267752C0938E72309B5644403B6F63B3237752C050FD834886564440D7F7E120217752C00D6C956071564440132A38BC207752C07A8A1C226E564440315D88D51F7752C07E8E8F1667564440D4F02DAC1B7752C0ADA415DF505644409E95B4E21B7752C09AE8F35146564440B88D06F0167752C0BB46CB811E564440A435069D107752C0C8E88024EC554440C9703C9F017752C0F01307D0EF55444083DE1B43007752C0855D143DF05544404EB4AB90F27652C0A69718CBF45544401ABE8575E37652C0C214E5D2F855444041649126DE7652C0FACE2F4AD0554440293C6876DD7652C0807D74EACA554440FAD170CADC7652C0779FE3A3C55544403FABCC94D67652C0F58079C8945544405AD76839D07652C0B41D537765554440849ECDAACF7652C0272D5C56615544405DA79196CA7652C0D87F9D9B36554440331477BCC97652C06A10E6762F55444060AB048BC37652C062F20698F95444402D23F59ECA7652C05D6919A9F754444011C30E63D27652C0B8E864A9F554444021C9ACDEE17652C073D87DC7F0544440F0F96184F07652C06FB72407EC5444408577B988EF7652C0DFA5D425E3544440A089B0E1E97652C0C8091346B35444403621AD31E87652C0999CDA19A6544440C763062AE37652C0EF3B86C77E5444401F4AB4E4F17652C0E0D4079277544440E2E65432007752C054E4107173544440FF0241800C7752C061FA5E437054444057B26323107752C0F677B6476F5444402026E1421E7752C00FEB8D5A61544440834F73F2227752C0E3361AC05B544440C2F693313E7752C0C05AB56B4254444097900F7A367752C0780C8FFD2C544440F834272F327752C06684B70721544440C4758C2B2E7752C03D0801F9125444408D959867257752C00E4A9869FB534440E68F696D1A7752C02FF99FFCDD53444022C2BF081A7752C0247F30F0DC534440EF1CCA50157752C03599F1B6D2534440C0B2D2A4147752C06551D845D15344409048DBF8137752C09509BFD4CF53444014419C87137752C0FB027AE1CE534440E5F04927127752C01A84B9DDCB53444092B06F27117752C0DAC87553CA5344407EA65EB7087752C0228C9FC6BD534440A3E4D539067752C065170CAEB9534440C2FA3F87F97652C059F5B9DA8A5344408BFA2477D87652C082A62556465344406403E962D37652C03197546D3753444018B49080D17652C0D5928E72305344404A22FB20CB7652C0765089EB185344402A1900AAB87652C0BE0F070951524440E386DF4DB77652C01F63EE5A425244400F7D772B4B7652C005A568E55E524440FB3F87F9F27552C07D224F92AE5144405793A7ACA67552C0D7C0560916514440BEDA519CA37552C0A44FABE80F514440745B22179C7552C0E2CCAFE600514440DCD6169E977552C00B43E4F4F5504440A93121E6927552C05E807D74EA504440D13FC1C58A7552C056ED9A90D6504440096B63EC847552C0AB92C83EC8504440AE80423D7D7552C04127840EBA50444040F7E5CC767552C0D0967329AE50444089CE328B507552C0162D40DB6A504440C8ED974F567552C05646239F57504440211FF46C567552C03674B33F5050444015713AC9567552C059DC7F643A5044404AB20E47577552C028B682A62550444037AB3E575B7552C0F7AE415F7A4F44408D261763607552C0226C787AA54E444045460724617552C0A94885B1854E4440F62686E4647552C02D978DCEF94D444036AE7FD7677552C018AE0E80B84D4440B9E00CFE7E7552C0B01F6283854D4440446B459BE37552C0C5E23785954C444012A27C410B7652C03C1405FA444C4440588B4F01307652C0B058C345EE4B4440A6457D923B7652C07C28D192C74B44402C9CA4F9637652C0A2957B81594B4440A81ABD1AA07652C0300C5872154B4440FBC8AD49B77652C035272F32014B44404127840EBA7652C02AE109BDFE4A44401DCBBBEA017752C02172FA7ABE4A4440130CE71A667752C0C6A2E9EC644A44400A4B3CA06C7752C0BEF8A23D5E4A4440A5D93C0E837752C06473D53C474A4440FDBCA948857752C06B98A1F1444A4440F0C000C2877752C0F0DE5163424A4440D8817346947752C04450357A354A4440BF28417FA17752C08099EFE0274A44400A2DEBFEB17752C0BCAE5FB01B4A44407FF8F9EFC17752C08C0DDDEC0F4A444053C90050C57752C0B14B546F0D4A44402E71E481C87752C0BF61A2410A4A44401EFB592C457852C09F39EB538E494440056D72F8A47852C06D8E739B7049444036AD1402B97852C0D68BA19C68494440F59F353FFE7852C0BAA0BE654E494440289A07B0C87952C0C58F31772D4944406133C005D97952C0D862B7CF2A494440E1783E03EA7952C04DDA54DD2349444046B3B27DC87A52C06A11514CDE4844402F185C73477B52C0FCE25295B6484440A26131EA5A7B52C06A696E85B04844408499B67F657B52C036902E36AD4844404F8F6D19707B52C0C1C760C5A94844402E1D739EB17B52C02BDCF29194484440F9122A38BC7B52C0B5132521914844401021AE9CBD7B52C080D250A39048444081CEA44DD57B52C0431B800D88484440BBB88D06F07B52C076A38FF980484440B5A50EF27A7C52C07780272D5C484440F7C77BD5CA7C52C08AE5965643484440614D6551D87C52C05CFDD8243F484440E84CDA54DD7C52C03F1878EE3D4844409947FE60E07C52C05774EB353D484440AF0793E2E37C52C0FF5C34643C48444065A54929E87C52C0C45E28603B484440EFAB72A1F27C52C01F12BEF737484440D07D39B35D7D52C0075F984C1548444025AB22DC647D52C03D0801F912484440C39E76F86B7D52C0861C5BCF104844401211FE45D07F52C0F2CEA10C55474440B804E09F528252C0785C548B884644407615527E528252C0DB85E63A8D464440E2E5E95C518252C0BB270F0BB546444089B48D3F518252C0A7203F1BB94644400858AB764D8252C0F294D5743D474440CD565EF23F8252C07D7555A0164944401B28F04E3E8252C0E9F010C64F494440AAB4C5353E8252C0BDC117265349444032CB9E04368252C0F6285C8FC24944405111A7936C8252C09FE238F06A4B44402252D32EA68252C0BC02D193324D44404C50C3B7B08252C0F9F36DC1524D444068075C57CC8252C0ECDCB419A74D4440A31F0DA7CC8252C086E3F90CA84D44409D2E8B89CD8252C0438CD7BCAA4D44402BA1BB24CE8252C00726378AAC4D4440DDE9CE13CF8252C035423F53AF4D4440A774B0FECF8252C0C266800BB24D4440A626C11BD28252C007431D56B84D4440EDD286C3D28252C0DC476E4DBA4D44402638F581E48252C04A5F0839EF4D444074779D0DF98252C0E3C281902C4E4440890629780A8352C016DC0F78604E44408315A75A0B8352C0E5EFDE51634E4440EA793716148352C036E84B6F7F4E44404703780B248352C0C24CDBBFB24E44403046240A2D8352C09BE09BA6CF4E4440A4C00298328352C02D776682E14E444055F833BC598352C09F91088D604F4440B3B27DC85B8352C08922A46E674F444075E789E76C8352C066118AADA04F44400D52F014728352C051F355F2B14F4440C5ABAC6D8A8352C0D4D00660035044403D7E6FD39F8352C05C1ABFF04A5044405051F52B9D8352C042B28009DC504440'::geometry INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundariesbypointandradius (username text, orgname text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundariesbypointandradius invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, radius, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0106000020E6100000010000000103000000010000001500000083A3E4D5397C52C09946938B315A44404AED45B41D7C52C0785DBF60375A444099F221A81A7C52C0D0EFFB372F5A4440B9C15087157C52C034643C4A255A4440BB438A01127C52C0DE1CAED51E5A44400FECF82F107C52C0876D8B321B5A4440510FD1E80E7C52C0C4D32B65195A44407FDAA84E077C52C0E0675C38105A444092AD2EA7047C52C08E75711B0D5A4440CF2D7425027C52C0A86DC328085A4440EFFCA204FD7B52C07E384888F259444034BC5983F77B52C0205ED72FD8594440E76F4221027C52C0F3A96395D259444081AD122C0E7C52C00ED6FF39CC594440CB63CDC8207C52C031276893C359444047205ED72F7C52C0287D21E4BC594440BD1C76DF317C52C0F8325184D4594440CD1FD3DA347C52C0B0A9F3A8F8594440C72E51BD357C52C0C3651536035A444043024697377C52C028999CDA195A444083A3E4D5397C52C09946938B315A4440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpointsbygeometry (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpointsbygeometry invoked with params (%, %, %, %, %, %)', username, orgname, geom, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0101000020E610000037CB75821A7C52C0BA8784EFFD594440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpointsbypointandradius (username text, orgname text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpointsbypointandradius invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, radius, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0101000020E610000037CB75821A7C52C0BA8784EFFD594440'::geometry as the_geom, '36047048900'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getmeasure (username text, orgname text, geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getmeasure invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, measure_id, normalize, boundary_id, time_span; + SELECT 10923.093200390833950::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getcategory (username text, orgname text, geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getcategory invoked with params (%, %, %, %, %, %)', username, orgname, geom, category_id, boundary_id, time_span; + SELECT 'Wealthy, urban without Kids'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getuscensusmeasure (username text, orgname text, geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getuscensusmeasure invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, name, normalize, boundary_id, time_span; + SELECT 6789.5647735060920500::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getuscensuscategory (username text, orgname text, geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getuscensuscategory invoked with params (%, %, %, %, %, %)', username, orgname, geom, name, boundary_id, time_span; + SELECT 'Wealthy, urban without Kids'::text INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getpopulation (username text, orgname text, geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getpopulation invoked with params (%, %, %, %, %, %)', username, orgname, geom, normalize, boundary_id, time_span; + SELECT 10923.093200390833950::numeric INTO ret; + RETURN ret; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_search (username text, orgname text, search_term text, relevant_boundary text DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_search invoked with params (%, %, %, %)', username, orgname, search_term, relevant_boundary; + RETURN QUERY SELECT 'es.ine.total_pop'::text as id, 'The total number of all people living in a geographic area.'::text as description, 'Total Population'::text as name, 'sum'::text as aggregate, NULL::text as source; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getavailableboundaries (username text, orgname text, geom geometry(Geometry, 4326), timespan text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getavailableboundaries invoked with params (%, %, %, %)', username, orgname, geom, timespan; + RETURN QUERY SELECT 'us.census.tiger.place'::text as boundary_id, 'Incorporated places are those reported to the Census Bureau as legally in existence as of January 1, 2010, as reported in the latest Boundary and Annexation Survey (BAS), under the laws of their respective states.'::text as description, '2014'::text as timespan, 'obs_7c9493c41fa8f4bd178ab993ea3d5891c1977667'::text as tablename; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getboundariesbygeometry (username text, orgname text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +BEGIN + RAISE NOTICE 'cdb_dataservices_server.obs_getboundariesbygeometry invoked with params (%, %, %, %, %, %)', username, orgname, geom, boundary_id, time_span, overlap_type; + RETURN QUERY SELECT '0106000020E61000000100000001030000000100000019000000DD96C805677C52C0CBD8D0CDFE5A44407A19C5724B7C52C033BF9A03045B4440FF59F3E32F7C52C0CB290131095B4440247EC51A2E7C52C0548B8862F25A44401FF5D72B2C7C52C0CB811E6ADB5A444049F086342A7C52C09CC3B5DAC35A444044679945287C52C01F680586AC5A444012D90759167C52C09430D3F6AF5A44405698BED7107C52C04759BF99985A4440DEE522BE137C52C00664AF777F5A4440F92EA52E197C52C09BA73AE4665A4440C558A65F227C52C0D80DDB16655A4440373465A71F7C52C065A71FD4455A44404AED45B41D7C52C0785DBF60375A444083A3E4D5397C52C09946938B315A4440F2B4FCC0557C52C01FF5D72B2C5A444026C286A7577C52C02BDD5D67435A44405BCF108E597C52C0C651B9895A5A444030D461855B7C52C0D1393FC5715A444065E1EB6B5D7C52C078280AF4895A44403AE63C635F7C52C07D1F0E12A25A44403F6F2A52617C52C05983F755B95A44405C3AE63C637C52C04852D2C3D05A444049810530657C52C0FAEE5696E85A4440DD96C805677C52C0CBD8D0CDFE5A4440'::geometry as the_geom, '36047049300'::text as geom_refs; +END; +$$ LANGUAGE 'plpgsql'; -- Exercise the public and the proxied function -SELECT obs_get_demographic_snapshot('POINT(-87.81406 41.89308)'::geometry); -SELECT obs_get_segment_snapshot('POINT(-87.81406 41.89308)'::geometry); \ No newline at end of file +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_getdemographicsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013', '"us.census.tiger".block_group'::text); +SELECT obs_getsegmentsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); +SELECT obs_getboundary(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); +SELECT obs_getboundaryid(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); +SELECT obs_getboundarybyid('36047'::text, 'us.census.tiger.county'::text); +SELECT obs_getboundariesbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); +SELECT obs_getboundariesbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500, 'us.census.tiger.census_tract'::text); +SELECT obs_getpointsbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); +SELECT obs_getpointsbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500::numeric, 'us.census.tiger.census_tract'::text); +SELECT obs_getmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.acs.B01001001'::text); +SELECT obs_getcategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.spielman_singleton_segments.X10'::text); +SELECT obs_getuscensusmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'male population'::text); +SELECT obs_getuscensuscategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'Spielman-Singleton Segments: 10 Clusters'::text); +SELECT obs_getpopulation(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); +SELECT obs_search('total_pop'::text); +SELECT obs_getavailableboundaries(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); diff --git a/server/extension/Makefile b/server/extension/Makefile index 0acc452..1c869fc 100644 --- a/server/extension/Makefile +++ b/server/extension/Makefile @@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql) # @see http://www.postgresql.org/docs/current/static/extend-pgxs.html DATA = $(NEW_EXTENSION_ARTIFACT) \ $(OLD_VERSIONS) \ - cdb_dataservices_server--0.7.3--0.7.4.sql \ - cdb_dataservices_server--0.7.4--0.7.3.sql + cdb_dataservices_server--0.7.4--0.8.0.sql \ + cdb_dataservices_server--0.8.0--0.7.4.sql REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql))) TEST_DIR = test/ diff --git a/server/extension/cdb_dataservices_server--0.7.4--0.8.0.sql b/server/extension/cdb_dataservices_server--0.7.4--0.8.0.sql new file mode 100644 index 0000000..718f858 --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.7.4--0.8.0.sql @@ -0,0 +1,966 @@ +--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.8.0'" to load this file. \quit +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshot(text, text, geometry(Geometry, 4326), text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshot(text, text, geometry(Geometry, 4326), text); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_config(username text, orgname text) +RETURNS boolean AS $$ + cache_key = "user_obs_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import ObservatoryConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + obs_config = ObservatoryConfig(redis_conn, plpy, username, orgname) + GD[cache_key] = obs_config + return True +$$ LANGUAGE plpythonu SECURITY DEFINER; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshotJSON( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshotJSON($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetDemographicSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF JSON AS $$ + from cartodb_services.metrics import QuotaService + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) + if result: + resp = [] + for element in result: + value = element['snapshot'] + resp.append(value) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshotJSON( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshotJSON($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetSegmentSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF JSON AS $$ + from cartodb_services.metrics import QuotaService + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) + if result: + resp = [] + for element in result: + value = element['snapshot'] + resp.append(value) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetMeasure(geom, measure_id, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasure($1, $2, $3, $4, $5, $6, $7) as measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, measure_id, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['measure'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetMeasure: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + category_id TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetCategory(geom, category_id, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + category_id TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetCategory($1, $2, $3, $4, $5, $6) as category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, category_id, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['category'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetCategory: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetUSCensusMeasure(geom, name, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusMeasure($1, $2, $3, $4, $5, $6, $7) as census_measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, name, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['census_measure'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetUSCensusMeasure: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetUSCensusCategory(geom, name, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusCategory($1, $2, $3, $4, $5, $6) as census_category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, name, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['census_category'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetUSCensusCategory: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetPopulation(geom, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetPopulation($1, $2, $3, $4, $5, $6) as population;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['population'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPopulation: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_Search( + username TEXT, + orgname TEXT, + search_term TEXT, + relevant_boundary TEXT DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_Search(search_term, relevant_boundary); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_Search( + username TEXT, + orgname TEXT, + search_term TEXT, + relevant_boundary TEXT DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_Search($1, $2, $3, $4) as search;", ["text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, search_term, relevant_boundary]) + if result: + resp = [] + for element in result: + id = element['id'] + description = element['description'] + name = element['name'] + aggregate = element['aggregate'] + source = element['source'] + resp.append([id, description, name, aggregate, source]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_Search: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetAvailableBoundaries( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableBoundaries(geom, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableBoundaries( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetAvailableBoundaries($1, $2, $3, $4) as available_boundaries;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span]) + if result: + resp = [] + for element in result: + id = element['boundary_id'] + description = element['description'] + tspan = element['time_span'] + tablename = element['tablename'] + resp.append([id, description, tspan, tablename]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetAvailableBoundaries: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundary( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundary(geom, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundary( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundary($1, $2, $3, $4) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundary: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryId( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundaryId(geom, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryId( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryId($1, $2, $3, $4, $5) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use obs_search: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryById( + username TEXT, + orgname TEXT, + geometry_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundaryById(geometry_id, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryById( + username TEXT, + orgname TEXT, + geometry_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryById($1, $2, $3, $4, $5) as boundary;", ["text", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geometry_id, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundaryById: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetBoundariesByGeometry(geom, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundariesByGeometry: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetBoundariesByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundariesByPointAndRadius: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetPointsByGeometry(geom, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPointsByGeometry: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetPointsByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPointsByPointAndRadius: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + + diff --git a/server/extension/cdb_dataservices_server--0.8.0--0.7.4.sql b/server/extension/cdb_dataservices_server--0.8.0--0.7.4.sql new file mode 100644 index 0000000..f907e15 --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.8.0--0.7.4.sql @@ -0,0 +1,138 @@ +--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.7.4'" to load this file. \quit + +DROP FUNCTION IF EXISTS cdb_dataservices_server._get_obs_config(text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshot(text, text, geometry(Geometry, 4326), text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshotJSON(text, text, geometry(Geometry, 4326), text, text); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetDemographicSnapshot(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshot(text, text, geometry(Geometry, 4326), text); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshotJSON(text, text, geometry(Geometry, 4326), text); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetSegmentSnapshot(TEXT, TEXT, geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetUSCensusMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetUSCensusMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetUSCensusCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetUSCensusCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPopulation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPopulation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_Search(TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_Search(TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableBoundaries(TEXT, TEXT, geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetAvailableBoundaries(TEXT, TEXT, geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundary(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundary(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundaryId(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundaryId(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundaryById(TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundaryById(TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundariesByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundariesByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius(TEXT, TEXT, NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius(TEXT, TEXT, NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPointsByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPointsByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPointsByPointAndRadius(TEXT, TEXT, geometry(Point, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPointsByPointAndRadius(TEXT, TEXT, geometry(Point, 4326), NUMERIC, TEXT, TEXT, TEXT); + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT '2009 - 2013', + geometry_level TEXT DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT '2009 - 2013', + geometry_level TEXT DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT '"us.census.tiger".block_group') +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; \ No newline at end of file diff --git a/server/extension/cdb_dataservices_server.control b/server/extension/cdb_dataservices_server.control index cc9db8e..19613d1 100644 --- a/server/extension/cdb_dataservices_server.control +++ b/server/extension/cdb_dataservices_server.control @@ -1,5 +1,5 @@ comment = 'CartoDB dataservices server extension' -default_version = '0.7.4' +default_version = '0.8.0' requires = 'plpythonu, plproxy, postgis, cdb_geocoder' superuser = true schema = cdb_dataservices_server diff --git a/server/extension/cdb_dataservices_server--0.7.3--0.7.4.sql b/server/extension/old_versions/cdb_dataservices_server--0.7.3--0.7.4.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.7.3--0.7.4.sql rename to server/extension/old_versions/cdb_dataservices_server--0.7.3--0.7.4.sql diff --git a/server/extension/cdb_dataservices_server--0.7.4--0.7.3.sql b/server/extension/old_versions/cdb_dataservices_server--0.7.4--0.7.3.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.7.4--0.7.3.sql rename to server/extension/old_versions/cdb_dataservices_server--0.7.4--0.7.3.sql diff --git a/server/extension/cdb_dataservices_server--0.7.4.sql b/server/extension/old_versions/cdb_dataservices_server--0.7.4.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.7.4.sql rename to server/extension/old_versions/cdb_dataservices_server--0.7.4.sql diff --git a/server/extension/sql/110_data_observatory.sql b/server/extension/sql/110_data_observatory.sql deleted file mode 100644 index 1f3075b..0000000 --- a/server/extension/sql/110_data_observatory.sql +++ /dev/null @@ -1,115 +0,0 @@ --- --- Observatory connection config --- --- The purpose of this function is provide to the PL/Proxy functions --- the connection string needed to connect with the current production database - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_server_conn_str( - username TEXT, - orgname TEXT) -RETURNS text AS $$ - 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] - - return user_obs_snapshot_config.connection_str -$$ LANGUAGE plpythonu; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - time_span TEXT DEFAULT '2009 - 2013', - geometry_level TEXT DEFAULT '"us.census.tiger".block_group') -RETURNS json AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); -$$ LANGUAGE plproxy; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - time_span TEXT DEFAULT '2009 - 2013', - geometry_level TEXT DEFAULT '"us.census.tiger".block_group') -RETURNS json AS $$ - from cartodb_services.metrics import QuotaService - import json - - 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] - - quota_service = QuotaService(user_obs_snapshot_config, redis_conn) - if not quota_service.check_user_quota(): - plpy.error('You have reached the limit of your quota') - - try: - obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) - result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) - if result: - quota_service.increment_success_service_use() - return result[0]['snapshot'] - else: - quota_service.increment_empty_service_use() - return None - except BaseException as e: - import sys, traceback - type_, value_, traceback_ = sys.exc_info() - quota_service.increment_failed_service_use() - error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) - plpy.notice(traceback.format_tb(traceback_)) - plpy.error(error_msg) - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE plpythonu; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - geometry_level TEXT DEFAULT '"us.census.tiger".block_group') -RETURNS json AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); -$$ LANGUAGE plproxy; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - geometry_level TEXT DEFAULT '"us.census.tiger".block_group') -RETURNS json AS $$ - from cartodb_services.metrics import QuotaService - import json - - 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] - - quota_service = QuotaService(user_obs_snapshot_config, redis_conn) - if not quota_service.check_user_quota(): - plpy.error('You have reached the limit of your quota') - - try: - obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) - result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) - if result: - quota_service.increment_success_service_use() - return result[0]['snapshot'] - else: - quota_service.increment_empty_service_use() - return None - except BaseException as e: - import sys, traceback - type_, value_, traceback_ = sys.exc_info() - quota_service.increment_failed_service_use() - error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) - plpy.notice(traceback.format_tb(traceback_)) - plpy.error(error_msg) - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE plpythonu; diff --git a/server/extension/sql/110_data_observatory_augmentation.sql b/server/extension/sql/110_data_observatory_augmentation.sql new file mode 100644 index 0000000..6ad4042 --- /dev/null +++ b/server/extension/sql/110_data_observatory_augmentation.sql @@ -0,0 +1,478 @@ +-- +-- Observatory connection config +-- +-- The purpose of this function is provide to the PL/Proxy functions +-- the connection string needed to connect with the current production database + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_server_conn_str( + username TEXT, + orgname TEXT) +RETURNS text AS $$ + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + return user_obs_snapshot_config.connection_str +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshotJSON( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshotJSON($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetDemographicSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL, + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF JSON AS $$ + from cartodb_services.metrics import QuotaService + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level]) + if result: + resp = [] + for element in result: + value = element['snapshot'] + resp.append(value) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshotJSON( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS json AS $$ + from cartodb_services.metrics import QuotaService + import json + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshotJSON($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) + if result: + quota_service.increment_success_service_use() + return result[0]['snapshot'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF json AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetSegmentSnapshot( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + geometry_level TEXT DEFAULT NULL) +RETURNS SETOF JSON AS $$ + from cartodb_services.metrics import QuotaService + + 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_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)] + + quota_service = QuotaService(user_obs_snapshot_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level]) + if result: + resp = [] + for element in result: + value = element['snapshot'] + resp.append(value) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use get_segment_snapshot: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetMeasure(geom, measure_id, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasure($1, $2, $3, $4, $5, $6, $7) as measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, measure_id, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['measure'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetMeasure: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + category_id TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetCategory(geom, category_id, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + category_id TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetCategory($1, $2, $3, $4, $5, $6) as category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, category_id, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['category'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetCategory: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetUSCensusMeasure(geom, name, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusMeasure($1, $2, $3, $4, $5, $6, $7) as census_measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, name, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['census_measure'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetUSCensusMeasure: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetUSCensusCategory(geom, name, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusCategory( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusCategory($1, $2, $3, $4, $5, $6) as census_category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, name, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['census_category'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetUSCensusCategory: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetPopulation(geom, normalize, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT 'area', + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetPopulation($1, $2, $3, $4, $5, $6) as population;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, normalize, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['population'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPopulation: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; diff --git a/server/extension/sql/115_data_observatory_exploration.sql b/server/extension/sql/115_data_observatory_exploration.sql new file mode 100644 index 0000000..fbf38cc --- /dev/null +++ b/server/extension/sql/115_data_observatory_exploration.sql @@ -0,0 +1,108 @@ +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_Search( + username TEXT, + orgname TEXT, + search_term TEXT, + relevant_boundary TEXT DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_Search(search_term, relevant_boundary); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_Search( + username TEXT, + orgname TEXT, + search_term TEXT, + relevant_boundary TEXT DEFAULT NULL) +RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_Search($1, $2, $3, $4);", ["text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, search_term, relevant_boundary]) + if result: + resp = [] + for element in result: + id = element['id'] + description = element['description'] + name = element['name'] + aggregate = element['aggregate'] + source = element['source'] + resp.append([id, description, name, aggregate, source]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [None, None, None, None, None] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_Search: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetAvailableBoundaries( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableBoundaries(geom, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableBoundaries( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + time_span TEXT DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetAvailableBoundaries($1, $2, $3, $4) as available_boundaries;", ["text", "text", "geometry(Geometry, 4326)", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, time_span]) + if result: + resp = [] + for element in result: + id = element['boundary_id'] + description = element['description'] + tspan = element['time_span'] + tablename = element['tablename'] + resp.append([id, description, tspan, tablename]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetAvailableBoundaries: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; diff --git a/server/extension/sql/120_data_observatory_geometries.sql b/server/extension/sql/120_data_observatory_geometries.sql new file mode 100644 index 0000000..4281220 --- /dev/null +++ b/server/extension/sql/120_data_observatory_geometries.sql @@ -0,0 +1,374 @@ +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundary( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundary(geom, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundary( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundary($1, $2, $3, $4) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundary: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryId( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundaryId(geom, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryId( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS TEXT AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryId($1, $2, $3, $4, $5) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use obs_search: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryById( + username TEXT, + orgname TEXT, + geometry_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetBoundaryById(geometry_id, boundary_id, time_span); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryById( + username TEXT, + orgname TEXT, + geometry_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS geometry(Geometry, 4326) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryById($1, $2, $3, $4, $5) as boundary;", ["text", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geometry_id, boundary_id, time_span]) + if result: + quota_service.increment_success_service_use() + return result[0]['boundary'] + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundaryById: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type text DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetBoundariesByGeometry(geom, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundariesByGeometry: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetBoundariesByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetBoundariesByPointAndRadius: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetPointsByGeometry(geom, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByGeometry( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPointsByGeometry: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetPointsByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type); +$$ LANGUAGE plproxy; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByPointAndRadius( + username TEXT, + orgname TEXT, + geom geometry(Point, 4326), + radius NUMERIC, + boundary_id TEXT, + time_span TEXT DEFAULT NULL, + overlap_type TEXT DEFAULT 'intersects') +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import QuotaService + + 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)] + + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + plpy.error('You have reached the limit of your quota') + + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type]) + if result: + resp = [] + for element in result: + the_geom = element['the_geom'] + geom_refs = element['geom_refs'] + resp.append([the_geom, geom_refs]) + quota_service.increment_success_service_use() + return resp + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys, traceback + type_, value_, traceback_ = sys.exc_info() + quota_service.increment_failed_service_use() + error_msg = 'There was an error trying to use OBS_GetPointsByPointAndRadius: {0}'.format(e) + plpy.notice(traceback.format_tb(traceback_)) + plpy.error(error_msg) + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE plpythonu; diff --git a/server/extension/sql/15_config_helper.sql b/server/extension/sql/15_config_helper.sql index eb038fe..68726ff 100644 --- a/server/extension/sql/15_config_helper.sql +++ b/server/extension/sql/15_config_helper.sql @@ -67,3 +67,17 @@ RETURNS boolean AS $$ GD[cache_key] = obs_snapshot_config return True $$ LANGUAGE plpythonu SECURITY DEFINER; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_config(username text, orgname text) +RETURNS boolean AS $$ + cache_key = "user_obs_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import ObservatoryConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + obs_config = ObservatoryConfig(redis_conn, plpy, username, orgname) + GD[cache_key] = obs_config + return True +$$ LANGUAGE plpythonu SECURITY DEFINER; diff --git a/server/extension/test/expected/100_data_observatory_test.out b/server/extension/test/expected/100_data_observatory_test.out index 225382d..0cc1ac8 100644 --- a/server/extension/test/expected/100_data_observatory_test.out +++ b/server/extension/test/expected/100_data_observatory_test.out @@ -2,7 +2,7 @@ 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_get_demographic_snapshot' + AND proname = 'obs_getdemographicsnapshot' AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text'); exists -------- @@ -13,10 +13,164 @@ 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_get_segment_snapshot' + AND proname = 'obs_getsegmentsnapshot' AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text'); exists -------- t (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_getmeasure' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text'); + exists +-------- + t +(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_getcategory' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text'); + exists +-------- + t +(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_getuscensusmeasure' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text'); + exists +-------- + t +(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_getuscensuscategory' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text'); + exists +-------- + t +(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_getpopulation' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text'); + exists +-------- + t +(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_search' + AND oidvectortypes(p.proargtypes) = 'text, text, text, text'); + exists +-------- + t +(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_getavailableboundaries' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text'); + exists +-------- + t +(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_getboundary' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text'); + exists +-------- + t +(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_getboundaryid' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text'); + exists +-------- + t +(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_getboundarybyid' + AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text'); + exists +-------- + t +(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_getboundariesbygeometry' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text'); + exists +-------- + t +(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_getboundariesbypointandradius' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text'); + exists +-------- + t +(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_getpointsbygeometry' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text'); + exists +-------- + t +(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_getpointsbypointandradius' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text'); + exists +-------- + t +(1 row) + diff --git a/server/extension/test/sql/100_data_observatory_test.sql b/server/extension/test/sql/100_data_observatory_test.sql index 7621cb2..e8b9d85 100644 --- a/server/extension/test/sql/100_data_observatory_test.sql +++ b/server/extension/test/sql/100_data_observatory_test.sql @@ -2,12 +2,110 @@ 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_get_demographic_snapshot' + AND proname = 'obs_getdemographicsnapshot' AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_get_segment_snapshot' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text'); \ No newline at end of file + AND proname = 'obs_getsegmentsnapshot' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getmeasure' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, 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_getcategory' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getuscensusmeasure' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, 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_getuscensuscategory' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getpopulation' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_search' + AND oidvectortypes(p.proargtypes) = 'text, 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_getavailableboundaries' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getboundary' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getboundaryid' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getboundarybyid' + AND oidvectortypes(p.proargtypes) = 'text, text, 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_getboundariesbygeometry' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getboundariesbypointandradius' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, 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_getpointsbygeometry' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, 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_getpointsbypointandradius' + AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text'); \ No newline at end of file diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py b/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py index 0807d55..078bbbd 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py @@ -1,3 +1,3 @@ -from config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException, ObservatorySnapshotConfig +from config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException, ObservatorySnapshotConfig, ObservatoryConfig from quota import QuotaService from user import UserMetricsService diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/config.py b/server/lib/python/cartodb_services/cartodb_services/metrics/config.py index 141aa90..b1f110f 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/config.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/config.py @@ -33,32 +33,11 @@ class ServiceConfig(object): def organization(self): return self._orgname - -class ObservatorySnapshotConfig(ServiceConfig): - - SOFT_LIMIT_KEY = 'soft_obs_snapshot_limit' - QUOTA_KEY = 'obs_snapshot_quota' - PERIOD_END_DATE = 'period_end_date' +class DataObservatoryConfig(ServiceConfig): def __init__(self, redis_connection, db_conn, username, orgname=None): - super(ObservatorySnapshotConfig, self).__init__(redis_connection, db_conn, + super(DataObservatoryConfig, self).__init__(redis_connection, db_conn, username, orgname) - self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE]) - if self.SOFT_LIMIT_KEY in self._redis_config and self._redis_config[self.SOFT_LIMIT_KEY].lower() == 'true': - self._soft_limit = True - else: - self._soft_limit = False - # Mixed config between db and redis. If we don't update all the users - # in redis, we could use the db value as default - if self.QUOTA_KEY in self._redis_config: - self._monthly_quota = float(self._redis_config[self.QUOTA_KEY]) - else: - self._monthly_quota = float(self._db_config.data_observatory_monthly_quota) - self._connection_str = self._db_config.data_observatory_connection_str - - @property - def service_type(self): - return 'obs_snapshot' @property def monthly_quota(self): @@ -76,6 +55,52 @@ class ObservatorySnapshotConfig(ServiceConfig): def connection_str(self): return self._connection_str +class ObservatorySnapshotConfig(DataObservatoryConfig): + + SOFT_LIMIT_KEY = 'soft_obs_snapshot_limit' + QUOTA_KEY = 'obs_snapshot_quota' + PERIOD_END_DATE = 'period_end_date' + + def __init__(self, redis_connection, db_conn, username, orgname=None): + super(ObservatorySnapshotConfig, self).__init__(redis_connection, db_conn, + username, orgname) + self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE]) + if self.SOFT_LIMIT_KEY in self._redis_config and self._redis_config[self.SOFT_LIMIT_KEY].lower() == 'true': + self._soft_limit = True + else: + self._soft_limit = False + self._monthly_quota = 0 + if self.QUOTA_KEY in self._redis_config: + self._monthly_quota = float(self._redis_config[self.QUOTA_KEY]) + self._connection_str = self._db_config.data_observatory_connection_str + + @property + def service_type(self): + return 'obs_snapshot' + +class ObservatoryConfig(DataObservatoryConfig): + + SOFT_LIMIT_KEY = 'soft_obs_general_limit' + QUOTA_KEY = 'obs_general_quota' + PERIOD_END_DATE = 'period_end_date' + + def __init__(self, redis_connection, db_conn, username, orgname=None): + super(ObservatoryConfig, self).__init__(redis_connection, db_conn, + username, orgname) + self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE]) + if self.SOFT_LIMIT_KEY in self._redis_config and self._redis_config[self.SOFT_LIMIT_KEY].lower() == 'true': + self._soft_limit = True + else: + self._soft_limit = False + self._monthly_quota = 0 + if self.QUOTA_KEY in self._redis_config: + self._monthly_quota = float(self._redis_config[self.QUOTA_KEY]) + self._connection_str = self._db_config.data_observatory_connection_str + + @property + def service_type(self): + return 'obs_general' + class RoutingConfig(ServiceConfig): PERIOD_END_DATE = 'period_end_date' @@ -370,7 +395,6 @@ class ServicesDBConfig: raise ConfigException('Data Observatory configuration missing') else: do_conf = json.loads(do_conf_json) - self._data_observatory_monthly_quota = do_conf['monthly_quota'] if self._orgname and self._orgname in do_conf['connection']['whitelist']: self._data_observatory_connection_str = do_conf['connection']['staging'] elif self._username in do_conf['connection']['whitelist']: @@ -434,10 +458,6 @@ class ServicesDBConfig: def geocoder_log_path(self): return self._geocoder_log_path - @property - def data_observatory_monthly_quota(self): - return self._data_observatory_monthly_quota - @property def data_observatory_connection_str(self): return self._data_observatory_connection_str diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py b/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py index 2460082..c627769 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py @@ -73,9 +73,9 @@ class QuotaChecker: elif re.match('routing_mapzen', self._user_service_config.service_type) is not None: return self.__check_routing_quota() - elif re.match('obs_snapshot', + elif re.match('obs_*', self._user_service_config.service_type) is not None: - return self.__check_obs_snapshot_quota() + return self.__check_data_observatory_quota() else: return False @@ -118,13 +118,14 @@ class QuotaChecker: else: return False - def __check_obs_snapshot_quota(self): + def __check_data_observatory_quota(self): user_quota = self._user_service_config.monthly_quota + soft_limit = self._user_service_config.soft_limit today = date.today() service_type = self._user_service_config.service_type current_used = self._user_service.used_quota(service_type, today) - if (user_quota > 0 and current_used <= user_quota): + if soft_limit or (user_quota > 0 and current_used <= user_quota): return True else: return False diff --git a/server/lib/python/cartodb_services/setup.py b/server/lib/python/cartodb_services/setup.py index 5808b69..3254050 100644 --- a/server/lib/python/cartodb_services/setup.py +++ b/server/lib/python/cartodb_services/setup.py @@ -10,7 +10,7 @@ from setuptools import setup, find_packages setup( name='cartodb_services', - version='0.5.3', + version='0.6.0', description='CartoDB Services API Python Library', diff --git a/server/lib/python/cartodb_services/test/test_config.py b/server/lib/python/cartodb_services/test/test_config.py index 8d980d2..4a639ec 100644 --- a/server/lib/python/cartodb_services/test/test_config.py +++ b/server/lib/python/cartodb_services/test/test_config.py @@ -49,7 +49,7 @@ class TestConfig(TestCase): end_date=yesterday) do_config = ObservatorySnapshotConfig(self.redis_conn, self.plpy_mock, 'test_user') - assert do_config.monthly_quota == 100000 + assert do_config.monthly_quota == 0 assert do_config.soft_limit is False assert do_config.period_end_date.date() == yesterday.date() diff --git a/server/lib/python/cartodb_services/test/test_helper.py b/server/lib/python/cartodb_services/test/test_helper.py index 41d58e4..e13fa65 100644 --- a/server/lib/python/cartodb_services/test/test_helper.py +++ b/server/lib/python/cartodb_services/test/test_helper.py @@ -61,4 +61,4 @@ def _plpy_execute_side_effect(*args, **kwargs): elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('logger_conf') as conf": return [{'conf': '{"geocoder_log_path": "/dev/null"}'}] elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('data_observatory_conf') as conf": - return [{'conf': '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}'}] + return [{'conf': '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}}'}] diff --git a/test/integration/test_data_observatory_functions.py b/test/integration/test_data_observatory_functions.py index 8955d50..1ebe647 100644 --- a/test/integration/test_data_observatory_functions.py +++ b/test/integration/test_data_observatory_functions.py @@ -15,25 +15,220 @@ class TestDataObservatoryFunctions(TestCase): ) def test_if_get_demographic_snapshot_is_ok(self): - query = "SELECT obs_get_demographic_snapshot(CDB_LatLng(40.704512, -73.936669)) as snapshot;&api_key={0}".format(self.env_variables['api_key']) - snapshot = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(snapshot['snapshot'], None) + query = "SELECT obs_GetDemographicSnapshot(CDB_LatLng(40.704512, -73.936669)) as snapshot;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['snapshot'], None) def test_if_get_demographic_snapshot_without_api_key_raise_error(self): - query = "SELECT obs_get_demographic_snapshot(CDB_LatLng(40.704512, -73.936669));" + query = "SELECT obs_GetDemographicSnapshot(CDB_LatLng(40.704512, -73.936669));" try: IntegrationTestHelper.execute_query(self.sql_api_url, query) except Exception as e: assert_equal(e.message[0], "The api_key must be provided") def test_if_get_segment_snapshot_is_ok(self): - query = "SELECT obs_get_segment_snapshot(CDB_LatLng(40.704512, -73.936669)) as snapshot;&api_key={0}".format(self.env_variables['api_key']) - snapshot = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(snapshot['snapshot'], None) + query = "SELECT OBS_GetSegmentSnapshot(CDB_LatLng(40.704512, -73.936669)) as snapshot;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['snapshot'], None) def test_if_get_segment_snapshot_without_api_key_raise_error(self): - query = "SELECT obs_get_segment_snapshot(CDB_LatLng(40.704512, -73.936669));" + query = "SELECT OBS_GetSegmentSnapshot(CDB_LatLng(40.704512, -73.936669));" try: IntegrationTestHelper.execute_query(self.sql_api_url, query) except Exception as e: assert_equal(e.message[0], "The api_key must be provided") + + def test_if_get_measure_with_point_is_ok(self): + query = "SELECT OBS_GetMeasure(CDB_LatLng(40.704512, -73.936669), 'us.census.acs.B01001001') as measure;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['measure'], None) + assert_not_equal(result['measure'], 10923.097048937793740) + + def test_if_get_measure_with_area_is_ok(self): + query = "SELECT OBS_GetMeasure('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'us.census.acs.B01001001') as measure;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['measure'], None) + assert_not_equal(result['measure'], 12327.3133495107) + + def test_if_get_measure_without_api_key_raise_error(self): + query = "SELECT OBS_GetMeasure(CDB_LatLng(40.704512, -73.936669), 'us.census.acs.B01001001');" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_get_category_is_ok(self): + query = "SELECT OBS_GetCategory(CDB_LatLng(40.704512, -73.936669), 'us.census.spielman_singleton_segments.X10', 'us.census.tiger.census_tract', '2009 - 2013') as category;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['category'], None) + assert_equal(result['category'], 'Wealthy, urban without Kids') + + def test_if_get_category_without_api_key_raise_error(self): + query = "SELECT OBS_GetCategory(CDB_LatLng(40.704512, -73.936669), 'us.census.spielman_singleton_segments.X10', 'us.census.tiger.census_tract', '2009 - 2013');" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_get_us_census_measure_with_point_is_ok(self): + query = "SELECT OBS_GetUSCensusMeasure(CDB_LatLng(40.704512, -73.936669), 'male population') as measure;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['measure'], None) + assert_equal(result['measure'], 6789.56716568) + + def test_if_get_us_census_measure_with_area_is_ok(self): + query = "SELECT OBS_GetUSCensusMeasure('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'male population') as measure;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['measure'], None) + assert_equal(result['measure'], 6043.63061043) + + def test_if_get_us_census_measure_without_api_key_raise_error(self): + query = "SELECT OBS_GetUSCensusMeasure('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'male population');" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_get_us_census_category_is_ok(self): + query = "SELECT OBS_GetUSCensusCategory('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'Spielman-Singleton Segments: 10 Clusters') as category;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['category'], None) + assert_equal(result['category'], 'Low income, mix of minorities') + + def test_if_get_us_census_category_without_api_key_raise_error(self): + query = "SELECT OBS_GetUSCensusCategory('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'Spielman-Singleton Segments: 10 Clusters');" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_get_population_is_ok(self): + query = "SELECT OBS_GetPopulation(CDB_LatLng(40.704512, -73.936669)) as population;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['population'], None) + assert_equal(result['population'], 10923.0970489) + + def test_if_get_population_without_api_key_raise_error(self): + query = "SELECT OBS_GetPopulation(CDB_LatLng(40.704512, -73.936669));" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_search_is_ok(self): + query = "SELECT id FROM OBS_Search('total_pop') LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['id'], None) + assert_equal(result['id'], 'es.ine.total_pop') + + def test_if_obs_search_without_api_key_raise_error(self): + query = "SELECT id FROM OBS_Search('total_pop') LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_available_boundaries_is_ok(self): + query = "SELECT boundary_id FROM OBS_GetAvailableBoundaries(CDB_LatLng(40.704512, -73.936669)) LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['boundary_id'], None) + assert_equal(result['boundary_id'], 'us.census.tiger.place') + + def test_if_obs_get_available_boundaries_without_api_key_raise_error(self): + query = "SELECT boundary_id FROM OBS_GetAvailableBoundaries(CDB_LatLng(40.704512, -73.936669)) LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_boundary_is_ok(self): + query = "SELECT OBS_GetBoundary(CDB_LatLng(40.704512, -73.936669), 'us.census.tiger.census_tract') as boundary;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['boundary'], None) + assert_equal(result['boundary'], '0106000020E6100000010000000103000000010000003700000056EF703B347C52C054FF2092215B44401B9AB2D30F7C52C03FE1ECD6325B4440B14B546F0D7C52C0BBCE86FC335B4440730F09DFFB7B52C0B796C9703C5B4440108FC4CBD37B52C0B96C74CE4F5B444001C0B167CF7B52C0ED0BE8853B5B4440C843DFDDCA7B52C05DDDB1D8265B4440A73D25E7C47B52C0D53BDC0E0D5B4440BB5E9A22C07B52C0F8A3A833F75A4440355F251FBB7B52C0B64604E3E05A444008910C39B67B52C098BF42E6CA5A44405227A089B07B52C0F204C24EB15A444024F1F274AE7B52C069E4F38AA75A44402B4A09C1AA7B52C06B63EC84975A4440E199D024B17B52C0546F0D6C955A44403C873254C57B52C02EAC1BEF8E5A44402593533BC37B52C0588AE42B815A4440973AC8EBC17B52C087890629785A44407A6F0C01C07B52C0E1EB6B5D6A5A44401B9B1DA9BE7B52C03F6F2A52615A444088855AD3BC7B52C088669E5C535A4440E1EA0088BB7B52C0E6E95C514A5A44400CE6AF90B97B52C070D05E7D3C5A44401E85EB51B87B52C0B03A72A4335A4440BAF3C473B67B52C09929ADBF255A4440CD920035B57B52C0454AB3791C5A4440F78DAF3DB37B52C0E09BA6CF0E5A4440DBC2F352B17B52C0703FE081015A444015C440D7BE7B52C05E83BEF4F659444041446ADAC57B52C0EFDFBC38F15944405FB1868BDC7B52C0C03E3A75E559444034BC5983F77B52C0205ED72FD8594440EFFCA204FD7B52C07E384888F2594440CF2D7425027C52C0A86DC328085A444092AD2EA7047C52C08E75711B0D5A44407FDAA84E077C52C0E0675C38105A4440510FD1E80E7C52C0C4D32B65195A44400FECF82F107C52C0876D8B321B5A4440BB438A01127C52C0DE1CAED51E5A4440B9C15087157C52C034643C4A255A444099F221A81A7C52C0D0EFFB372F5A44404AED45B41D7C52C0785DBF60375A4440373465A71F7C52C065A71FD4455A4440C558A65F227C52C0D80DDB16655A4440F92EA52E197C52C09BA73AE4665A4440DEE522BE137C52C00664AF777F5A44405698BED7107C52C04759BF99985A444012D90759167C52C09430D3F6AF5A444044679945287C52C01F680586AC5A444049F086342A7C52C09CC3B5DAC35A44401FF5D72B2C7C52C0CB811E6ADB5A4440247EC51A2E7C52C0548B8862F25A4440FF59F3E32F7C52C0CB290131095B4440F96871C6307C52C09605137F145B444056EF703B347C52C054FF2092215B4440') + + def test_if_obs_get_boundary_without_api_key_raise_error(self): + query = "SELECT OBS_GetBoundary(CDB_LatLng(40.704512, -73.936669), 'us.census.tiger.census_tract') as boundary;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_boundary_id_is_ok(self): + query = "SELECT OBS_GetBoundaryId(CDB_LatLng(40.704512, -73.936669), 'us.census.tiger.census_tract', '2014') as boundary_id;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['boundary_id'], None) + assert_equal(result['boundary_id'], '36047048500') + + def test_if_obs_get_boundary_id_without_api_key_raise_error(self): + query = "SELECT OBS_GetBoundaryId(CDB_LatLng(40.704512, -73.936669), 'us.census.tiger.census_tract', '2014') as boundary_id;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_boundary_by_id_is_ok(self): + query = "SELECT OBS_GetBoundaryById('36047', 'us.census.tiger.county', '2014') as boundary;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['boundary'], None) + assert_equal(result['boundary'], '0106000020E610000001000000010300000001000000930200005051F52B9D8352C042B28009DC50444093C2BCC7998352C0E89E758D965144402EFD4B52998352C09A07B0C8AF514440E75086AA988352C022FAB5F5D351444027874F3A918352C0A46B26DF6C53444018E945ED7E8352C04D81CCCEA25344401346B3B27D8352C05D50DF32A753444068226C787A8352C08D25AC8DB153444015C8EC2C7A8352C004560E2DB2534440DF8618AF798352C00FD07D39B3534440FEB627486C8352C0DC9E20B1DD534440B98C9B1A688352C05D328E91EC5344408B8A389D648352C0929048DBF853444075CAA31B618352C0986A662D05544440EA758BC0588352C0D6C397892254444048DFA469508352C0151DC9E53F544440B67F65A5498352C0F73DEAAF575444401403249A408352C05E2A36E6755444402367614F3B8352C06DE2E47E8754444011FC6F253B8352C0431B800D885444403E7958A8358352C0DD0A6135965444401D739EB12F8352C093DFA293A5544440FB04508C2C8352C035289A07B05444401EA4A7C8218352C0347F4C6BD3544440D7C05609168352C05053CBD6FA544440AC8E1CE90C8352C0C9AA083719554440FC8D76DCF08252C0BD18CA897655444048895DDBDB8252C0C3B7B06EBC554440698995D1C88252C032207BBDFB55444004A73E90BC8252C0DB4C857824564440BC1FB75F3E8252C08F368E588B574440E15D2EE23B8252C066F4A3E194574440C614AC71368252C0381268B0A9574440CEA44DD53D8152C04F1F813FFC564440A51133FB3C8152C0F607CA6DFB56444070D05E7D3C8152C0CB0C1B65FD564440C5C6BC8E388152C0F303577902574440EA043411368152C03F390A1005574440840B7904378152C0D34ECDE506574440390A1005338152C047E350BF0B5744405D143DF0318152C0D53BDC0E0D5744401D59F965308152C00A4966F50E574440236420CF2E8152C00FD253E41057444084EE92382B8152C0AD2D3C2F15574440E23D0796238152C0A304FD851E574440B3EDB435228152C001D9EBDD1F5744401EBE4C14218152C08BDCD3D51D574440A2D0B2EE1F8152C0FC1BB4571F57444007B0C8AF1F8152C0CC9717601F574440F678211D1E8152C0374E0AF31E5744401A69A9BC1D8152C0793D98141F574440102384471B8152C0CB2F833122574440B7EEE6A90E8152C09F1D705D315744405968E7340B8152C02C0E677E355744400E4A9869FB8052C0C91EA166485744401B2C9CA4F98052C05C001AA54B5744401AF8510DFB8052C0C51A2E724F574440925CFE43FA8052C0309DD66D50574440BB9866BAD78052C0035DFB027A574440A04FE449D28052C02920ED7F80574440DC9BDF30D18052C0E8305F5E80574440B43C0FEECE8052C0D8614CFA7B5744404AEEB089CC8052C0950A2AAA7E5744409A5B21ACC68052C032FE7DC6855744406682E15CC38052C01EF7ADD689574440F78DAF3DB38052C020CD58349D5744402FFA0AD28C8052C00919C8B3CB574440D0251C7A8B8052C00EA2B5A2CD57444001DE02098A8052C030444E5FCF5744404A404CC2858052C0992A1895D45744403480B740828052C0A33CF372D857444028ECA2E8818052C0CD0358E4D7574440F3AACE6A818052C074ECA012D75744402920ED7F808052C0DFA293A5D657444036E84B6F7F8052C092054CE0D6574440AD4CF8A57E8052C0E55FCB2BD757444042CA4FAA7D8052C01AA19FA9D7574440A2EC2DE57C8052C0205ED72FD8574440BB6246787B8052C08BE07F2BD95744405C74B2D47A8052C025E7C41EDA5744405CA8FC6B798052C0F52EDE8FDB574440FF0758AB768052C09AAF928FDD574440A60A4625758052C0C442AD69DE574440A73E90BC738052C05E49F25CDF574440BF9A0304738052C046ED7E15E0574440A19BFD81728052C070B4E386DF5744403D0AD7A3708052C0D0F0660DDE574440680586AC6E8052C04D469561DC57444063963D096C8052C0965AEF37DA574440944E24986A8052C0BA641C23D957444059501894698052C014B01D8CD8574440E21FB6F4688052C0614D6551D85744401895D409688052C0205ED72FD85744406379573D608052C0A4A487A1D55744401878EE3D5C8052C041B5C189E85744402F4FE78A528052C0A580B4FF01584440983270404B8052C0EECEDA6D1758444050357A35408052C0E3C281902C58444086C43D963E8052C0DC9DB5DB2E584440C5E061DA378052C0BFF2203D455844409946938B318052C0C4E9245B5D5844407C478D09318052C040A374E95F584440E3A8DC442D8052C0F92AF9D85D584440919C4CDC2A8052C06BD26D895C584440276893C3278052C0E9279CDD5A58444053B131AF238052C061C092AB5858444055336B29208052C068E55E605658444091990B5C1E8052C082C64CA25E584440AA2688BA0F8052C027F6D03E56584440F488D1730B8052C0D21C59F9655844400C1CD0D2158052C0BB96900F7A584440C6A69542208052C0B77BB94F8E584440D3A23EC91D8052C02EC901BB9A584440B6BDDD921C8052C0BF42E6CAA058444082E49D43198052C036902E36AD58444072FBE593158052C0ACA92C0ABB5844402B4F20EC148052C0EC3026FDBD584440E4BCFF8F138052C04E266E15C4584440C26856B60F8052C06E15C440D7584440C404357C0B8052C00F5EBBB4E1584440397CD289048052C0CA87A06AF4584440FB761211FE7F52C090F7AA9509594440D93C0E83F97F52C03561FBC9185944402828452BF77F52C0F06DFAB31F594440F9BD4D7FF67F52C0DC9A745B225944403AADDBA0F67F52C0BE4D7FF62359444093C49272F77F52C0526342CC25594440450DA661F87F52C0798EC87729594440F2CCCB61F77F52C0067FBF982D5944409B030473F47F52C017821C94305944401E300F99F27F52C05609168733594440E57FF277EF7F52C0EDBAB72231594440A3AA09A2EE7F52C0EA1ED95C355944405D18E945ED7F52C0D3F6AFAC345944401C5DA5BBEB7F52C076DB85E63A5944404BADF71BED7F52C0B1D991EA3B5944401F477364E57F52C0E48409A35959444022179CC1DF7F52C001D8800871594440A4703D0AD77F52C02EC6C03A8E594440457F68E6C97F52C061C26856B659444070404B57B07F52C0FCDEA63FFB594440DC10E335AF7F52C048E00F3FFF59444055F7C8E6AA7F52C02DB4739A055A4440A4E2FF8EA87F52C00CFFE9060A5A44407E8AE3C0AB7F52C0EC4960730E5A444006F2ECF2AD7F52C08CD99255115A444042588D25AC7F52C09BA8A5B9155A44405A9A5B21AC7F52C0F4BF5C8B165A44406762BA10AB7F52C0A5BA8097195A4440E5B7E864A97F52C0B6BDDD921C5A44402B4A09C1AA7F52C0499F56D11F5A4440D48041D2A77F52C0177FDB13245A4440C22FF5F3A67F52C0D55B035B255A4440FE7BF0DAA57F52C0F8FD9B17275A44409A046F48A37F52C04FADBEBA2A5A444045F12A6B9B7F52C0AC1919E42E5A44404BE2AC889A7F52C0A75CE15D2E5A4440462575029A7F52C0965984622B5A4440E75086AA987F52C0906802452C5A44400B2769FE987F52C05FB01BB62D5A444004029D499B7F52C0DD2230D6375A44404301DBC1887F52C0CBF10A444F5A4440D6A88768747F52C0B81E85EB515A44407C0C569C6A7F52C0F6CFD380415A4440CB113290677F52C0A9328CBB415A44407905A227657F52C03D7C9928425A44407EA5F3E1597F52C0787AA52C435A444009F7CABC557F52C0A2410A9E425A44408D23D6E2537F52C00EF8FC30425A444029780AB9527F52C08B19E1ED415A44402992AF04527F52C08B19E1ED415A4440C51A2E724F7F52C08B19E1ED415A4440AC36FFAF3A7F52C01AA6B6D4415A444009522976347F52C0A2410A9E425A4440F25D4A5D327F52C0252026E1425A44408252B4722F7F52C05A61FA5E435A444032E202D0287F52C013B534B7425A4440E0BBCD1B277F52C014E97E4E415A44409352D0ED257F52C0151DC9E53F5A444022F94A20257F52C0B08BA2073E5A4440CF9ECBD4247F52C0F3AE7AC03C5A444077A1B94E237F52C0F3AE7AC03C5A4440DDB419A7217F52C097FBE428405A4440666A12BC217F52C016A243E0485A44408EACFC32187F52C0CD8DE9094B5A44404F05DCF3FC7E52C0B952CF82505A4440D2E0B6B6F07E52C0FFCA4A93525A44404F029B73F07E52C0A7E7DD58505A4440EA3C2AFEEF7E52C020B41EBE4C5A44404A5F0839EF7E52C01AF7E6374C5A4440D462F030ED7E52C055F5F23B4D5A4440825660C8EA7E52C0B5FD2B2B4D5A4440825660C8EA7E52C072DA53724E5A44403C2CD49AE67E52C030B77BB94F5A44400DDC813AE57E52C0D76B7A50505A4440670DDE57E57E52C0072461DF4E5A4440C77DAB75E27E52C0A25EF0694E5A4440ABB2EF8AE07E52C04F04711E4E5A44403A3FC571E07E52C03C65355D4F5A4440643A747ADE7E52C04ED026874F5A444077F35487DC7E52C08A027D224F5A4440F0A5F0A0D97E52C031EBC5504E5A444068588CBAD67E52C0D8D30E7F4D5A444046B3B27DC87E52C06FB9FAB1495A4440B85A272EC77E52C03C821B295B5A444039CE6DC2BD7E52C097016729595A44409A07B0C8AF7E52C07FD93D79585A44407E8AE3C0AB7E52C0EBC37AA3565A4440C1E10511A97E52C0D097DEFE5C5A44401B82E3326E7E52C03F170D198F5A44408A3C49BA667E52C0D619DF17975A444026DF6C73637E52C07A32FFE89B5A4440E78BBD175F7E52C000FE2955A25A4440594DD7135D7E52C040852348A55A4440E36A64575A7E52C03EE94482A95A4440E603029D497E52C067B62BF4C15A4440ED42739D467E52C04701A260C65A4440253ACB2C427E52C03E40F7E5CC5A4440D026874F3A7E52C061C5A9D6C25A44405C5837DE1D7E52C0868F8829915A4440162EABB0197E52C007B5DFDA895A4440B859BC58187E52C083A279008B5A44408FE046CA167E52C011FB04508C5A4440B131AF230E7E52C0D2C43BC0935A44401A4CC3F0117E52C0F0FACC599F5A44401A321EA5127E52C06631B1F9B85A44402B836A83137E52C0E55C8AABCA5A4440C9737D1F0E7E52C0B376DB85E65A4440D3687231067E52C07405DB88275B444009DE9046057E52C09A94826E2F5B4440158C4AEA047E52C08D7E349C325B4440C808A870047E52C0B6114F76335B4440634337FB037E52C00F290648345B4440DAA7E331037E52C03E7958A8355B444082902C60027E52C0DE3CD521375B4440AB5791D1017E52C048BF7D1D385B4440942F6821017E52C095287B4B395B4440268C6665FB7D52C0548A1D8D435B44405C1B2AC6F97D52C065187783685B4440FA0B3D62F47D52C03FE08101845B4440E2E313B2F37D52C03196E997885B444038F4160FEF7D52C05D50DF32A75B4440109546CCEC7D52C07FDB1324B65B44401C261AA4E07D52C0BA641C23D95B444076BF0AF0DD7D52C06AF7AB00DF5B4440DCB8C5FCDC7D52C0B06F2711E15B44405A0EF450DB7D52C0081F4AB4E45B444084D558C2DA7D52C0F57F0EF3E55B4440BBB20B06D77D52C06E693524EE5B4440CE6BEC12D57D52C0FB592C45F25B444073672618CE7D52C09A0645F3005C4440BB7B80EECB7D52C0C7BAB88D065C4440F5F411F8C37D52C057E9EE3A1B5C44407B8670CCB27D52C09AB4A9BA475C4440240B98C0AD7D52C0282A1BD6545C4440E4839ECDAA7D52C0FA5E43705C5C4440E4805D4D9E7D52C08AAA5FE97C5C44401B2AC6F99B7D52C01C2444F9825C4440D3122BA3917D52C059F8FA5A975C4440A7ACA6EB897D52C0FD2D01F8A75C444007B5DFDA897D52C04818062CB95C44401EF7ADD6897D52C0399A232BBF5C444036397CD2897D52C0904946CEC25C444001DE02098A7D52C08A58C4B0C35C4440CB68E4F38A7D52C0527B116DC75C4440AD4F39268B7D52C0AB92C83EC85C4440531EDD088B7D52C0EB19C231CB5C4440C5C551B9897D52C070EB6E9EEA5C444090847D3B897D52C02E5393E00D5D44409C4CDC2A887D52C01D39D219185D4440FC6EBA65877D52C00D87A5811F5D4440D9CC21A9857D52C0641F6459305D44402D7590D7837D52C0DB4FC6F8305D44409354A698837D52C03FE1ECD6325D44402D5BEB8B847D52C05CC64D0D345D44403A3DEFC6827D52C02C0E677E355D44405299620E827D52C0938C9C853D5D444011AAD4EC817D52C0CE8AA8893E5D44407689EAAD817D52C045BB0A293F5D444094A2957B817D52C02C5F97E13F5D4440EDED96E4807D52C060048D99445D44407C7A6CCB807D52C00551F701485D4440BE69FAEC807D52C0999A046F485D44401781B1BE817D52C0ECF483BA485D444028ECA2E8817D52C0F6D214014E5D44403480B740827D52C07024D060535D4440BD35B055827D52C0CEF8BEB8545D44401C3EE944827D52C03F389F3A565D4440FF243E77827D52C0B534B742585D44407B2C7DE8827D52C02AFD84B35B5D44406F7EC344837D52C0535C55F65D5D4440DA006C40847D52C041F163CC5D5D4440459DB987847D52C0CE15A584605D4440FDBCA948857D52C0F4A44C6A685D44408658FD11867D52C097A608707A5D44404FAF9465887D52C03EC91D36915D4440BD38F1D58E7D52C0CFF753E3A55D44406876DD5B917D52C0F1B6D26BB35D44405B7A34D5937D52C0E4F1B4FCC05D4440B6476FB88F7D52C0C0E78711C25D4440743E3C4B907D52C0A5BBEB6CC85D4440D190F128957D52C03A394371C75D4440ADA06989957D52C0512D228AC95D4440D74D29AF957D52C01BB80375CA5D4440307F85CC957D52C0E542E55FCB5D444042EA76F6957D52C049D40B3ECD5D444054556820967D52C0B3226AA2CF5D44408F6D1970967D52C0C189E8D7D65D4440AD6C1FF2967D52C0F71BEDB8E15D4440BED7101C977D52C0C8B4368DED5D4440D47D00529B7D52C0EBE1CB44115E44403F00A94D9C7D52C068774831405E4440F7393E5A9C7D52C04339D1AE425E44409831056B9C7D52C090A2CEDC435E4440984BAAB69B7D52C02384471B475E4440A547533D997D52C04ED026874F5E44403F170D198F7D52C00E661360585E4440545227A0897D52C0E202D0285D5E4440D3139678407D52C026A435069D5E44406C753925207D52C0CA54C1A8A45E44403B1BF2CF0C7D52C0E17CEA58A55E4440FD12F1D6F97C52C078962023A05E444068C9E369F97C52C0A81ABD1AA05E44406FBA6587F87C52C037A79201A05E44407008556AF67C52C0CC24EA059F5E44404CE141B3EB7C52C0F3FE3F4E985E444003CE52B29C7C52C06C239EEC665E44409AB33EE5987C52C020EEEA55645E4440DFC0E446917C52C0CF6394675E5E444014200A664C7C52C07F315BB22A5E44401D8D43FD2E7C52C0D71533C2DB5D4440C4758C2B2E7C52C09C4B7155D95D4440EE08A7052F7C52C0444B1E4FCB5D444091B6F1272A7C52C0A7069ACFB95D444014C95702297C52C0CC785BE9B55D4440807F4A95287C52C0567C43E1B35D44407405DB88277C52C0A0C4E74EB05D44400057B263237C52C07E39B35DA15D4440AC8BDB68007C52C0AB90F2936A5D444025E4839ECD7B52C0395E81E8495D444018265305A37B52C0C2DCEEE53E5D44402781CD39787B52C0685721E5275D4440514832AB777B52C0639AE95E275D4440F2599E07777B52C0EC6987BF265D4440F94A2025767B52C0B16B7BBB255D44409485AFAF757B52C088D860E1245D4440893F8A3A737B52C09622F94A205D44408D0C7217617B52C0BF5E61C1FD5C444026C286A7577B52C0D3DA34B6D75C4440FCDD3B6A4C7B52C0D0967329AE5C444030630AD6387B52C082C64CA25E5C444081E7DEC3257B52C0A33B889D295C4440639AE95E277B52C0D47FD6FCF85B44407EC34483147B52C03A394371C75B4440342A70B20D7B52C0D826158DB55B444099EFE0270E7B52C06762BA10AB5B4440D3F36E2C287B52C0350873BB975B4440D427B9C3267B52C07842AF3F895B4440C4245CC8237B52C030D7A205685B4440880CAB78237B52C08B8A389D645B4440902E36AD147B52C0718C648F505B4440AF928FDD057B52C05169C4CC3E5B44407E8978EBFC7A52C0FC1BB4571F5B44409DF0129CFA7A52C05D86FF74035B4440DCD8EC48F57A52C044A51133FB5A444027BD6F7CED7A52C0D769A4A5F25A44406B9C4D47007B52C0E4F4F57CCD5A4440F29881CAF87A52C095D233BDC45A44403F19E3C3EC7A52C05BEB8B84B65A44403468E89FE07A52C0DF14562AA85A4440E0F08288D47A52C0224F92AE995A44403448C153C87A52C0B8E34D7E8B5A44401155F833BC7A52C06C91B41B7D5A44401DE6CB0BB07A52C050C3B7B06E5A444029779FE3A37A52C0A568E55E605A44400584D6C3977A52C0889AE8F3515A44401215AA9B8B7A52C0DD3F16A2435A4440EE21E17B7F7A52C0C1711937355A4440B3EC4960737A52C0E692AAED265A4440D7BFEB33677A52C0CAC4AD82185A4440E350BF0B5B7A52C04EEE77280A5A4440CE18E6046D7A52C001FA7DFFE6594440DAA9B9DC607A52C0B5A7E49CD8594440B7B6F0BC547A52C0DAC87553CA594440DB899290487A52C0ED7E15E0BB594440CB0EF10F5B7A52C0239D819197594440A25EF0694E7A52C0B340BB438A594440BBEB6CC83F7A52C092E9D0E9795944407F68E6C9357A52C033C4B12E6E594440205D6C5A297A52C05DA27A6B605944401B834E081D7A52C065AA605452594440765089EB187A52C0A27895B54D5944402A357BA0157A52C07B4D0F0A4A5944408A5759DB147A52C0F2B1BB404959444097530262127A52C0D0436D1B465944409E5E29CB107A52C0ADA1D45E445944400A630B410E7A52C07F85CC9541594440DB12B9E00C7A52C00F46EC134059444000378B170B7A52C039419B1C3E5944408A20CEC3097A52C06AF981AB3C59444080423D7D047A52C0670C738236594440CAA48636007A52C034677DCA31594440BF44BC75FE7952C0A051BAF42F594440605628D2FD7952C077BE9F1A2F59444093AAED26F87952C0DF87838428594440CFF6E80DF77952C033164D672759444011346612F57952C07C2AA73D2559444001310917F27952C0E8482EFF21594440730CC85EEF7952C05567B5C01E594440984A3FE1EC7952C0B6D782DE1B5944404CE141B3EB7952C0570394861A594440C91CCBBBEA7952C00B9A9658195944408E1EBFB7E97952C08EACFC3218594440A794D74AE87952C08FE046CA165944409677D503E67952C0B41EBE4C145944402EC55565DF7952C0E2E995B20C5944408F52094FE87952C09DF0129CFA58444052EC681CEA7952C06326512FF8584440E02D90A0F87952C0739EB12FD9584440519E7939EC7952C05C8DEC4ACB584440938AC6DADF7952C0A5846055BD5844401666A19DD37952C07C08AA46AF58444029CE5147C77952C0B3942C27A1584440B2666490BB7952C0AEEE586C935844404E232D95B77952C0EDF0D7648D584440A4198BA6B37952C0FC6EBA65875844401E34BBEEAD7952C0179B560A81584440A297512CB77952C0289831056B5844400DE02D90A07952C0B3D0CE6916584440789961A3AC7952C0A6D1E4620C58444076FEEDB25F7952C015713AC956574440D50627A25F7952C06072A3C85A574440E7A562635E7952C0E08096AE6057444012876C205D7952C05AD2510E6657444072C3EFA65B7952C0C4EC65DB69574440FCC6D79E597952C0374D9F1D7057444051D7DAFB547952C0554FE61F7D574440658D7A88467952C04F1DAB949E57444008556AF6407952C04A7D59DAA95744406F9C14E63D7952C0A5811FD5B0574440A679C7293A7952C09CC0745AB757444061FBC9181F7952C097A608707A574440B0C91AF5107952C03483F8C08E5744402E36AD14027952C0718BF9B9A1574440D4997B48F87852C089D00836AE574440BBD23252EF7852C090BB085394574440EF8E8CD5E67852C01840F850A2574440EACE13CFD97852C0B6847CD0B35744408C48145AD67852C09012BBB6B7574440E690D442C97852C084B53176C257444063F030ED9B7852C090BA9D7DE5574440DFC0E446917852C0DEE2E13D075844403FFD67CD8F7852C0719010E50B5844401C2785798F7852C0764D486B0C584440B1BE81C98D7852C093FE5E0A0F58444037363B527D7852C0093543AA28584440C3D50110777852C09355116E32584440EEE714E4677852C03387A4164A584440717500C45D7852C07EA5F3E1595844407442E8A04B7852C0E108522976584440211CB3EC497852C0CE35CCD0785844405791D101497852C09D7DE5417A584440CB660E492D7852C0056A3178985844401AC1C6F5EF7752C0B9162D40DB5844400F7C0C569C7752C03EE8D9ACFA584440AC1E300F997752C0828AAA5FE9584440A661F888987752C0C2A38D23D6584440DCBC7152987752C042959A3DD0584440A661F888987752C0302AA913D0584440E7FF55478E7752C05DC2A1B7785844402FFA0AD28C7752C0581CCEFC6A584440DCB930D28B7752C021567F8461584440FB20CB82897752C062D7F6764B58444079909E22877752C0D89942E7355844408C63247B847752C0B58993FB1D584440ACE46377817752C0677E350708584440C6C210397D7752C0B2F4A10BEA57444074B680D07A7752C0909DB7B1D9574440DB317557767752C0077767EDB65744409A7631CD747752C02D7B12D89C5744400D6C9560717752C054FEB5BC72574440FC34EECD6F7752C0A3E6ABE4635744409E7AA4C16D7752C0D1949D7E50574440FE9C82FC6C7752C0E046CA16495744401E4FCB0F5C7752C09B53C90050574440D503E621537752C0E063B0E25457444037DC476E4D7752C032569BFF5757444070ED4449487752C0836C59BE2E57444066F50EB7437752C054C554FA0957444032022A1C417752C0713C9F01F55644404487C091407752C01F7EFE7BF05644406E4E2503407752C05D4C33DDEB56444088F546AD307752C03ECBF3E0EE5644401F0F7D772B7752C04835ECF7C4564440A33B889D297752C026AAB706B656444087A4164A267752C0938E72309B5644403B6F63B3237752C050FD834886564440D7F7E120217752C00D6C956071564440132A38BC207752C07A8A1C226E564440315D88D51F7752C07E8E8F1667564440D4F02DAC1B7752C0ADA415DF505644409E95B4E21B7752C09AE8F35146564440B88D06F0167752C0BB46CB811E564440A435069D107752C0C8E88024EC554440C9703C9F017752C0F01307D0EF55444083DE1B43007752C0855D143DF05544404EB4AB90F27652C0A69718CBF45544401ABE8575E37652C0C214E5D2F855444041649126DE7652C0FACE2F4AD0554440293C6876DD7652C0807D74EACA554440FAD170CADC7652C0779FE3A3C55544403FABCC94D67652C0F58079C8945544405AD76839D07652C0B41D537765554440849ECDAACF7652C0272D5C56615544405DA79196CA7652C0D87F9D9B36554440331477BCC97652C06A10E6762F55444060AB048BC37652C062F20698F95444402D23F59ECA7652C05D6919A9F754444011C30E63D27652C0B8E864A9F554444021C9ACDEE17652C073D87DC7F0544440F0F96184F07652C06FB72407EC5444408577B988EF7652C0DFA5D425E3544440A089B0E1E97652C0C8091346B35444403621AD31E87652C0999CDA19A6544440C763062AE37652C0EF3B86C77E5444401F4AB4E4F17652C0E0D4079277544440E2E65432007752C054E4107173544440FF0241800C7752C061FA5E437054444057B26323107752C0F677B6476F5444402026E1421E7752C00FEB8D5A61544440834F73F2227752C0E3361AC05B544440C2F693313E7752C0C05AB56B4254444097900F7A367752C0780C8FFD2C544440F834272F327752C06684B70721544440C4758C2B2E7752C03D0801F9125444408D959867257752C00E4A9869FB534440E68F696D1A7752C02FF99FFCDD53444022C2BF081A7752C0247F30F0DC534440EF1CCA50157752C03599F1B6D2534440C0B2D2A4147752C06551D845D15344409048DBF8137752C09509BFD4CF53444014419C87137752C0FB027AE1CE534440E5F04927127752C01A84B9DDCB53444092B06F27117752C0DAC87553CA5344407EA65EB7087752C0228C9FC6BD534440A3E4D539067752C065170CAEB9534440C2FA3F87F97652C059F5B9DA8A5344408BFA2477D87652C082A62556465344406403E962D37652C03197546D3753444018B49080D17652C0D5928E72305344404A22FB20CB7652C0765089EB185344402A1900AAB87652C0BE0F070951524440E386DF4DB77652C01F63EE5A425244400F7D772B4B7652C005A568E55E524440FB3F87F9F27552C07D224F92AE5144405793A7ACA67552C0D7C0560916514440BEDA519CA37552C0A44FABE80F514440745B22179C7552C0E2CCAFE600514440DCD6169E977552C00B43E4F4F5504440A93121E6927552C05E807D74EA504440D13FC1C58A7552C056ED9A90D6504440096B63EC847552C0AB92C83EC8504440AE80423D7D7552C04127840EBA50444040F7E5CC767552C0D0967329AE50444089CE328B507552C0162D40DB6A504440C8ED974F567552C05646239F57504440211FF46C567552C03674B33F5050444015713AC9567552C059DC7F643A5044404AB20E47577552C028B682A62550444037AB3E575B7552C0F7AE415F7A4F44408D261763607552C0226C787AA54E444045460724617552C0A94885B1854E4440F62686E4647552C02D978DCEF94D444036AE7FD7677552C018AE0E80B84D4440B9E00CFE7E7552C0B01F6283854D4440446B459BE37552C0C5E23785954C444012A27C410B7652C03C1405FA444C4440588B4F01307652C0B058C345EE4B4440A6457D923B7652C07C28D192C74B44402C9CA4F9637652C0A2957B81594B4440A81ABD1AA07652C0300C5872154B4440FBC8AD49B77652C035272F32014B44404127840EBA7652C02AE109BDFE4A44401DCBBBEA017752C02172FA7ABE4A4440130CE71A667752C0C6A2E9EC644A44400A4B3CA06C7752C0BEF8A23D5E4A4440A5D93C0E837752C06473D53C474A4440FDBCA948857752C06B98A1F1444A4440F0C000C2877752C0F0DE5163424A4440D8817346947752C04450357A354A4440BF28417FA17752C08099EFE0274A44400A2DEBFEB17752C0BCAE5FB01B4A44407FF8F9EFC17752C08C0DDDEC0F4A444053C90050C57752C0B14B546F0D4A44402E71E481C87752C0BF61A2410A4A44401EFB592C457852C09F39EB538E494440056D72F8A47852C06D8E739B7049444036AD1402B97852C0D68BA19C68494440F59F353FFE7852C0BAA0BE654E494440289A07B0C87952C0C58F31772D4944406133C005D97952C0D862B7CF2A494440E1783E03EA7952C04DDA54DD2349444046B3B27DC87A52C06A11514CDE4844402F185C73477B52C0FCE25295B6484440A26131EA5A7B52C06A696E85B04844408499B67F657B52C036902E36AD4844404F8F6D19707B52C0C1C760C5A94844402E1D739EB17B52C02BDCF29194484440F9122A38BC7B52C0B5132521914844401021AE9CBD7B52C080D250A39048444081CEA44DD57B52C0431B800D88484440BBB88D06F07B52C076A38FF980484440B5A50EF27A7C52C07780272D5C484440F7C77BD5CA7C52C08AE5965643484440614D6551D87C52C05CFDD8243F484440E84CDA54DD7C52C03F1878EE3D4844409947FE60E07C52C05774EB353D484440AF0793E2E37C52C0FF5C34643C48444065A54929E87C52C0C45E28603B484440EFAB72A1F27C52C01F12BEF737484440D07D39B35D7D52C0075F984C1548444025AB22DC647D52C03D0801F912484440C39E76F86B7D52C0861C5BCF104844401211FE45D07F52C0F2CEA10C55474440B804E09F528252C0785C548B884644407615527E528252C0DB85E63A8D464440E2E5E95C518252C0BB270F0BB546444089B48D3F518252C0A7203F1BB94644400858AB764D8252C0F294D5743D474440CD565EF23F8252C07D7555A0164944401B28F04E3E8252C0E9F010C64F494440AAB4C5353E8252C0BDC117265349444032CB9E04368252C0F6285C8FC24944405111A7936C8252C09FE238F06A4B44402252D32EA68252C0BC02D193324D44404C50C3B7B08252C0F9F36DC1524D444068075C57CC8252C0ECDCB419A74D4440A31F0DA7CC8252C086E3F90CA84D44409D2E8B89CD8252C0438CD7BCAA4D44402BA1BB24CE8252C00726378AAC4D4440DDE9CE13CF8252C035423F53AF4D4440A774B0FECF8252C0C266800BB24D4440A626C11BD28252C007431D56B84D4440EDD286C3D28252C0DC476E4DBA4D44402638F581E48252C04A5F0839EF4D444074779D0DF98252C0E3C281902C4E4440890629780A8352C016DC0F78604E44408315A75A0B8352C0E5EFDE51634E4440EA793716148352C036E84B6F7F4E44404703780B248352C0C24CDBBFB24E44403046240A2D8352C09BE09BA6CF4E4440A4C00298328352C02D776682E14E444055F833BC598352C09F91088D604F4440B3B27DC85B8352C08922A46E674F444075E789E76C8352C066118AADA04F44400D52F014728352C051F355F2B14F4440C5ABAC6D8A8352C0D4D00660035044403D7E6FD39F8352C05C1ABFF04A5044405051F52B9D8352C042B28009DC504440') + + def test_if_obs_get_boundary_by_id_without_api_key_raise_error(self): + query = "SELECT OBS_GetBoundaryById('36047', 'us.census.tiger.county', '2014') as boundary_id;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_boundaries_by_geometry_is_ok(self): + query = "SELECT geom_refs FROM OBS_GetBoundariesByGeometry(ST_MakeEnvelope(-73.9452409744,40.6988851644,-73.9280319214,40.7101254524,4326), 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['geom_refs'], None) + assert_equal(result['geom_refs'], '36047025700') + + def test_if_obs_get_boundaries_by_geometry_without_api_key_raise_error(self): + query = "SELECT geom_refs FROM OBS_GetBoundariesByGeometry(ST_MakeEnvelope(-73.9452409744,40.6988851644,-73.9280319214,40.7101254524,4326), 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_boundaries_by_point_and_radius_is_ok(self): + query = "SELECT geom_refs FROM OBS_GetBoundariesByPointAndRadius(CDB_LatLng(40.704512, -73.936669), 500, 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['geom_refs'], None) + assert_equal(result['geom_refs'], '36047038900') + + def test_if_obs_get_boundaries_by_point_and_radius_without_api_key_raise_error(self): + query = "SELECT geom_refs FROM OBS_GetBoundariesByPointAndRadius(CDB_LatLng(40.704512, -73.936669), 500, 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_points_by_geometry_is_ok(self): + query = "SELECT geom_refs FROM OBS_GetPointsByGeometry(ST_MakeEnvelope(-73.9452409744,40.6988851644,-73.9280319214,40.7101254524,4326), 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['geom_refs'], None) + assert_equal(result['geom_refs'], '36047025700') + + def test_if_obs_get_points_by_geometry_without_api_key_raise_error(self): + query = "SELECT geom_refs FROM OBS_GetPointsByGeometry(ST_MakeEnvelope(-73.9452409744,40.6988851644,-73.9280319214,40.7101254524,4326), 'us.census.tiger.census_tract') ORDER BY geom_refs ASC LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") + + def test_if_obs_get_points_by_point_and_radius_is_ok(self): + query = "SELECT geom_refs FROM OBS_GetPointsByPointAndRadius(CDB_LatLng(40.704512, -73.936669), 500, 'us.census.tiger.census_tract', '2014') ORDER BY geom_refs ASC LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) + result = IntegrationTestHelper.execute_query(self.sql_api_url, query) + assert_not_equal(result['geom_refs'], None) + assert_equal(result['geom_refs'], '36047038900') + + def test_if_obs_get_points_by_point_and_radius_without_api_key_raise_error(self): + query = "SELECT geom_refs FROM OBS_GetPointsByPointAndRadius(CDB_LatLng(40.704512, -73.936669), 500, 'us.census.tiger.census_tract', '2014') ORDER BY geom_refs ASC LIMIT 1;" + try: + IntegrationTestHelper.execute_query(self.sql_api_url, query) + except Exception as e: + assert_equal(e.message[0], "The api_key must be provided") +