diff --git a/NEWS.md b/NEWS.md index b787fc0..99b1d89 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +Mar 4th, 2021 +============= +* Version `0.31.0` of the client extension +* Version `0.40.0` of the server extension +* Version `0.24.0` of the Python library + * Remove Data Observatory + Jan 26th, 2021 ============== * Version `0.39.3` of the server extension diff --git a/README.md b/README.md index addad72..d196ff6 100644 --- a/README.md +++ b/README.md @@ -80,28 +80,6 @@ Steps to deploy a new Data Services API version : psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS cdb_geocoder; COMMIT" -e ``` -- [optional] install data observatory extension - - Make the extension available in postgresql to be installed - ``` - git clone https://github.com/CartoDB/observatory-extension.git - cd observatory - sudo make install - ``` - - This extension needs data, dumps are not available so we're going to use the test fixtures to make it work. Execute: - ``` - psql -U postgres -d dataservices_db -f src/pg/test/fixtures/load_fixtures.sql - ``` - - Give permission to execute and select to the `geocoder_api` user: - ``` - psql -U postgres -d dataservices_db -c "BEGIN;CREATE EXTENSION IF NOT EXISTS observatory VERSION 'dev'; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA cdb_observatory TO geocoder_api; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO geocoder_api; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT USAGE ON SCHEMA cdb_observatory TO geocoder_api; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT SELECT ON ALL TABLES IN SCHEMA observatory TO geocoder_api; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA observatory TO geocoder_api; COMMIT" -e - psql -U postgres -d dataservices_db -c "BEGIN;GRANT USAGE ON SCHEMA observatory TO geocoder_api; COMMIT" -e - ``` - ### Server configuration Configuration for the different services must be stored in the server database using `CDB_Conf_SetConf()`. @@ -190,15 +168,6 @@ SELECT CDB_Conf_SetConf( ); ``` -#### Data Observatory - -```sql -SELECT CDB_Conf_SetConf( - 'data_observatory_conf', - '{"connection": {"whitelist": [], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}}' -); -``` - #### Logger ```sql diff --git a/client/Makefile b/client/Makefile index 4322d9c..39978c2 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,7 +1,7 @@ # Makefile to generate the extension out of separate sql source files. # Once a version is released, it is not meant to be changed. E.g: once version 0.0.1 is out, it SHALL NOT be changed. EXTENSION = cdb_dataservices_client -EXTVERSION = 0.30.0 +EXTVERSION = 0.31.0 # The new version to be generated from templates SED ?= sed diff --git a/client/cdb_dataservices_client--0.30.0--0.31.0.sql b/client/cdb_dataservices_client--0.30.0--0.31.0.sql new file mode 100644 index 0000000..6d8354f --- /dev/null +++ b/client/cdb_dataservices_client--0.30.0--0.31.0.sql @@ -0,0 +1,187 @@ +--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.31.0'" to load this file. \quit + +-- Make sure we have a sane search path to create/update the extension +SET search_path = "$user",cartodb,public,cdb_dataservices_client; + +-- HERE goes your code to upgrade/downgrade + +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_get_demographic_snapshot(geom public.geometry(Geometry, 4326), time_span text, geometry_level text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_get_demographic_snapshot_exception_safe(geom public.geometry(Geometry, 4326), time_span text, geometry_level text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_get_segment_snapshot(geom public.geometry(Geometry, 4326), geometry_level text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_get_segment_snapshot_exception_safe(geom public.geometry(Geometry, 4326), geometry_level text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdemographicsnapshot(geom public.geometry(Geometry, 4326), time_span text, geometry_level text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot_exception_safe(geom public.geometry(Geometry, 4326), time_span text, geometry_level text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getsegmentsnapshot(geom public.geometry(Geometry, 4326), geometry_level text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot_exception_safe(geom public.geometry(Geometry, 4326), geometry_level text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundary(geom public.geometry(Geometry, 4326), boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundary_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundaryid(geom public.geometry(Geometry, 4326), boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundaryid_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundarybyid(geometry_id text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundarybyid_exception_safe(geometry_id text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbygeometry(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbypointandradius(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius_exception_safe(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbygeometry(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpointsbygeometry_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbypointandradius(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius_exception_safe(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeasure(geom public.Geometry, measure_id text, normalize text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeasure_exception_safe(geom public.Geometry, measure_id text, normalize text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeasurebyid(geom_ref text, measure_id text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeasurebyid_exception_safe(geom_ref text, measure_id text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdata(geomvals geomval[], params json, merge boolean) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdata_exception_safe(geomvals geomval[], params json, merge boolean ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdata(geomrefs text[], params json) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdata_exception_safe(geomrefs text[], params json ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeta(geom_ref public.Geometry(Geometry, 4326), params json, max_timespan_rank integer, max_score_rank integer, target_geoms integer) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeta_exception_safe(geom_ref public.Geometry(Geometry, 4326), params json, max_timespan_rank integer, max_score_rank integer, target_geoms integer ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_metadatavalidation(geom_extent public.Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_metadatavalidation_exception_safe(geom_extent public.Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getcategory(geom public.Geometry, category_id text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getcategory_exception_safe(geom public.Geometry, category_id text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensusmeasure(geom public.Geometry, name text, normalize text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getuscensusmeasure_exception_safe(geom public.Geometry, name text, normalize text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensuscategory(geom public.Geometry, name text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getuscensuscategory_exception_safe(geom public.Geometry, name text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpopulation(geom public.Geometry, normalize text, boundary_id text, time_span text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpopulation_exception_safe(geom public.Geometry, normalize text, boundary_id text, time_span text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_search(search_term text, relevant_boundary text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_search_exception_safe(search_term text, relevant_boundary text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailableboundaries(geom public.Geometry, timespan text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailableboundaries_exception_safe(geom public.Geometry, timespan text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_dumpversion() FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_dumpversion_exception_safe( ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailablenumerators(bounds public.geometry(Geometry, 4326), filter_tags text[], denom_id text, geom_id text, timespan text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailablenumerators_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], denom_id text, geom_id text, timespan text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getnumerators(bounds public.geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe(bounds public.geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailabledenominators(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, geom_id text, timespan text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailabledenominators_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, geom_id text, timespan text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailablegeometries(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, timespan text, number_geometries integer) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailablegeometries_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, timespan text, number_geometries integer ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailabletimespans(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, geom_id text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailabletimespans_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, geom_id text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client.obs_legacybuildermetadata(aggregate_type text) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._obs_legacybuildermetadata_exception_safe(aggregate_type text ) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure(output_table_name text, params json) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure(table_name text, output_table_name text, params json) FROM publicuser; +REVOKE EXECUTE ON FUNCTION cdb_dataservices_client._OBS_PreCheck(source_query text, params JSON) FROM publicuser; + +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_demographic_snapshot (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_segment_snapshot (geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getdemographicsnapshot (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getsegmentsnapshot (geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundary (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundaryid (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundarybyid (TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbygeometry (geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbypointandradius (geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbygeometry (geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbypointandradius (geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getmeasure (geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getmeasurebyid (TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getdata (geomval[], JSON, BOOLEAN); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getdata (TEXT[], JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getmeta (geometry(Geometry, 4326), JSON, INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_metadatavalidation (geometry(Geometry, 4326), TEXT, JSON, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getcategory (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensusmeasure (geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensuscategory (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpopulation (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_search (TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailableboundaries (geometry, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_dumpversion (); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailablenumerators (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getnumerators (geometry(Geometry, 4326), TEXT[], TEXT[], TEXT[], TEXT[], TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailabledenominators (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailablegeometries (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailabletimespans (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_legacybuildermetadata (TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure (TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure (TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client.__DST_PrepareTableOBS_GetMeasure (TEXT, TEXT, TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client.__DST_PopulateTableOBS_GetMeasure (TEXT, TEXT, TEXT, TEXT, TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_ConnectUserTable (TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_GetReturnMetadata (TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_FetchJoinFdwTableData (TEXT, TEXT, TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._DST_DisconnectUserTable (TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot_exception_safe (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot_exception_safe (geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdemographicsnapshot_exception_safe (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getsegmentsnapshot_exception_safe (geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundary_exception_safe (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundaryid_exception_safe (geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundarybyid_exception_safe (TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbygeometry_exception_safe (geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbypointandradius_exception_safe (geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbygeometry_exception_safe (geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbypointandradius_exception_safe (geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasure_exception_safe (geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasurebyid_exception_safe (TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdata_exception_safe (geomval[], JSON, BOOLEAN); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdata_exception_safe (TEXT[], JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeta_exception_safe (geometry(Geometry, 4326), JSON, INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_metadatavalidation_exception_safe (geometry(Geometry, 4326), TEXT, JSON, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getcategory_exception_safe (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensusmeasure_exception_safe (geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensuscategory_exception_safe (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpopulation_exception_safe (geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_search_exception_safe (TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailableboundaries_exception_safe (geometry, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_dumpversion_exception_safe (); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailablenumerators_exception_safe (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.__obs_getnumerators_exception_safe (geometry(Geometry, 4326), TEXT[], TEXT[], TEXT[], TEXT[], TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailabledenominators_exception_safe (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailablegeometries_exception_safe (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailabletimespans_exception_safe (geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_legacybuildermetadata_exception_safe (TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot (TEXT, TEXT, geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdemographicsnapshot (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getsegmentsnapshot (TEXT, TEXT, geometry(Geometry, 4326), TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundary (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundaryid (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundarybyid (TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbygeometry (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbypointandradius (TEXT, TEXT, geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbygeometry (TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbypointandradius (TEXT, TEXT, geometry(Geometry, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasure (TEXT, TEXT, geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasurebyid (TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdata (TEXT, TEXT, geomval[], JSON, BOOLEAN); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdata (TEXT, TEXT, TEXT[], JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeta (TEXT, TEXT, geometry(Geometry, 4326), JSON, INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_metadatavalidation (TEXT, TEXT, geometry(Geometry, 4326), TEXT, JSON, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getcategory (TEXT, TEXT, geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensusmeasure (TEXT, TEXT, geometry, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensuscategory (TEXT, TEXT, geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpopulation (TEXT, TEXT, geometry, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_search (TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailableboundaries (TEXT, TEXT, geometry, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_dumpversion (TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailablenumerators (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client.__obs_getnumerators (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT[], TEXT[], TEXT[], TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailabledenominators (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailablegeometries (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailabletimespans (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_legacybuildermetadata (TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_client._OBS_PreCheck (TEXT, JSON); + +DROP TYPE IF EXISTS cdb_dataservices_client.obs_meta_numerator; +DROP TYPE IF EXISTS cdb_dataservices_client.obs_meta_denominator; +DROP TYPE IF EXISTS cdb_dataservices_client.obs_meta_geometry; +DROP TYPE IF EXISTS cdb_dataservices_client.obs_meta_timespan; +DROP TYPE IF EXISTS cdb_dataservices_client.ds_fdw_metadata; +DROP TYPE IF EXISTS cdb_dataservices_client.ds_return_metadata; + +DELETE FROM pg_enum +WHERE enumlabel = 'observatory' +AND enumtypid = ( + SELECT pg_type.oid + FROM pg_type INNER JOIN pg_namespace ON (pg_type.typnamespace = pg_namespace.oid) + WHERE pg_type.typname = 'service_type' AND pg_namespace.nspname = 'cdb_dataservices_client' +); \ No newline at end of file diff --git a/client/cdb_dataservices_client--0.31.0--0.30.0.sql b/client/cdb_dataservices_client--0.31.0--0.30.0.sql new file mode 100644 index 0000000..b2f52a6 --- /dev/null +++ b/client/cdb_dataservices_client--0.31.0--0.30.0.sql @@ -0,0 +1,2724 @@ +--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.30.0'" to load this file. \quit + +-- Make sure we have a sane search path to create/update the extension +SET search_path = "$user",cartodb,public,cdb_dataservices_client; + +-- HERE goes your code to upgrade/downgrade + +CREATE TYPE cdb_dataservices_client.obs_meta_numerator AS (numer_id text, numer_name text, numer_description text, numer_weight text, numer_license text, numer_source text, numer_type text, numer_aggregate text, numer_extra jsonb, numer_tags jsonb, valid_denom boolean, valid_geom boolean, valid_timespan boolean); +CREATE TYPE cdb_dataservices_client.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean); +CREATE TYPE cdb_dataservices_client.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb); +CREATE TYPE cdb_dataservices_client.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb); + +ALTER TYPE cdb_dataservices_client.service_type ADD VALUE 'observatory' AFTER 'routing'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.obs_get_demographic_snapshot (geom public.geometry(Geometry, 4326) ,time_span text DEFAULT '2009 - 2013'::text ,geometry_level text DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_get_demographic_snapshot(username, orgname, geom, time_span, geometry_level) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_get_segment_snapshot (geom public.geometry(Geometry, 4326) ,geometry_level text DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_get_segment_snapshot(username, orgname, geom, geometry_level) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,time_span text DEFAULT NULL ,geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,radius numeric ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.geometry(Geometry, 4326) ,radius numeric ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,measure_id text ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getmeasurebyid (geom_ref text ,measure_id text ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getmeasurebyid(username, orgname, geom_ref, measure_id, boundary_id, time_span) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getdata (geomvals geomval[] ,params json ,merge boolean DEFAULT true) +RETURNS TABLE(id int, data json) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getdata(username, orgname, geomvals, params, merge); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getdata (geomrefs text[] ,params json) +RETURNS TABLE(id text, data json) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getdata(username, orgname, geomrefs, params); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getmeta (geom_ref public.Geometry(Geometry, 4326) ,params json ,max_timespan_rank integer DEFAULT NULL ,max_score_rank integer DEFAULT NULL ,target_geoms integer DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getmeta(username, orgname, geom_ref, params, max_timespan_rank, max_score_rank, target_geoms) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_metadatavalidation (geom_extent public.Geometry(Geometry, 4326) ,geom_type text ,params json ,target_geoms integer DEFAULT NULL) +RETURNS TABLE(valid boolean, errors text[]) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_metadatavalidation(username, orgname, geom_extent, geom_type, params, target_geoms); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,category_id text ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,name text ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,name text ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 public.Geometry ,timespan text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_dumpversion () +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_dumpversion(username, orgname) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getavailablenumerators (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,denom_id text DEFAULT NULL ,geom_id text DEFAULT NULL ,timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getavailablenumerators(username, orgname, bounds, filter_tags, denom_id, geom_id, timespan); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getnumerators (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,section_tags text[] DEFAULT ARRAY[]::TEXT[] ,subsection_tags text[] DEFAULT ARRAY[]::TEXT[] ,other_tags text[] DEFAULT ARRAY[]::TEXT[] ,ids text[] DEFAULT ARRAY[]::TEXT[] ,name text DEFAULT NULL ,denom_id text DEFAULT '' ,geom_id text DEFAULT '' ,timespan text DEFAULT '') +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + RETURN QUERY SELECT * FROM cdb_dataservices_client.__obs_getnumerators(username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getavailabledenominators (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,geom_id text DEFAULT NULL ,timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_denominator AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getavailabledenominators(username, orgname, bounds, filter_tags, numer_id, geom_id, timespan); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getavailablegeometries (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,denom_id text DEFAULT NULL ,timespan text DEFAULT NULL ,number_geometries integer DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_geometry AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getavailablegeometries(username, orgname, bounds, filter_tags, numer_id, denom_id, timespan, number_geometries); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_getavailabletimespans (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,denom_id text DEFAULT NULL ,geom_id text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_timespan AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_getavailabletimespans(username, orgname, bounds, filter_tags, numer_id, denom_id, geom_id); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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_legacybuildermetadata (aggregate_type text DEFAULT NULL) +RETURNS TABLE(name text, subsection json) AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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_legacybuildermetadata(username, orgname, aggregate_type); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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 TYPE cdb_dataservices_client.ds_fdw_metadata as (schemaname text, tabname text, servername text); +CREATE TYPE cdb_dataservices_client.ds_return_metadata as (colnames text[], coltypes text[]); + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure( + output_table_name text, + params json +) RETURNS boolean AS $$ +DECLARE + username text; + user_db_role text; + orgname text; + user_schema text; + result boolean; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + + SELECT session_user INTO user_db_role; + + SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument'; + END IF; + + IF orgname IS NULL OR orgname = '' OR orgname = '""' THEN + user_schema := 'public'; + ELSE + user_schema := username; + END IF; + + SELECT cdb_dataservices_client.__DST_PrepareTableOBS_GetMeasure( + username, + orgname, + user_db_role, + user_schema, + output_table_name, + params + ) INTO result; + + RETURN result; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER VOLATILE PARALLEL UNSAFE + SET search_path = pg_temp; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure( + table_name text, + output_table_name text, + params json +) RETURNS boolean AS $$ +DECLARE + username text; + user_db_role text; + orgname text; + dbname text; + user_schema text; + result boolean; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + + SELECT session_user INTO user_db_role; + + SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument'; + END IF; + + IF orgname IS NULL OR orgname = '' OR orgname = '""' THEN + user_schema := 'public'; + ELSE + user_schema := username; + END IF; + + SELECT current_database() INTO dbname; + + SELECT cdb_dataservices_client.__DST_PopulateTableOBS_GetMeasure( + username, + orgname, + user_db_role, + user_schema, + dbname, + table_name, + output_table_name, + params + ) INTO result; + + RETURN result; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER VOLATILE PARALLEL UNSAFE + SET search_path = pg_temp; + + + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__DST_PrepareTableOBS_GetMeasure( + username text, + orgname text, + user_db_role text, + user_schema text, + output_table_name text, + params json +) RETURNS boolean AS $$ + function_name = 'OBS_GetMeasure' + # Obtain return types for augmentation procedure + ds_return_metadata = plpy.execute("SELECT colnames, coltypes " + "FROM cdb_dataservices_client._DST_GetReturnMetadata({username}::text, {orgname}::text, {function_name}::text, {params}::json);" + .format( + username=plpy.quote_nullable(username), + orgname=plpy.quote_nullable(orgname), + function_name=plpy.quote_literal(function_name), + params=plpy.quote_literal(params) + ) + ) + if ds_return_metadata[0]["colnames"]: + colnames_arr = ds_return_metadata[0]["colnames"] + coltypes_arr = ds_return_metadata[0]["coltypes"] + else: + raise Exception('Error retrieving OBS_GetMeasure metadata') + + + # Prepare column and type strings required in the SQL queries + columns_with_types_arr = [colnames_arr[i] + ' ' + coltypes_arr[i] for i in range(0,len(colnames_arr))] + columns_with_types = ','.join(columns_with_types_arr) + + # Create a new table with the required columns + plpy.execute('CREATE TABLE "{schema}".{table_name} ( ' + 'cartodb_id int, the_geom public.geometry, {columns_with_types} ' + ');' + .format(schema=user_schema, table_name=output_table_name, columns_with_types=columns_with_types) + ) + + plpy.execute('ALTER TABLE "{schema}".{table_name} OWNER TO "{user}";' + .format(schema=user_schema, table_name=output_table_name, user=user_db_role) + ) + + return True +$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__DST_PopulateTableOBS_GetMeasure( + username text, + orgname text, + user_db_role text, + user_schema text, + dbname text, + table_name text, + output_table_name text, + params json +) RETURNS boolean AS $$ + function_name = 'OBS_GetMeasure' + # Obtain return types for augmentation procedure + ds_return_metadata = plpy.execute( + "SELECT colnames, coltypes " + "FROM cdb_dataservices_client._DST_GetReturnMetadata({username}::text, {orgname}::text, {function_name}::text, {params}::json);" .format( + username=plpy.quote_nullable(username), + orgname=plpy.quote_nullable(orgname), + function_name=plpy.quote_literal(function_name), + params=plpy.quote_literal(params))) + + if ds_return_metadata[0]["colnames"]: + colnames_arr = ds_return_metadata[0]["colnames"] + coltypes_arr = ds_return_metadata[0]["coltypes"] + else: + raise Exception('Error retrieving OBS_GetMeasure metadata') + + # Prepare column and type strings required in the SQL queries + columns_with_types_arr = [ + colnames_arr[i] + + ' ' + + coltypes_arr[i] for i in range( + 0, + len(colnames_arr))] + columns_with_types = ','.join(columns_with_types_arr) + aliased_colname_list = ','.join( + ['result.' + name for name in colnames_arr]) + + # Instruct the OBS server side to establish a FDW + # The metadata is obtained as well in order to: + # - (a) be able to write the query to grab the actual data to be executed in the remote server via pl/proxy, + # - (b) be able to tell OBS to free resources when done. + ds_fdw_metadata = plpy.execute( + "SELECT schemaname, tabname, servername " + "FROM cdb_dataservices_client._DST_ConnectUserTable({username}::text, {orgname}::text, {user_db_role}::text, " + "{schema}::text, {dbname}::text, {table_name}::text);" .format( + username=plpy.quote_nullable(username), + orgname=plpy.quote_nullable(orgname), + user_db_role=plpy.quote_literal(user_db_role), + schema=plpy.quote_literal(user_schema), + dbname=plpy.quote_literal(dbname), + table_name=plpy.quote_literal(table_name))) + + if ds_fdw_metadata[0]["schemaname"]: + server_schema = ds_fdw_metadata[0]["schemaname"] + server_table_name = ds_fdw_metadata[0]["tabname"] + server_name = ds_fdw_metadata[0]["servername"] + else: + raise Exception('Error connecting dataset via FDW') + + # Create a new table with the required columns + plpy.execute( + 'INSERT INTO "{schema}".{analysis_table_name} ' + 'SELECT ut.cartodb_id, ut.the_geom, {colname_list} ' + 'FROM "{schema}".{table_name} ut ' + 'LEFT JOIN cdb_dataservices_client._DST_FetchJoinFdwTableData({username}::text, {orgname}::text, {server_schema}::text, {server_table_name}::text, ' + '{function_name}::text, {params}::json) ' + 'AS result ({columns_with_types}, cartodb_id int) ' + 'ON result.cartodb_id = ut.cartodb_id;' .format( + schema=user_schema, + analysis_table_name=output_table_name, + colname_list=aliased_colname_list, + table_name=table_name, + username=plpy.quote_nullable(username), + orgname=plpy.quote_nullable(orgname), + server_schema=plpy.quote_literal(server_schema), + server_table_name=plpy.quote_literal(server_table_name), + function_name=plpy.quote_literal(function_name), + params=plpy.quote_literal(params), + columns_with_types=columns_with_types)) + + # Wipe user FDW data from the server + wiped = plpy.execute( + "SELECT cdb_dataservices_client._DST_DisconnectUserTable({username}::text, {orgname}::text, {server_schema}::text, " + "{server_table_name}::text, {fdw_server}::text)" .format( + username=plpy.quote_nullable(username), + orgname=plpy.quote_nullable(orgname), + server_schema=plpy.quote_literal(server_schema), + server_table_name=plpy.quote_literal(server_table_name), + fdw_server=plpy.quote_literal(server_name))) + + return True +$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_ConnectUserTable( + username text, + orgname text, + user_db_role text, + user_schema text, + dbname text, + table_name text +)RETURNS cdb_dataservices_client.ds_fdw_metadata AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + TARGET cdb_dataservices_server._DST_ConnectUserTable; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_GetReturnMetadata( + username text, + orgname text, + function_name text, + params json +) RETURNS cdb_dataservices_client.ds_return_metadata AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + TARGET cdb_dataservices_server._DST_GetReturnMetadata; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_FetchJoinFdwTableData( + username text, + orgname text, + table_schema text, + table_name text, + function_name text, + params json +) RETURNS SETOF record AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + TARGET cdb_dataservices_server._DST_FetchJoinFdwTableData; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_DisconnectUserTable( + username text, + orgname text, + table_schema text, + table_name text, + server_name text +) RETURNS boolean AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + TARGET cdb_dataservices_server._DST_DisconnectUserTable; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_get_demographic_snapshot_exception_safe (geom public.geometry(Geometry, 4326) ,time_span text DEFAULT '2009 - 2013'::text ,geometry_level text DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_get_demographic_snapshot(username, orgname, geom, time_span, geometry_level) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_get_segment_snapshot_exception_safe (geom public.geometry(Geometry, 4326) ,geometry_level text DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_get_segment_snapshot(username, orgname, geom, geometry_level) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot_exception_safe (geom public.geometry(Geometry, 4326) ,time_span text DEFAULT NULL ,geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getdemographicsnapshot(username, orgname, geom, time_span, geometry_level); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot_exception_safe (geom public.geometry(Geometry, 4326) ,geometry_level text DEFAULT NULL) +RETURNS SETOF JSON AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getsegmentsnapshot(username, orgname, geom, geometry_level); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundary_exception_safe (geom public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getboundary(username, orgname, geom, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundaryid_exception_safe (geom public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getboundaryid(username, orgname, geom, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundarybyid_exception_safe (geometry_id text ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getboundarybyid(username, orgname, geometry_id, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry_exception_safe (geom public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getboundariesbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius_exception_safe (geom public.geometry(Geometry, 4326) ,radius numeric ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getboundariesbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbygeometry_exception_safe (geom public.geometry(Geometry, 4326) ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getpointsbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius_exception_safe (geom public.geometry(Geometry, 4326) ,radius numeric ,boundary_id text ,time_span text DEFAULT NULL ,overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getpointsbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasure_exception_safe (geom public.Geometry ,measure_id text ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getmeasure(username, orgname, geom, measure_id, normalize, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasurebyid_exception_safe (geom_ref text ,measure_id text ,boundary_id text ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getmeasurebyid(username, orgname, geom_ref, measure_id, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdata_exception_safe (geomvals geomval[] ,params json ,merge boolean DEFAULT true) +RETURNS TABLE(id int, data json) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getdata(username, orgname, geomvals, params, merge); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdata_exception_safe (geomrefs text[] ,params json) +RETURNS TABLE(id text, data json) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getdata(username, orgname, geomrefs, params); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeta_exception_safe (geom_ref public.Geometry(Geometry, 4326) ,params json ,max_timespan_rank integer DEFAULT NULL ,max_score_rank integer DEFAULT NULL ,target_geoms integer DEFAULT NULL) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getmeta(username, orgname, geom_ref, params, max_timespan_rank, max_score_rank, target_geoms) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_metadatavalidation_exception_safe (geom_extent public.Geometry(Geometry, 4326) ,geom_type text ,params json ,target_geoms integer DEFAULT NULL) +RETURNS TABLE(valid boolean, errors text[]) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_metadatavalidation(username, orgname, geom_extent, geom_type, params, target_geoms); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getcategory_exception_safe (geom public.Geometry ,category_id text ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getcategory(username, orgname, geom, category_id, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensusmeasure_exception_safe (geom public.Geometry ,name text ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getuscensusmeasure(username, orgname, geom, name, normalize, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensuscategory_exception_safe (geom public.Geometry ,name text ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getuscensuscategory(username, orgname, geom, name, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpopulation_exception_safe (geom public.Geometry ,normalize text DEFAULT NULL ,boundary_id text DEFAULT NULL ,time_span text DEFAULT NULL) +RETURNS numeric AS $$ +DECLARE + ret numeric; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_getpopulation(username, orgname, geom, normalize, boundary_id, time_span) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_search_exception_safe (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; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_search(username, orgname, search_term, relevant_boundary); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailableboundaries_exception_safe (geom public.Geometry ,timespan text DEFAULT NULL) +RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getavailableboundaries(username, orgname, geom, timespan); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_dumpversion_exception_safe () +RETURNS text AS $$ +DECLARE + ret text; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._obs_dumpversion(username, orgname) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailablenumerators_exception_safe (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,denom_id text DEFAULT NULL ,geom_id text DEFAULT NULL ,timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getavailablenumerators(username, orgname, bounds, filter_tags, denom_id, geom_id, timespan); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,section_tags text[] DEFAULT ARRAY[]::TEXT[] ,subsection_tags text[] DEFAULT ARRAY[]::TEXT[] ,other_tags text[] DEFAULT ARRAY[]::TEXT[] ,ids text[] DEFAULT ARRAY[]::TEXT[] ,name text DEFAULT NULL ,denom_id text DEFAULT '' ,geom_id text DEFAULT '' ,timespan text DEFAULT '') +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client.__obs_getnumerators(username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailabledenominators_exception_safe (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,geom_id text DEFAULT NULL ,timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_denominator AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getavailabledenominators(username, orgname, bounds, filter_tags, numer_id, geom_id, timespan); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailablegeometries_exception_safe (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,denom_id text DEFAULT NULL ,timespan text DEFAULT NULL ,number_geometries integer DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_geometry AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getavailablegeometries(username, orgname, bounds, filter_tags, numer_id, denom_id, timespan, number_geometries); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailabletimespans_exception_safe (bounds public.geometry(Geometry, 4326) DEFAULT NULL ,filter_tags text[] DEFAULT NULL ,numer_id text DEFAULT NULL ,denom_id text DEFAULT NULL ,geom_id text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_timespan AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_getavailabletimespans(username, orgname, bounds, filter_tags, numer_id, denom_id, geom_id); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_legacybuildermetadata_exception_safe (aggregate_type text DEFAULT NULL) +RETURNS TABLE(name text, subsection json) AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'observatory' THEN + RAISE EXCEPTION 'Data Observatory permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._obs_legacybuildermetadata(username, orgname, aggregate_type); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_get_demographic_snapshot (username text, orgname text, geom public.geometry(Geometry, 4326), time_span text DEFAULT '2009 - 2013'::text, geometry_level text DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_get_demographic_snapshot (username, orgname, geom, time_span, geometry_level); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_get_segment_snapshot (username text, orgname text, geom public.geometry(Geometry, 4326), geometry_level text DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_get_segment_snapshot (username, orgname, geom, geometry_level); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot (username text, orgname text, geom public.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, orgname, geom, time_span, geometry_level); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot (username text, orgname text, geom public.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, orgname, geom, geometry_level); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundary (username text, orgname text, geom public.geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getboundary (username, orgname, geom, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundaryid (username text, orgname text, geom public.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, orgname, geom, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundarybyid (username text, orgname text, geometry_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getboundarybyid (username, orgname, geometry_id, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry (username text, orgname text, geom public.geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getboundariesbygeometry (username, orgname, geom, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius (username text, orgname text, geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getboundariesbypointandradius (username, orgname, geom, radius, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbygeometry (username text, orgname text, geom public.geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getpointsbygeometry (username, orgname, geom, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius (username text, orgname text, geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getpointsbypointandradius (username, orgname, geom, radius, boundary_id, time_span, overlap_type); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasure (username text, orgname text, geom public.Geometry, measure_id text, normalize text DEFAULT NULL, 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, orgname, geom, measure_id, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasurebyid (username text, orgname text, geom_ref text, measure_id text, boundary_id text, time_span text DEFAULT NULL) +RETURNS numeric AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getmeasurebyid (username, orgname, geom_ref, measure_id, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdata (username text, orgname text, geomvals geomval[], params json, merge boolean DEFAULT true) +RETURNS TABLE(id int, data json) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getdata (username, orgname, geomvals, params, merge); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdata (username text, orgname text, geomrefs text[], params json) +RETURNS TABLE(id text, data json) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getdata (username, orgname, geomrefs, params); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeta (username text, orgname text, geom_ref public.Geometry(Geometry, 4326), params json, max_timespan_rank integer DEFAULT NULL, max_score_rank integer DEFAULT NULL, target_geoms integer DEFAULT NULL) +RETURNS json AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_getmeta (username, orgname, geom_ref, params, max_timespan_rank, max_score_rank, target_geoms); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_metadatavalidation (username text, orgname text, geom_extent public.Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer DEFAULT NULL) +RETURNS TABLE(valid boolean, errors text[]) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_metadatavalidation (username, orgname, geom_extent, geom_type, params, target_geoms); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getcategory (username text, orgname text, geom public.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, orgname, geom, category_id, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensusmeasure (username text, orgname text, geom public.Geometry, name text, normalize text DEFAULT NULL, 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, orgname, geom, name, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensuscategory (username text, orgname text, geom public.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, orgname, geom, name, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpopulation (username text, orgname text, geom public.Geometry, normalize text DEFAULT NULL, 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, orgname, geom, normalize, boundary_id, time_span); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._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_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_search (username, orgname, search_term, relevant_boundary); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailableboundaries (username text, orgname text, geom public.Geometry, timespan 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, orgname, geom, timespan); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_dumpversion (username text, orgname text) +RETURNS text AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.obs_dumpversion (username, orgname); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailablenumerators (username text, orgname text, bounds public.geometry(Geometry, 4326) DEFAULT NULL, filter_tags text[] DEFAULT NULL, denom_id text DEFAULT NULL, geom_id text DEFAULT NULL, timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getavailablenumerators (username, orgname, bounds, filter_tags, denom_id, geom_id, timespan); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__obs_getnumerators (username text, orgname text, bounds public.geometry(Geometry, 4326) DEFAULT NULL, section_tags text[] DEFAULT ARRAY[]::TEXT[], subsection_tags text[] DEFAULT ARRAY[]::TEXT[], other_tags text[] DEFAULT ARRAY[]::TEXT[], ids text[] DEFAULT ARRAY[]::TEXT[], name text DEFAULT NULL, denom_id text DEFAULT '', geom_id text DEFAULT '', timespan text DEFAULT '') +RETURNS SETOF cdb_dataservices_client.obs_meta_numerator AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server._obs_getnumerators (username, orgname, bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailabledenominators (username text, orgname text, bounds public.geometry(Geometry, 4326) DEFAULT NULL, filter_tags text[] DEFAULT NULL, numer_id text DEFAULT NULL, geom_id text DEFAULT NULL, timespan text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_denominator AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getavailabledenominators (username, orgname, bounds, filter_tags, numer_id, geom_id, timespan); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailablegeometries (username text, orgname text, bounds public.geometry(Geometry, 4326) DEFAULT NULL, filter_tags text[] DEFAULT NULL, numer_id text DEFAULT NULL, denom_id text DEFAULT NULL, timespan text DEFAULT NULL, number_geometries integer DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getavailablegeometries (username, orgname, bounds, filter_tags, numer_id, denom_id, timespan, number_geometries); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailabletimespans (username text, orgname text, bounds public.geometry(Geometry, 4326) DEFAULT NULL, filter_tags text[] DEFAULT NULL, numer_id text DEFAULT NULL, denom_id text DEFAULT NULL, geom_id text DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.obs_meta_timespan AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_getavailabletimespans (username, orgname, bounds, filter_tags, numer_id, denom_id, geom_id); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_legacybuildermetadata (username text, orgname text, aggregate_type text DEFAULT NULL) +RETURNS TABLE(name text, subsection json) AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.obs_legacybuildermetadata (username, orgname, aggregate_type); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._OBS_PreCheck( + source_query text, + parameters json +) RETURNS boolean AS $$ +DECLARE + errors text[]; + validator_errors text[]; + validator_error text; + valid boolean; + geoms record; +BEGIN + errors := (ARRAY[])::TEXT[]; + FOR geoms IN EXECUTE format('SELECT ST_GeometryType(the_geom) as geom_type, + bool_and(st_isvalid(the_geom)) as valid, + avg(st_npoints(the_geom)) as avg_vertex, + ST_SetSRID(ST_Extent(the_geom), 4326) as extent, + count(*)::INT as numgeoms + FROM (%s) as _source + GROUP BY ST_GeometryType(the_geom)', source_query) + LOOP + IF geoms.geom_type NOT IN ('ST_Polygon', 'ST_MultiPolygon', 'ST_Point') THEN + errors := array_append(errors, format($data$'Geometry type %s not supported'$data$, geoms.geom_type)); + END IF; + + IF geoms.valid IS FALSE THEN + errors := array_append(errors, 'There are invalid geometries in the input data, please try to fix them'); + END IF; + + -- 1000 vertex for a geometry is a limit we have in the obs_getdata function. You can check here + -- https://github.com/CartoDB/observatory-extension/blob/1.6.0/src/pg/sql/41_observatory_augmentation.sql#L813 + IF geoms.avg_vertex > 1000 THEN + errors := array_append(errors, 'The average number of vertices per geometry is greater than 1000, please try to simplify them'); + END IF; + + -- OBS specific part + EXECUTE 'SELECT valid, errors + FROM cdb_dataservices_client.OBS_MetadataValidation($1, $2, $3, $4)' + INTO valid, validator_errors + USING geoms.extent, geoms.geom_type, parameters, geoms.numgeoms; + IF valid is FALSE THEN + FOR validator_error IN EXECUTE 'SELECT unnest($1)' USING validator_errors + LOOP + errors := array_append(errors, validator_error); + END LOOP; + END IF; + END LOOP; + + IF CARDINALITY(errors) > 0 THEN + RAISE EXCEPTION '%', errors; + END IF; + + RETURN TRUE; +END; +$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_get_demographic_snapshot(geom public.geometry(Geometry, 4326), time_span text, geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_get_demographic_snapshot_exception_safe(geom public.geometry(Geometry, 4326), time_span text, geometry_level text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_get_segment_snapshot(geom public.geometry(Geometry, 4326), geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_get_segment_snapshot_exception_safe(geom public.geometry(Geometry, 4326), geometry_level text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdemographicsnapshot(geom public.geometry(Geometry, 4326), time_span text, geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot_exception_safe(geom public.geometry(Geometry, 4326), time_span text, geometry_level text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getsegmentsnapshot(geom public.geometry(Geometry, 4326), geometry_level text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot_exception_safe(geom public.geometry(Geometry, 4326), geometry_level text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundary(geom public.geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundary_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundaryid(geom public.geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundaryid_exception_safe(geom public.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_getboundarybyid_exception_safe(geometry_id text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbygeometry(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbypointandradius(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius_exception_safe(geom public.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 public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpointsbygeometry_exception_safe(geom public.geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbypointandradius(geom public.geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius_exception_safe(geom public.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 public.Geometry, measure_id text, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeasure_exception_safe(geom public.Geometry, measure_id text, normalize text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeasurebyid(geom_ref text, measure_id text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeasurebyid_exception_safe(geom_ref text, measure_id text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdata(geomvals geomval[], params json, merge boolean) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdata_exception_safe(geomvals geomval[], params json, merge boolean ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdata(geomrefs text[], params json) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getdata_exception_safe(geomrefs text[], params json ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeta(geom_ref public.Geometry(Geometry, 4326), params json, max_timespan_rank integer, max_score_rank integer, target_geoms integer) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getmeta_exception_safe(geom_ref public.Geometry(Geometry, 4326), params json, max_timespan_rank integer, max_score_rank integer, target_geoms integer ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_metadatavalidation(geom_extent public.Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_metadatavalidation_exception_safe(geom_extent public.Geometry(Geometry, 4326), geom_type text, params json, target_geoms integer ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getcategory(geom public.Geometry, category_id text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getcategory_exception_safe(geom public.Geometry, category_id text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensusmeasure(geom public.Geometry, name text, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getuscensusmeasure_exception_safe(geom public.Geometry, name text, normalize text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensuscategory(geom public.Geometry, name text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getuscensuscategory_exception_safe(geom public.Geometry, name text, boundary_id text, time_span text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpopulation(geom public.Geometry, normalize text, boundary_id text, time_span text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getpopulation_exception_safe(geom public.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_search_exception_safe(search_term text, relevant_boundary text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailableboundaries(geom public.Geometry, timespan text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailableboundaries_exception_safe(geom public.Geometry, timespan text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_dumpversion() TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_dumpversion_exception_safe( ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailablenumerators(bounds public.geometry(Geometry, 4326), filter_tags text[], denom_id text, geom_id text, timespan text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailablenumerators_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], denom_id text, geom_id text, timespan text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getnumerators(bounds public.geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.__obs_getnumerators_exception_safe(bounds public.geometry(Geometry, 4326), section_tags text[], subsection_tags text[], other_tags text[], ids text[], name text, denom_id text, geom_id text, timespan text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailabledenominators(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, geom_id text, timespan text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailabledenominators_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, geom_id text, timespan text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailablegeometries(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, timespan text, number_geometries integer) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailablegeometries_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, timespan text, number_geometries integer ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailabletimespans(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, geom_id text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_getavailabletimespans_exception_safe(bounds public.geometry(Geometry, 4326), filter_tags text[], numer_id text, denom_id text, geom_id text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_legacybuildermetadata(aggregate_type text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._obs_legacybuildermetadata_exception_safe(aggregate_type text ) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure(output_table_name text, params json) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure(table_name text, output_table_name text, params json) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._OBS_PreCheck(source_query text, params JSON) TO publicuser; diff --git a/client/cdb_dataservices_client--0.31.0.sql b/client/cdb_dataservices_client--0.31.0.sql new file mode 100644 index 0000000..421984d --- /dev/null +++ b/client/cdb_dataservices_client--0.31.0.sql @@ -0,0 +1,3077 @@ +--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 "CREATE EXTENSION cdb_dataservices_client" to load this file. \quit + +-- Make sure we have a sane search path to create/update the extension +SET search_path = "$user",cartodb,public,cdb_dataservices_client; +-- Taken from https://wiki.postgresql.org/wiki/Count_estimate +CREATE FUNCTION cdb_dataservices_client.cdb_count_estimate(query text) RETURNS INTEGER AS +$func$ +DECLARE + rec record; + ROWS INTEGER; +BEGIN + FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP + ROWS := SUBSTRING(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)'); + EXIT WHEN ROWS IS NOT NULL; + END LOOP; + + RETURN ROWS; +END +$func$ LANGUAGE plpgsql; + +-- Taken from https://stackoverflow.com/a/48013356/351721 +CREATE OR REPLACE FUNCTION cdb_dataservices_client.cdb_jsonb_array_casttext(jsonb) RETURNS text[] AS $f$ + SELECT array_agg(x) || ARRAY[]::text[] FROM jsonb_array_elements_text($1) t(x); +$f$ LANGUAGE sql IMMUTABLE; +-- +-- Geocoder server connection config +-- +-- The purpose of this function is provide to the PL/Proxy functions +-- the connection string needed to connect with the server + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._server_conn_str() +RETURNS text AS $$ +DECLARE + db_connection_str text; +BEGIN + SELECT cartodb.cdb_conf_getconf('geocoder_server_config')->'connection_str' INTO db_connection_str; + SELECT trim(both '"' FROM db_connection_str) INTO db_connection_str; + RETURN db_connection_str; +END; +$$ LANGUAGE 'plpgsql' STABLE PARALLEL SAFE; +CREATE TYPE cdb_dataservices_client._entity_config AS ( + username text, + organization_name text, + apikey_permissions json +); + +-- +-- Get entity config function +-- +-- The purpose of this function is to retrieve the username and organization name from +-- a) schema where he/her is the owner in case is an organization user +-- b) entity_name from the cdb_conf database in case is a non organization user +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_entity_config() +RETURNS record AS $$ +DECLARE + result cdb_dataservices_client._entity_config; + apikey_config json; + is_organization boolean; + organization_name text DEFAULT NULL; +BEGIN + SELECT cartodb.cdb_conf_getconf('api_keys_'||session_user) INTO apikey_config; + + SELECT cartodb.cdb_conf_getconf('user_config')->'is_organization' INTO is_organization; + IF is_organization IS NULL THEN + RAISE EXCEPTION 'User must have user configuration in the config table'; + ELSIF is_organization = TRUE THEN + SELECT cartodb.cdb_conf_getconf('user_config')->>'entity_name' INTO organization_name; + END IF; + result.username = apikey_config->>'username'; + result.organization_name = organization_name; + result.apikey_permissions = apikey_config->'permissions'; + RETURN result; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL SAFE + SET search_path = pg_temp; + +CREATE TYPE cdb_dataservices_client.isoline AS ( + center geometry(Geometry,4326), + data_range integer, + the_geom geometry(Multipolygon,4326) +); + +CREATE TYPE cdb_dataservices_client.geocoding AS ( + cartodb_id integer, + the_geom geometry(Point,4326), + metadata jsonb +); + +CREATE TYPE cdb_dataservices_client.simple_route AS ( + shape geometry(LineString,4326), + length real, + duration integer +); + +-- For quotas and services configuration +CREATE TYPE cdb_dataservices_client.service_type AS ENUM ( + 'isolines', + 'hires_geocoder', + 'routing' +); + +CREATE TYPE cdb_dataservices_client.service_quota_info AS ( + service cdb_dataservices_client.service_type, + monthly_quota NUMERIC, + used_quota NUMERIC, + soft_limit BOOLEAN, + provider TEXT +); + +CREATE TYPE cdb_dataservices_client.service_quota_info_batch AS ( + service cdb_dataservices_client.service_type, + monthly_quota NUMERIC, + used_quota NUMERIC, + soft_limit BOOLEAN, + provider TEXT, + max_batch_size NUMERIC +); +-- +-- 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.cdb_geocode_admin0_polygon (country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_admin0_polygon(username, orgname, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_admin1_polygon (admin1_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_admin1_polygon(username, orgname, admin1_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_admin1_polygon (admin1_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_admin1_polygon(username, orgname, admin1_name, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_namedplace_point (city_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_namedplace_point(username, orgname, city_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_namedplace_point (city_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_namedplace_point(username, orgname, city_name, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_namedplace_point (city_name text ,admin1_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_namedplace_point(username, orgname, city_name, admin1_name, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_postalcode_polygon (postal_code text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_postalcode_polygon(username, orgname, postal_code, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_postalcode_polygon (postal_code double precision ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_postalcode_polygon(username, orgname, postal_code, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_postalcode_point (postal_code text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_postalcode_point(username, orgname, postal_code, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_postalcode_point (postal_code double precision ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_postalcode_point(username, orgname, postal_code, country_name) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_ipaddress_point (ip_address text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_ipaddress_point(username, orgname, ip_address) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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._cdb_bulk_geocode_street_point (searches jsonb) +RETURNS SETOF cdb_dataservices_client.geocoding AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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.__cdb_bulk_geocode_street_point(username, orgname, searches); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_here_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_here_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_google_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_google_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapbox_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapbox_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_tomtom_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_tomtom_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_geocodio_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_geocodio_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapzen_geocode_street_point (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapzen_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_isodistance (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_isodistance(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_isochrone (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_isochrone(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapbox_isochrone (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapbox_isochrone(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_tomtom_isochrone (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_tomtom_isochrone(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapzen_isochrone (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapzen_isochrone(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapbox_isodistance (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapbox_isodistance(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_tomtom_isodistance (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_tomtom_isodistance(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_mapzen_isodistance (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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._cdb_mapzen_isodistance(username, orgname, source, mode, range, options); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_route_point_to_point (origin public.geometry(Point, 4326) ,destination public.geometry(Point, 4326) ,mode text ,options text[] DEFAULT ARRAY[]::text[] ,units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ +DECLARE + ret cdb_dataservices_client.simple_route; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'routing' THEN + RAISE EXCEPTION 'Routing permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 * FROM cdb_dataservices_client._cdb_route_point_to_point(username, orgname, origin, destination, mode, options, units) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_route_with_waypoints (waypoints public.geometry(Point, 4326)[] ,mode text ,options text[] DEFAULT ARRAY[]::text[] ,units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ +DECLARE + ret cdb_dataservices_client.simple_route; + username text; + orgname text; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'routing' THEN + RAISE EXCEPTION 'Routing permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_quota_info () +RETURNS SETOF service_quota_info AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- 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._cdb_service_quota_info(username, orgname); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_quota_info_batch () +RETURNS SETOF service_quota_info_batch AS $$ +DECLARE + + username text; + orgname text; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- 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._cdb_service_quota_info_batch(username, orgname); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_enough_quota (service TEXT ,input_size NUMERIC) +RETURNS BOOLEAN AS $$ +DECLARE + ret BOOLEAN; + username text; + orgname text; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- 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._cdb_enough_quota(username, orgname, service, input_size) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_get_rate_limit (service text) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- 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._cdb_service_get_rate_limit(username, orgname, service) INTO ret; RETURN ret; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_set_user_rate_limit (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + +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, p json); + -- 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; + + PERFORM cdb_dataservices_client._cdb_service_set_user_rate_limit(username, orgname, service, rate_limit); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_set_org_rate_limit (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + +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, p json); + -- 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; + + PERFORM cdb_dataservices_client._cdb_service_set_org_rate_limit(username, orgname, service, rate_limit); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- 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.cdb_service_set_server_rate_limit (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + +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, p json); + -- 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; + + PERFORM cdb_dataservices_client._cdb_service_set_server_rate_limit(username, orgname, service, rate_limit); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +CREATE OR REPLACE FUNCTION cdb_dataservices_client.cdb_bulk_geocode_street_point (query text, + street_column text, city_column text default null, state_column text default null, country_column text default null, batch_size integer DEFAULT NULL) +RETURNS SETOF cdb_dataservices_client.geocoding AS $$ +DECLARE + query_row_count integer; + enough_quota boolean; + remaining_quota integer; + max_batch_size integer; + + cartodb_id_batch integer; + batches_n integer; + DEFAULT_BATCH_SIZE CONSTANT numeric := 100; + MAX_SAFE_BATCH_SIZE CONSTANT numeric := 5000; + + temp_table_name text; + username text; + orgname text; + apikey_permissions json; +BEGIN + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied' USING ERRCODE = '01007'; + END IF; + + -- 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 csqi.monthly_quota - csqi.used_quota AS remaining_quota, csqi.max_batch_size + INTO remaining_quota, max_batch_size + FROM cdb_dataservices_client.cdb_service_quota_info_batch() csqi + WHERE service = 'hires_geocoder'; + RAISE DEBUG 'remaining_quota: %; max_batch_size: %', remaining_quota, max_batch_size; + + IF batch_size IS NULL THEN + batch_size := max_batch_size; + ELSIF batch_size > max_batch_size THEN + RAISE EXCEPTION 'batch_size must be lower than %', max_batch_size + 1; + END IF; + + IF batch_size > MAX_SAFE_BATCH_SIZE THEN + batch_size := MAX_SAFE_BATCH_SIZE; + END IF; + + EXECUTE format('SELECT count(1), ceil(count(1)::float/%s) FROM (%s) _x', batch_size, query) + INTO query_row_count, batches_n; + + RAISE DEBUG 'cdb_bulk_geocode_street_point --> query_row_count: %; query: %; country: %; state: %; city: %; street: %', + query_row_count, query, country_column, state_column, city_column, street_column; + SELECT cdb_dataservices_client.cdb_enough_quota('hires_geocoder', query_row_count) INTO enough_quota; + IF enough_quota IS NULL OR NOT enough_quota THEN + RAISE EXCEPTION 'Remaining quota: %. Estimated cost: %', remaining_quota, query_row_count; + END IF; + + RAISE DEBUG 'batches_n: %', batches_n; + + temp_table_name := 'bulk_geocode_street_' || md5(random()::text); + + EXECUTE format('CREATE TEMPORARY TABLE %s ' || + '(cartodb_id integer, the_geom public.geometry(Point,4326), metadata jsonb)', + temp_table_name); + + select + coalesce(street_column, ''''''), coalesce(city_column, ''''''), + coalesce(state_column, ''''''), coalesce(country_column, '''''') + into street_column, city_column, state_column, country_column; + + IF batches_n > 0 THEN + FOR cartodb_id_batch in 0..(batches_n - 1) + LOOP + EXECUTE format( + 'WITH geocoding_data as (' || + ' SELECT ' || + ' json_build_object(''id'', cartodb_id, ''address'', %s, ''city'', %s, ''state'', %s, ''country'', %s) as data , ' || + ' floor((row_number() over () - 1)::float/$1) as batch' || + ' FROM (%s) _x' || + ') ' || + 'INSERT INTO %s SELECT (cdb_dataservices_client._cdb_bulk_geocode_street_point(jsonb_agg(data))).* ' || + 'FROM geocoding_data ' || + 'WHERE batch = $2', street_column, city_column, state_column, country_column, query, temp_table_name) + USING batch_size, cartodb_id_batch; + + END LOOP; + END IF; + + RETURN QUERY EXECUTE 'SELECT * FROM ' || quote_ident(temp_table_name); +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER VOLATILE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin0_polygon_exception_safe (country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_admin0_polygon(username, orgname, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon_exception_safe (admin1_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_admin1_polygon(username, orgname, admin1_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon_exception_safe (admin1_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_admin1_polygon(username, orgname, admin1_name, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe (city_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_namedplace_point(username, orgname, city_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe (city_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_namedplace_point(username, orgname, city_name, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe (city_name text ,admin1_name text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_namedplace_point(username, orgname, city_name, admin1_name, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon_exception_safe (postal_code text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_postalcode_polygon(username, orgname, postal_code, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon_exception_safe (postal_code double precision ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_postalcode_polygon(username, orgname, postal_code, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point_exception_safe (postal_code text ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_postalcode_point(username, orgname, postal_code, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point_exception_safe (postal_code double precision ,country_name text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_postalcode_point(username, orgname, postal_code, country_name) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_ipaddress_point_exception_safe (ip_address text) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_ipaddress_point(username, orgname, ip_address) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__cdb_bulk_geocode_street_point_exception_safe (searches jsonb) +RETURNS SETOF cdb_dataservices_client.geocoding AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client.__cdb_bulk_geocode_street_point(username, orgname, searches); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_here_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_here_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_google_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_google_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_mapbox_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_tomtom_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocodio_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_geocodio_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_geocode_street_point_exception_safe (searchtext text ,city text DEFAULT NULL ,state_province text DEFAULT NULL ,country text DEFAULT NULL) +RETURNS public.Geometry AS $$ +DECLARE + ret public.Geometry; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'geocoding' THEN + RAISE EXCEPTION 'Geocoding permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_mapzen_geocode_street_point(username, orgname, searchtext, city, state_province, country) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_isodistance_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_isodistance(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_isochrone_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_isochrone(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_isochrone_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_mapbox_isochrone(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_isochrone_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_tomtom_isochrone(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_isochrone_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_mapzen_isochrone(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_isodistance_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_mapbox_isodistance(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_isodistance_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_tomtom_isodistance(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_isodistance_exception_safe (source public.geometry(Geometry, 4326) ,mode text ,range integer[] ,options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'isolines' THEN + RAISE EXCEPTION 'Isolines permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_mapzen_isodistance(username, orgname, source, mode, range, options); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_route_point_to_point_exception_safe (origin public.geometry(Point, 4326) ,destination public.geometry(Point, 4326) ,mode text ,options text[] DEFAULT ARRAY[]::text[] ,units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ +DECLARE + ret cdb_dataservices_client.simple_route; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'routing' THEN + RAISE EXCEPTION 'Routing permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT * FROM cdb_dataservices_client._cdb_route_point_to_point(username, orgname, origin, destination, mode, options, units) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_route_with_waypoints_exception_safe (waypoints public.geometry(Point, 4326)[] ,mode text ,options text[] DEFAULT ARRAY[]::text[] ,units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ +DECLARE + ret cdb_dataservices_client.simple_route; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + IF apikey_permissions IS NULL OR NOT apikey_permissions::jsonb ? 'routing' THEN + RAISE EXCEPTION 'Routing permission denied'; + END IF; + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_quota_info_exception_safe () +RETURNS SETOF service_quota_info AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_service_quota_info(username, orgname); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_quota_info_batch_exception_safe () +RETURNS SETOF service_quota_info_batch AS $$ +DECLARE + + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + RETURN QUERY SELECT * FROM cdb_dataservices_client._cdb_service_quota_info_batch(username, orgname); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_enough_quota_exception_safe (service TEXT ,input_size NUMERIC) +RETURNS BOOLEAN AS $$ +DECLARE + ret BOOLEAN; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_enough_quota(username, orgname, service, input_size) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_get_rate_limit_exception_safe (service text) +RETURNS json AS $$ +DECLARE + ret json; + username text; + orgname text; + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + apikey_permissions json; +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o, p INTO username, orgname, apikey_permissions FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + + + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + SELECT cdb_dataservices_client._cdb_service_get_rate_limit(username, orgname, service) INTO ret; RETURN ret; + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + RETURN ret; + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_user_rate_limit_exception_safe (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + PERFORM cdb_dataservices_client._cdb_service_set_user_rate_limit(username, orgname, service, rate_limit); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_org_rate_limit_exception_safe (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + PERFORM cdb_dataservices_client._cdb_service_set_org_rate_limit(username, orgname, service, rate_limit); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +-- +-- Exception-safe private DataServices API function +-- + +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_server_rate_limit_exception_safe (username text ,orgname text ,service text ,rate_limit json) +RETURNS void AS $$ +DECLARE + + + _returned_sqlstate TEXT; + _message_text TEXT; + _pg_exception_context TEXT; + +BEGIN + IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN + RAISE EXCEPTION 'The api_key must be provided'; + END IF; + SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); + -- JSON value stored "" is taken as literal + IF username IS NULL OR username = '' OR username = '""' THEN + RAISE EXCEPTION 'Username is a mandatory argument, check it out'; + END IF; + + + BEGIN + PERFORM cdb_dataservices_client._cdb_service_set_server_rate_limit(username, orgname, service, rate_limit); + EXCEPTION + WHEN OTHERS THEN + GET STACKED DIAGNOSTICS _returned_sqlstate = RETURNED_SQLSTATE, + _message_text = MESSAGE_TEXT, + _pg_exception_context = PG_EXCEPTION_CONTEXT; + RAISE WARNING USING ERRCODE = _returned_sqlstate, MESSAGE = _message_text, DETAIL = _pg_exception_context; + + END; +END; +$$ LANGUAGE 'plpgsql' SECURITY DEFINER STABLE PARALLEL UNSAFE + SET search_path = pg_temp; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_admin0_polygon (username text, orgname text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin0_polygon (username text, orgname text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_admin0_polygon (username, orgname, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_admin1_polygon (username text, orgname text, admin1_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon (username text, orgname text, admin1_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_admin1_polygon (username, orgname, admin1_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_admin1_polygon (username text, orgname text, admin1_name text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon (username text, orgname text, admin1_name text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_admin1_polygon (username, orgname, admin1_name, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_namedplace_point (username, orgname, city_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_namedplace_point (username, orgname, city_name, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text, admin1_name text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point (username text, orgname text, city_name text, admin1_name text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_namedplace_point (username, orgname, city_name, admin1_name, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_postalcode_polygon (username text, orgname text, postal_code text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon (username text, orgname text, postal_code text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_postalcode_polygon (username, orgname, postal_code, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_postalcode_polygon (username text, orgname text, postal_code double precision, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon (username text, orgname text, postal_code double precision, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_postalcode_polygon (username, orgname, postal_code, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_postalcode_point (username text, orgname text, postal_code text, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point (username text, orgname text, postal_code text, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_postalcode_point (username, orgname, postal_code, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_postalcode_point (username text, orgname text, postal_code double precision, country_name text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point (username text, orgname text, postal_code double precision, country_name text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_postalcode_point (username, orgname, postal_code, country_name); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_ipaddress_point (username text, orgname text, ip_address text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_ipaddress_point (username text, orgname text, ip_address text) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_ipaddress_point (username, orgname, ip_address); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client.__cdb_bulk_geocode_street_point (username text, orgname text, searches jsonb); +CREATE OR REPLACE FUNCTION cdb_dataservices_client.__cdb_bulk_geocode_street_point (username text, orgname text, searches jsonb) +RETURNS SETOF cdb_dataservices_client.geocoding AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server._cdb_bulk_geocode_street_point (username, orgname, searches); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_here_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_here_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_here_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_google_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_google_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_google_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapbox_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_mapbox_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_tomtom_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_tomtom_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_geocodio_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_geocodio_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_geocodio_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapzen_geocode_street_point (username text, orgname text, searchtext text, city text, state_province text, country text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_geocode_street_point (username text, orgname text, searchtext text, city text DEFAULT NULL, state_province text DEFAULT NULL, country text DEFAULT NULL) +RETURNS public.Geometry AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_mapzen_geocode_street_point (username, orgname, searchtext, city, state_province, country); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_isodistance (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_isochrone (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapbox_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_mapbox_isochrone (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_tomtom_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_tomtom_isochrone (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapzen_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_isochrone (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_mapzen_isochrone (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapbox_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapbox_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_mapbox_isodistance (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_tomtom_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_tomtom_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_tomtom_isodistance (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_mapzen_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[]); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_mapzen_isodistance (username text, orgname text, source public.geometry(Geometry, 4326), mode text, range integer[], options text[] DEFAULT ARRAY[]::text[]) +RETURNS SETOF cdb_dataservices_client.isoline AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_mapzen_isodistance (username, orgname, source, mode, range, options); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_route_point_to_point (username text, orgname text, origin public.geometry(Point, 4326), destination public.geometry(Point, 4326), mode text, options text[], units text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_route_point_to_point (username text, orgname text, origin public.geometry(Point, 4326), destination public.geometry(Point, 4326), mode text, options text[] DEFAULT ARRAY[]::text[], units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_route_point_to_point (username, orgname, origin, destination, mode, options, units); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_route_with_waypoints (username text, orgname text, waypoints public.geometry(Point, 4326)[], mode text, options text[], units text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_route_with_waypoints (username text, orgname text, waypoints public.geometry(Point, 4326)[], mode text, options text[] DEFAULT ARRAY[]::text[], units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_client.simple_route AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_route_with_waypoints (username, orgname, waypoints, mode, options, units); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_quota_info (username text, orgname text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_quota_info (username text, orgname text) +RETURNS SETOF service_quota_info AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_service_quota_info (username, orgname); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_quota_info_batch (username text, orgname text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_quota_info_batch (username text, orgname text) +RETURNS SETOF service_quota_info_batch AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT * FROM cdb_dataservices_server.cdb_service_quota_info_batch (username, orgname); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_enough_quota (username text, orgname text, service TEXT, input_size NUMERIC); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_enough_quota (username text, orgname text, service TEXT, input_size NUMERIC) +RETURNS BOOLEAN AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_enough_quota (username, orgname, service, input_size); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_get_rate_limit (username text, orgname text, service text); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_get_rate_limit (username text, orgname text, service text) +RETURNS json AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_service_get_rate_limit (username, orgname, service); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_set_user_rate_limit (username text, orgname text, service text, rate_limit json); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_user_rate_limit (username text, orgname text, service text, rate_limit json) +RETURNS void AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_service_set_user_rate_limit (username, orgname, service, rate_limit); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_set_org_rate_limit (username text, orgname text, service text, rate_limit json); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_org_rate_limit (username text, orgname text, service text, rate_limit json) +RETURNS void AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_service_set_org_rate_limit (username, orgname, service, rate_limit); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_service_set_server_rate_limit (username text, orgname text, service text, rate_limit json); +CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_service_set_server_rate_limit (username text, orgname text, service text, rate_limit json) +RETURNS void AS $$ + CONNECT cdb_dataservices_client._server_conn_str(); + + SELECT cdb_dataservices_server.cdb_service_set_server_rate_limit (username, orgname, service, rate_limit); + +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +-- Make sure by default there are no permissions for publicuser +-- NOTE: this happens at extension creation time, as part of an implicit transaction. +REVOKE ALL PRIVILEGES ON SCHEMA cdb_dataservices_client FROM PUBLIC, publicuser CASCADE; + +-- Grant permissions on the schema to publicuser (but just the schema) +GRANT USAGE ON SCHEMA cdb_dataservices_client TO publicuser; + +-- Revoke execute permissions on all functions in the schema by default +REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_dataservices_client FROM PUBLIC, publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_admin0_polygon(country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_admin0_polygon_exception_safe(country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_admin1_polygon(admin1_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon_exception_safe(admin1_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_admin1_polygon(admin1_name text, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_admin1_polygon_exception_safe(admin1_name text, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_namedplace_point(city_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe(city_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_namedplace_point(city_name text, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe(city_name text, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_namedplace_point(city_name text, admin1_name text, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_namedplace_point_exception_safe(city_name text, admin1_name text, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_postalcode_polygon(postal_code text, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon_exception_safe(postal_code text, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_postalcode_polygon(postal_code double precision, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_polygon_exception_safe(postal_code double precision, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_postalcode_point(postal_code text, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point_exception_safe(postal_code text, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_postalcode_point(postal_code double precision, country_name text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_postalcode_point_exception_safe(postal_code double precision, country_name text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_ipaddress_point(ip_address text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_ipaddress_point_exception_safe(ip_address text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_bulk_geocode_street_point(searches jsonb) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.__cdb_bulk_geocode_street_point_exception_safe(searches jsonb ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_here_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_here_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_google_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_google_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapbox_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapbox_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_tomtom_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_tomtom_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_geocodio_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_geocodio_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapzen_geocode_street_point(searchtext text, city text, state_province text, country text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapzen_geocode_street_point_exception_safe(searchtext text, city text, state_province text, country text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_isodistance(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_isodistance_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_isochrone(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_isochrone_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapbox_isochrone(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapbox_isochrone_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_tomtom_isochrone(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_tomtom_isochrone_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapzen_isochrone(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapzen_isochrone_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapbox_isodistance(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapbox_isodistance_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_tomtom_isodistance(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_tomtom_isodistance_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_mapzen_isodistance(source public.geometry(Geometry, 4326), mode text, range integer[], options text[]) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_mapzen_isodistance_exception_safe(source public.geometry(Geometry, 4326), mode text, range integer[], options text[] ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_route_point_to_point(origin public.geometry(Point, 4326), destination public.geometry(Point, 4326), mode text, options text[], units text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_route_point_to_point_exception_safe(origin public.geometry(Point, 4326), destination public.geometry(Point, 4326), mode text, options text[], units text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_route_with_waypoints(waypoints public.geometry(Point, 4326)[], mode text, options text[], units text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_route_with_waypoints_exception_safe(waypoints public.geometry(Point, 4326)[], mode text, options text[], units text ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_service_quota_info() TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_service_quota_info_exception_safe( ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_service_quota_info_batch() TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_service_quota_info_batch_exception_safe( ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_enough_quota(service TEXT, input_size NUMERIC) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_enough_quota_exception_safe(service TEXT, input_size NUMERIC ) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_service_get_rate_limit(service text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client._cdb_service_get_rate_limit_exception_safe(service text ) TO publicuser; + + + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_bulk_geocode_street_point(query text, street_column text, city_column text, state_column text, country_column text, batch_size integer) TO publicuser; + +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_count_estimate(query text) TO publicuser; +GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_jsonb_array_casttext(jsonb) TO publicuser; diff --git a/client/cdb_dataservices_client--0.29.0--0.30.0.sql b/client/old_versions/cdb_dataservices_client--0.29.0--0.30.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.29.0--0.30.0.sql rename to client/old_versions/cdb_dataservices_client--0.29.0--0.30.0.sql diff --git a/client/cdb_dataservices_client--0.30.0--0.29.0.sql b/client/old_versions/cdb_dataservices_client--0.30.0--0.29.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.30.0--0.29.0.sql rename to client/old_versions/cdb_dataservices_client--0.30.0--0.29.0.sql diff --git a/client/cdb_dataservices_client--0.30.0.sql b/client/old_versions/cdb_dataservices_client--0.30.0.sql similarity index 100% rename from client/cdb_dataservices_client--0.30.0.sql rename to client/old_versions/cdb_dataservices_client--0.30.0.sql diff --git a/client/renderer/interface.yaml b/client/renderer/interface.yaml index 22585c0..2b54eb5 100644 --- a/client/renderer/interface.yaml +++ b/client/renderer/interface.yaml @@ -311,390 +311,6 @@ - { name: options, type: "text[]", default: 'ARRAY[]::text[]' } - { name: units, type: "text", default: "'kilometers'"} -- name: obs_get_demographic_snapshot - return_type: json - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: time_span, type: "text", default: "'2009 - 2013'::text" } - - { name: geometry_level, type: text, default: 'NULL' } - -- name: obs_get_segment_snapshot - return_type: json - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: geometry_level, type: text, default: 'NULL' } - -- name: obs_getdemographicsnapshot - return_type: SETOF JSON - multi_row: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: geometry_level, type: text, default: 'NULL' } - -- name: obs_getboundary - return_type: public.Geometry - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: boundary_id, type: text } - - { name: time_span, type: text, default: 'NULL'} - -- name: obs_getboundaryid - return_type: text - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: boundary_id, type: text } - - { name: time_span, type: text, default: 'NULL'} - -- name: obs_getboundarybyid - return_type: public.Geometry - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - 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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: the_geom, type: geometry } - - { name: geom_refs, type: text } - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: boundary_id, type: text } - - { name: time_span, type: text, default: 'NULL'} - - { name: overlap_type, type: text, default: 'NULL'} - -- name: obs_getboundariesbypointandradius - return_type: TABLE(the_geom geometry, geom_refs text) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: the_geom, type: geometry } - - { name: geom_refs, type: text } - params: - - { name: geom, type: "public.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: 'NULL'} - -- name: obs_getpointsbygeometry - return_type: TABLE(the_geom geometry, geom_refs text) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: the_geom, type: geometry } - - { name: geom_refs, type: text } - params: - - { name: geom, type: "public.geometry(Geometry, 4326)" } - - { name: boundary_id, type: text } - - { name: time_span, type: text, default: 'NULL'} - - { name: overlap_type, type: text, default: 'NULL'} - -- name: obs_getpointsbypointandradius - return_type: TABLE(the_geom geometry, geom_refs text) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: the_geom, type: geometry } - - { name: geom_refs, type: text } - params: - - { name: geom, type: "public.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: 'NULL'} - -- name: obs_getmeasure - return_type: numeric - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: public.Geometry } - - { name: measure_id, type: text } - - { name: normalize, type: text, default: 'NULL'} - - { name: boundary_id, type: text, default: 'NULL' } - - { name: time_span, type: text, default: 'NULL'} - -- name: obs_getmeasurebyid - return_type: numeric - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom_ref, type: text } - - { name: measure_id, type: text } - - { name: boundary_id, type: text} - - { name: time_span, type: text, default: 'NULL'} - -- name: obs_getdata - return_type: TABLE(id int, data json) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: id, type: integer } - - { name: data, type: json } - params: - - { name: geomvals, type: "geomval[]" } - - { name: params, type: json } - - { name: merge, type: boolean, default: true } - -- name: obs_getdata - return_type: TABLE(id text, data json) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: id, type: text } - - { name: data, type: json } - params: - - { name: geomrefs, type: "text[]" } - - { name: params, type: json } - -- name: obs_getmeta - return_type: json - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom_ref, type: "public.Geometry(Geometry, 4326)" } - - { name: params, type: json } - - { name: max_timespan_rank, type: integer, default: 'NULL' } - - { name: max_score_rank, type: integer, default: 'NULL' } - - { name: target_geoms, type: integer, default: 'NULL' } - -- name: obs_metadatavalidation - return_type: TABLE(valid boolean, errors text[]) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom_extent, type: "public.Geometry(Geometry, 4326)" } - - { name: geom_type, type: text } - - { name: params, type: json } - - { name: target_geoms, type: integer, default: 'NULL' } - -- name: obs_getcategory - return_type: text - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: public.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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: public.Geometry } - - { name: name, type: text } - - { name: normalize, type: text, default: 'NULL'} - - { name: boundary_id, type: text, default: 'NULL' } - - { name: time_span, type: text, default: 'NULL'} - -- name: obs_getuscensuscategory - return_type: text - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: public.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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: geom, type: public.Geometry } - - { name: normalize, type: text, default: 'NULL'} - - { 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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - 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 - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - table_fields: - - { name: boundary_id, type: text } - - { name: description, type: text } - - { name: time_span, type: text } - - { name: tablename, type: text } - params: - - { name: geom, type: public.Geometry } - - { name: timespan, type: text, default: 'NULL'} - -- name: obs_dumpversion - return_type: text - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - {} - -- name: obs_getavailablenumerators - return_type: SETOF cdb_dataservices_client.obs_meta_numerator - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: bounds, type: "public.geometry(Geometry, 4326)", default: 'NULL' } - - { name: filter_tags, type: "text[]", default: 'NULL' } - - { name: denom_id, type: text, default: 'NULL' } - - { name: geom_id, type: text, default: 'NULL' } - - { name: timespan, type: text, default: 'NULL'} - -- name: _obs_getnumerators - return_type: SETOF cdb_dataservices_client.obs_meta_numerator - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: bounds, type: "public.geometry(Geometry, 4326)", default: 'NULL' } - - { name: section_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' } - - { name: subsection_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' } - - { name: other_tags, type: "text[]", default: 'ARRAY[]::TEXT[]' } - - { name: ids, type: "text[]", default: 'ARRAY[]::TEXT[]' } - - { name: name, type: text, default: 'NULL' } - - { name: denom_id, type: text, default: "''" } - - { name: geom_id, type: text, default: "''" } - - { name: timespan, type: text, default: "''"} - -- name: obs_getavailabledenominators - return_type: SETOF cdb_dataservices_client.obs_meta_denominator - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: bounds, type: "public.geometry(Geometry, 4326)", default: 'NULL' } - - { name: filter_tags, type: "text[]", default: 'NULL' } - - { name: numer_id, type: text, default: 'NULL' } - - { name: geom_id, type: text, default: 'NULL' } - - { name: timespan, type: text, default: 'NULL'} - -- name: obs_getavailablegeometries - return_type: SETOF cdb_dataservices_client.obs_meta_geometry - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: bounds, type: "public.geometry(Geometry, 4326)", default: 'NULL' } - - { name: filter_tags, type: "text[]", default: 'NULL' } - - { name: numer_id, type: text, default: 'NULL' } - - { name: denom_id, type: text, default: 'NULL' } - - { name: timespan, type: text, default: 'NULL'} - - { name: number_geometries, type: integer, default: 'NULL'} - -- name: obs_getavailabletimespans - return_type: SETOF cdb_dataservices_client.obs_meta_timespan - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: bounds, type: "public.geometry(Geometry, 4326)", default: 'NULL' } - - { name: filter_tags, type: "text[]", default: 'NULL' } - - { name: numer_id, type: text, default: 'NULL' } - - { name: denom_id, type: text, default: 'NULL' } - - { name: geom_id, type: text, default: 'NULL'} - -- name: obs_legacybuildermetadata - return_type: TABLE(name text, subsection json) - multi_row: true - multi_field: true - requires_permission: true - permission_name: observatory - permission_error: Data Observatory permission denied - params: - - { name: aggregate_type, type: text, default: 'NULL' } - - name: cdb_service_quota_info return_type: SETOF service_quota_info multi_row: true diff --git a/client/sql/16_custom_types.sql b/client/sql/16_custom_types.sql index bb13ee7..ce4582d 100644 --- a/client/sql/16_custom_types.sql +++ b/client/sql/16_custom_types.sql @@ -16,22 +16,11 @@ CREATE TYPE cdb_dataservices_client.simple_route AS ( duration integer ); --- For the OBS_Meta functions -CREATE TYPE cdb_dataservices_client.obs_meta_numerator AS (numer_id text, numer_name text, numer_description text, numer_weight text, numer_license text, numer_source text, numer_type text, numer_aggregate text, numer_extra jsonb, numer_tags jsonb, valid_denom boolean, valid_geom boolean, valid_timespan boolean); - -CREATE TYPE cdb_dataservices_client.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean); - -CREATE TYPE cdb_dataservices_client.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb); - -CREATE TYPE cdb_dataservices_client.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb); - - -- For quotas and services configuration CREATE TYPE cdb_dataservices_client.service_type AS ENUM ( 'isolines', 'hires_geocoder', - 'routing', - 'observatory' + 'routing' ); CREATE TYPE cdb_dataservices_client.service_quota_info AS ( diff --git a/client/sql/20_table_augmentation.sql b/client/sql/20_table_augmentation.sql deleted file mode 100644 index 7dd48e8..0000000 --- a/client/sql/20_table_augmentation.sql +++ /dev/null @@ -1,279 +0,0 @@ -CREATE TYPE cdb_dataservices_client.ds_fdw_metadata as (schemaname text, tabname text, servername text); -CREATE TYPE cdb_dataservices_client.ds_return_metadata as (colnames text[], coltypes text[]); - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure( - output_table_name text, - params json -) RETURNS boolean AS $$ -DECLARE - username text; - user_db_role text; - orgname text; - user_schema text; - result boolean; -BEGIN - IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN - RAISE EXCEPTION 'The api_key must be provided'; - END IF; - - SELECT session_user INTO user_db_role; - - SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); - -- JSON value stored "" is taken as literal - IF username IS NULL OR username = '' OR username = '""' THEN - RAISE EXCEPTION 'Username is a mandatory argument'; - END IF; - - IF orgname IS NULL OR orgname = '' OR orgname = '""' THEN - user_schema := 'public'; - ELSE - user_schema := username; - END IF; - - SELECT cdb_dataservices_client.__DST_PrepareTableOBS_GetMeasure( - username, - orgname, - user_db_role, - user_schema, - output_table_name, - params - ) INTO result; - - RETURN result; -END; -$$ LANGUAGE 'plpgsql' SECURITY DEFINER VOLATILE PARALLEL UNSAFE - SET search_path = pg_temp; - - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure( - table_name text, - output_table_name text, - params json -) RETURNS boolean AS $$ -DECLARE - username text; - user_db_role text; - orgname text; - dbname text; - user_schema text; - result boolean; -BEGIN - IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN - RAISE EXCEPTION 'The api_key must be provided'; - END IF; - - SELECT session_user INTO user_db_role; - - SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text, p json); - -- JSON value stored "" is taken as literal - IF username IS NULL OR username = '' OR username = '""' THEN - RAISE EXCEPTION 'Username is a mandatory argument'; - END IF; - - IF orgname IS NULL OR orgname = '' OR orgname = '""' THEN - user_schema := 'public'; - ELSE - user_schema := username; - END IF; - - SELECT current_database() INTO dbname; - - SELECT cdb_dataservices_client.__DST_PopulateTableOBS_GetMeasure( - username, - orgname, - user_db_role, - user_schema, - dbname, - table_name, - output_table_name, - params - ) INTO result; - - RETURN result; -END; -$$ LANGUAGE 'plpgsql' SECURITY DEFINER VOLATILE PARALLEL UNSAFE - SET search_path = pg_temp; - - - -CREATE OR REPLACE FUNCTION cdb_dataservices_client.__DST_PrepareTableOBS_GetMeasure( - username text, - orgname text, - user_db_role text, - user_schema text, - output_table_name text, - params json -) RETURNS boolean AS $$ - function_name = 'OBS_GetMeasure' - # Obtain return types for augmentation procedure - ds_return_metadata = plpy.execute("SELECT colnames, coltypes " - "FROM cdb_dataservices_client._DST_GetReturnMetadata({username}::text, {orgname}::text, {function_name}::text, {params}::json);" - .format( - username=plpy.quote_nullable(username), - orgname=plpy.quote_nullable(orgname), - function_name=plpy.quote_literal(function_name), - params=plpy.quote_literal(params) - ) - ) - if ds_return_metadata[0]["colnames"]: - colnames_arr = ds_return_metadata[0]["colnames"] - coltypes_arr = ds_return_metadata[0]["coltypes"] - else: - raise Exception('Error retrieving OBS_GetMeasure metadata') - - - # Prepare column and type strings required in the SQL queries - columns_with_types_arr = [colnames_arr[i] + ' ' + coltypes_arr[i] for i in range(0,len(colnames_arr))] - columns_with_types = ','.join(columns_with_types_arr) - - # Create a new table with the required columns - plpy.execute('CREATE TABLE "{schema}".{table_name} ( ' - 'cartodb_id int, the_geom public.geometry, {columns_with_types} ' - ');' - .format(schema=user_schema, table_name=output_table_name, columns_with_types=columns_with_types) - ) - - plpy.execute('ALTER TABLE "{schema}".{table_name} OWNER TO "{user}";' - .format(schema=user_schema, table_name=output_table_name, user=user_db_role) - ) - - return True -$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_client.__DST_PopulateTableOBS_GetMeasure( - username text, - orgname text, - user_db_role text, - user_schema text, - dbname text, - table_name text, - output_table_name text, - params json -) RETURNS boolean AS $$ - function_name = 'OBS_GetMeasure' - # Obtain return types for augmentation procedure - ds_return_metadata = plpy.execute( - "SELECT colnames, coltypes " - "FROM cdb_dataservices_client._DST_GetReturnMetadata({username}::text, {orgname}::text, {function_name}::text, {params}::json);" .format( - username=plpy.quote_nullable(username), - orgname=plpy.quote_nullable(orgname), - function_name=plpy.quote_literal(function_name), - params=plpy.quote_literal(params))) - - if ds_return_metadata[0]["colnames"]: - colnames_arr = ds_return_metadata[0]["colnames"] - coltypes_arr = ds_return_metadata[0]["coltypes"] - else: - raise Exception('Error retrieving OBS_GetMeasure metadata') - - # Prepare column and type strings required in the SQL queries - columns_with_types_arr = [ - colnames_arr[i] + - ' ' + - coltypes_arr[i] for i in range( - 0, - len(colnames_arr))] - columns_with_types = ','.join(columns_with_types_arr) - aliased_colname_list = ','.join( - ['result.' + name for name in colnames_arr]) - - # Instruct the OBS server side to establish a FDW - # The metadata is obtained as well in order to: - # - (a) be able to write the query to grab the actual data to be executed in the remote server via pl/proxy, - # - (b) be able to tell OBS to free resources when done. - ds_fdw_metadata = plpy.execute( - "SELECT schemaname, tabname, servername " - "FROM cdb_dataservices_client._DST_ConnectUserTable({username}::text, {orgname}::text, {user_db_role}::text, " - "{schema}::text, {dbname}::text, {table_name}::text);" .format( - username=plpy.quote_nullable(username), - orgname=plpy.quote_nullable(orgname), - user_db_role=plpy.quote_literal(user_db_role), - schema=plpy.quote_literal(user_schema), - dbname=plpy.quote_literal(dbname), - table_name=plpy.quote_literal(table_name))) - - if ds_fdw_metadata[0]["schemaname"]: - server_schema = ds_fdw_metadata[0]["schemaname"] - server_table_name = ds_fdw_metadata[0]["tabname"] - server_name = ds_fdw_metadata[0]["servername"] - else: - raise Exception('Error connecting dataset via FDW') - - # Create a new table with the required columns - plpy.execute( - 'INSERT INTO "{schema}".{analysis_table_name} ' - 'SELECT ut.cartodb_id, ut.the_geom, {colname_list} ' - 'FROM "{schema}".{table_name} ut ' - 'LEFT JOIN cdb_dataservices_client._DST_FetchJoinFdwTableData({username}::text, {orgname}::text, {server_schema}::text, {server_table_name}::text, ' - '{function_name}::text, {params}::json) ' - 'AS result ({columns_with_types}, cartodb_id int) ' - 'ON result.cartodb_id = ut.cartodb_id;' .format( - schema=user_schema, - analysis_table_name=output_table_name, - colname_list=aliased_colname_list, - table_name=table_name, - username=plpy.quote_nullable(username), - orgname=plpy.quote_nullable(orgname), - server_schema=plpy.quote_literal(server_schema), - server_table_name=plpy.quote_literal(server_table_name), - function_name=plpy.quote_literal(function_name), - params=plpy.quote_literal(params), - columns_with_types=columns_with_types)) - - # Wipe user FDW data from the server - wiped = plpy.execute( - "SELECT cdb_dataservices_client._DST_DisconnectUserTable({username}::text, {orgname}::text, {server_schema}::text, " - "{server_table_name}::text, {fdw_server}::text)" .format( - username=plpy.quote_nullable(username), - orgname=plpy.quote_nullable(orgname), - server_schema=plpy.quote_literal(server_schema), - server_table_name=plpy.quote_literal(server_table_name), - fdw_server=plpy.quote_literal(server_name))) - - return True -$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_ConnectUserTable( - username text, - orgname text, - user_db_role text, - user_schema text, - dbname text, - table_name text -)RETURNS cdb_dataservices_client.ds_fdw_metadata AS $$ - CONNECT cdb_dataservices_client._server_conn_str(); - TARGET cdb_dataservices_server._DST_ConnectUserTable; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_GetReturnMetadata( - username text, - orgname text, - function_name text, - params json -) RETURNS cdb_dataservices_client.ds_return_metadata AS $$ - CONNECT cdb_dataservices_client._server_conn_str(); - TARGET cdb_dataservices_server._DST_GetReturnMetadata; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_FetchJoinFdwTableData( - username text, - orgname text, - table_schema text, - table_name text, - function_name text, - params json -) RETURNS SETOF record AS $$ - CONNECT cdb_dataservices_client._server_conn_str(); - TARGET cdb_dataservices_server._DST_FetchJoinFdwTableData; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_client._DST_DisconnectUserTable( - username text, - orgname text, - table_schema text, - table_name text, - server_name text -) RETURNS boolean AS $$ - CONNECT cdb_dataservices_client._server_conn_str(); - TARGET cdb_dataservices_server._DST_DisconnectUserTable; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; diff --git a/client/sql/35_precheck_functions.sql b/client/sql/35_precheck_functions.sql deleted file mode 100644 index 92f4520..0000000 --- a/client/sql/35_precheck_functions.sql +++ /dev/null @@ -1,54 +0,0 @@ -CREATE OR REPLACE FUNCTION cdb_dataservices_client._OBS_PreCheck( - source_query text, - parameters json -) RETURNS boolean AS $$ -DECLARE - errors text[]; - validator_errors text[]; - validator_error text; - valid boolean; - geoms record; -BEGIN - errors := (ARRAY[])::TEXT[]; - FOR geoms IN EXECUTE format('SELECT ST_GeometryType(the_geom) as geom_type, - bool_and(st_isvalid(the_geom)) as valid, - avg(st_npoints(the_geom)) as avg_vertex, - ST_SetSRID(ST_Extent(the_geom), 4326) as extent, - count(*)::INT as numgeoms - FROM (%s) as _source - GROUP BY ST_GeometryType(the_geom)', source_query) - LOOP - IF geoms.geom_type NOT IN ('ST_Polygon', 'ST_MultiPolygon', 'ST_Point') THEN - errors := array_append(errors, format($data$'Geometry type %s not supported'$data$, geoms.geom_type)); - END IF; - - IF geoms.valid IS FALSE THEN - errors := array_append(errors, 'There are invalid geometries in the input data, please try to fix them'); - END IF; - - -- 1000 vertex for a geometry is a limit we have in the obs_getdata function. You can check here - -- https://github.com/CartoDB/observatory-extension/blob/1.6.0/src/pg/sql/41_observatory_augmentation.sql#L813 - IF geoms.avg_vertex > 1000 THEN - errors := array_append(errors, 'The average number of vertices per geometry is greater than 1000, please try to simplify them'); - END IF; - - -- OBS specific part - EXECUTE 'SELECT valid, errors - FROM cdb_dataservices_client.OBS_MetadataValidation($1, $2, $3, $4)' - INTO valid, validator_errors - USING geoms.extent, geoms.geom_type, parameters, geoms.numgeoms; - IF valid is FALSE THEN - FOR validator_error IN EXECUTE 'SELECT unnest($1)' USING validator_errors - LOOP - errors := array_append(errors, validator_error); - END LOOP; - END IF; - END LOOP; - - IF CARDINALITY(errors) > 0 THEN - RAISE EXCEPTION '%', errors; - END IF; - - RETURN TRUE; -END; -$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE; diff --git a/client/sql/95_grant_execute_manual.sql b/client/sql/95_grant_execute_manual.sql index 099c8df..288c594 100644 --- a/client/sql/95_grant_execute_manual.sql +++ b/client/sql/95_grant_execute_manual.sql @@ -1,6 +1,3 @@ -GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure(output_table_name text, params json) TO publicuser; -GRANT EXECUTE ON FUNCTION cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure(table_name text, output_table_name text, params json) TO publicuser; -GRANT EXECUTE ON FUNCTION cdb_dataservices_client._OBS_PreCheck(source_query text, params JSON) TO publicuser; GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_bulk_geocode_street_point(query text, street_column text, city_column text, state_column text, country_column text, batch_size integer) TO publicuser; GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_count_estimate(query text) TO publicuser; diff --git a/client/test/expected/90_data_observatory_test.out b/client/test/expected/90_data_observatory_test.out deleted file mode 100644 index f10e1a0..0000000 --- a/client/test/expected/90_data_observatory_test.out +++ /dev/null @@ -1,481 +0,0 @@ -\set VERBOSITY terse --- Add to the search path the schema -SET search_path TO public,cartodb,cdb_dataservices_client; --- Mock the server functions -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 $$ -DECLARE - ret json; -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_get_demographic_snapshot 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_get_segment_snapshot (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_get_segment_snapshot 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_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 NULL) -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 NULL) -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 NULL) -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 NULL, 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_getmeasurebyid (username text, orgname text, geom_ref text, measure_id text, boundary_id text, time_span text DEFAULT NULL) -RETURNS numeric AS $$ -DECLARE - ret numeric; -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getmeasurebyid invoked with params (%, %, %, %, %, %)', username, orgname, geom_ref, measure_id, 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 NULL, 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 NULL, 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 NULL) -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'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getmeta(username text, orgname text, geom geometry(Geometry, 4326), params JSON, max_timespan_rank INTEGER DEFAULT NULL, max_score_rank INTEGER DEFAULT NULL, target_geoms INTEGER DEFAULT NULL) -RETURNS JSON AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getmeta invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, params, max_timespan_rank, max_score_rank, target_geoms; - RETURN '[{"id" : 1, "numer_id" : "us.census.acs.B01003001", "timespan_rank" : 1, "score_rank" : 1, "score" : 19.9580760018781868330120152747832081562684, "numer_aggregate" : "sum", "numer_colname" : "total_pop", "numer_geomref_colname" : "geoid", "numer_tablename" : "obs_209d3476ef8eaaa18e597cabcf1bdb627f37aa5e", "numer_type" : "Numeric", "denom_aggregate" : null, "denom_colname" : null, "denom_geomref_colname" : null, "denom_tablename" : null, "denom_type" : null, "geom_colname" : "the_geom", "geom_geomref_colname" : "geoid", "geom_tablename" : "obs_78fb6c1d6ff6505225175922c2c389ce48d7632c", "geom_type" : "Geometry", "geom_timespan" : "2015", "numer_timespan" : "2011 - 2015", "numer_name" : "Total Population", "denom_name" : null, "geom_name" : "US Census Block Groups", "normalization" : null, "denom_id" : null, "geom_id" : "us.census.tiger.block_group"}]'::JSON; -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdata(username text, orgname text, geomrefs text[], params json) -RETURNS TABLE (id TEXT, data JSON) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getdata invoked with params (%, %, %, %)', username, orgname, geomrefs, params; - RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data; -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdata(username text, orgname text, geomvals geomval[], params json, merge boolean default true) -RETURNS TABLE (id TEXT, data JSON) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getdata invoked with params (%, %, %, %, %)', username, orgname, geomvals, params, merge; - RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data; -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_metadatavalidation(username text, orgname text, geom_extent geometry(Geometry, 4326), geom_type text, params JSON, target_geoms INTEGER DEFAULT NULL) -RETURNS TABLE (valid boolean, errors text[]) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_metadatavalidation invoked with params (%, %, %, %, %, %)', username, orgname, geom_extent, geom_type, params, target_geoms; - RETURN QUERY SELECT true AS valid, ARRAY[]::TEXT[] AS errors; -END; -$$ LANGUAGE 'plpgsql'; --- -- Exercise the public and the proxied function --- No permissions granted -SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_get_segment_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getdemographicsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013', '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getsegmentsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundary(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundaryid(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundarybyid('36047'::text, 'us.census.tiger.county'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundariesbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundariesbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500, 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpointsbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpointsbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500::numeric, 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.acs.B01001001'::text); -ERROR: Data Observatory permission denied -SELECT obs_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::text); -ERROR: Data Observatory permission denied -SELECT obs_getcategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.spielman_singleton_segments.X10'::text); -ERROR: Data Observatory permission denied -SELECT obs_getuscensusmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'male population'::text); -ERROR: Data Observatory permission denied -SELECT obs_getuscensuscategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'Spielman-Singleton Segments: 10 Clusters'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpopulation(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); -ERROR: Data Observatory permission denied -SELECT obs_search('total_pop'::text); -ERROR: Data Observatory permission denied -SELECT obs_getavailableboundaries(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); -ERROR: Data Observatory permission denied -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -ERROR: Data Observatory permission denied -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -ERROR: Data Observatory permission denied -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -ERROR: Data Observatory permission denied -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); -ERROR: Data Observatory permission denied --- Grant other permissions but DO -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": ["routing", "isolines"]}'); - cdb_conf_setconf ------------------- - -(1 row) - -SELECT obs_get_demographic_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013'::text, '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_get_segment_snapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getdemographicsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '2009 - 2013', '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getsegmentsnapshot(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), '"us.census.tiger".block_group'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundary(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundaryid(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundarybyid('36047'::text, 'us.census.tiger.county'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundariesbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getboundariesbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500, 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpointsbygeometry(ST_MakeEnvelope(-73.9452409744, 40.6988851644, -73.9280319214, 40.7101254524, 4326), 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpointsbypointandradius(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 500::numeric, 'us.census.tiger.census_tract'::text); -ERROR: Data Observatory permission denied -SELECT obs_getmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.acs.B01001001'::text); -ERROR: Data Observatory permission denied -SELECT obs_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::text); -ERROR: Data Observatory permission denied -SELECT obs_getcategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'us.census.spielman_singleton_segments.X10'::text); -ERROR: Data Observatory permission denied -SELECT obs_getuscensusmeasure(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'male population'::text); -ERROR: Data Observatory permission denied -SELECT obs_getuscensuscategory(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326), 'Spielman-Singleton Segments: 10 Clusters'::text); -ERROR: Data Observatory permission denied -SELECT obs_getpopulation(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); -ERROR: Data Observatory permission denied -SELECT obs_search('total_pop'::text); -ERROR: Data Observatory permission denied -SELECT obs_getavailableboundaries(ST_SetSRID(ST_Point(-73.936669 , 40.704512), 4326)); -ERROR: Data Observatory permission denied -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -ERROR: Data Observatory permission denied -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -ERROR: Data Observatory permission denied -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -ERROR: Data Observatory permission denied -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); -ERROR: Data Observatory permission denied --- Grant DO permissions -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": ["observatory"]}'); - cdb_conf_setconf ------------------- - -(1 row) - -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) - obs_get_demographic_snapshot -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"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(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) - obs_get_segment_snapshot -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"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) - 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) - 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, ) - 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, ) - 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, ) - 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, , ) - 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, , ) - 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, , ) - 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, , ) - 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, , , ) - obs_getmeasure ------------------------ - 10923.093200390833950 -(1 row) - -SELECT obs_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::text); -NOTICE: cdb_dataservices_client._obs_getmeasurebyid(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getmeasurebyid invoked with params (test_user, , 36047, us.census.acs.B01001001, us.census.tiger.county, ) - obs_getmeasurebyid ------------------------ - 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, , ) - 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, , , ) - 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, , ) - 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, , , ) - 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, ) - 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, ) - 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) - -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -NOTICE: cdb_dataservices_client._obs_getmeta(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getmeta invoked with params (test_user, , 0101000020E61000009A999999997952C09A99999999594440, [{"numer_id": "us.census.acs.B01003001"}], 1, 1, 1000) - obs_getmeta ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [{"id" : 1, "numer_id" : "us.census.acs.B01003001", "timespan_rank" : 1, "score_rank" : 1, "score" : 19.9580760018781868330120152747832081562684, "numer_aggregate" : "sum", "numer_colname" : "total_pop", "numer_geomref_colname" : "geoid", "numer_tablename" : "obs_209d3476ef8eaaa18e597cabcf1bdb627f37aa5e", "numer_type" : "Numeric", "denom_aggregate" : null, "denom_colname" : null, "denom_geomref_colname" : null, "denom_tablename" : null, "denom_type" : null, "geom_colname" : "the_geom", "geom_geomref_colname" : "geoid", "geom_tablename" : "obs_78fb6c1d6ff6505225175922c2c389ce48d7632c", "geom_type" : "Geometry", "geom_timespan" : "2015", "numer_timespan" : "2011 - 2015", "numer_name" : "Total Population", "denom_name" : null, "geom_name" : "US Census Block Groups", "normalization" : null, "denom_id" : null, "geom_id" : "us.census.tiger.block_group"}] -(1 row) - -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -NOTICE: cdb_dataservices_client._obs_getmeta(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getmeta invoked with params (test_user, , 0101000020E61000009A999999997952C09A99999999594440, [{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}], 1, 1, 1000) -NOTICE: cdb_dataservices_client._obs_getdata(4): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getdata invoked with params (test_user, , {36047}, [{"id" : 1, "numer_id" : "us.census.acs.B01003001", "timespan_rank" : 1, "score_rank" : 1, "score" : 19.9580760018781868330120152747832081562684, "numer_aggregate" : "sum", "numer_colname" : "total_pop", "numer_geomref_colname" : "geoid", "numer_tablename" : "obs_209d3476ef8eaaa18e597cabcf1bdb627f37aa5e", "numer_type" : "Numeric", "denom_aggregate" : null, "denom_colname" : null, "denom_geomref_colname" : null, "denom_tablename" : null, "denom_type" : null, "geom_colname" : "the_geom", "geom_geomref_colname" : "geoid", "geom_tablename" : "obs_78fb6c1d6ff6505225175922c2c389ce48d7632c", "geom_type" : "Geometry", "geom_timespan" : "2015", "numer_timespan" : "2011 - 2015", "numer_name" : "Total Population", "denom_name" : null, "geom_name" : "US Census Block Groups", "normalization" : null, "denom_id" : null, "geom_id" : "us.census.tiger.block_group"}]) - obs_getdata --------------------------------------------- - (36047,"[{""value"" : 10349.1547875017}]") -(1 row) - -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -NOTICE: cdb_dataservices_client._obs_getmeta(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getmeta invoked with params (test_user, , 0101000020E61000009A999999997952C09A99999999594440, [{"numer_id": "us.census.acs.B01003001"}], , , ) -NOTICE: cdb_dataservices_client._obs_getdata(5): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_getdata invoked with params (test_user, , {"(0101000020E61000009A999999997952C09A99999999594440,1)"}, [{"id" : 1, "numer_id" : "us.census.acs.B01003001", "timespan_rank" : 1, "score_rank" : 1, "score" : 19.9580760018781868330120152747832081562684, "numer_aggregate" : "sum", "numer_colname" : "total_pop", "numer_geomref_colname" : "geoid", "numer_tablename" : "obs_209d3476ef8eaaa18e597cabcf1bdb627f37aa5e", "numer_type" : "Numeric", "denom_aggregate" : null, "denom_colname" : null, "denom_geomref_colname" : null, "denom_tablename" : null, "denom_type" : null, "geom_colname" : "the_geom", "geom_geomref_colname" : "geoid", "geom_tablename" : "obs_78fb6c1d6ff6505225175922c2c389ce48d7632c", "geom_type" : "Geometry", "geom_timespan" : "2015", "numer_timespan" : "2011 - 2015", "numer_name" : "Total Population", "denom_name" : null, "geom_name" : "US Census Block Groups", "normalization" : null, "denom_id" : null, "geom_id" : "us.census.tiger.block_group"}], t) - obs_getdata --------------------------------------------- - (36047,"[{""value"" : 10349.1547875017}]") -(1 row) - -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); -NOTICE: cdb_dataservices_client._obs_metadatavalidation(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.obs_metadatavalidation invoked with params (test_user, , 0101000020E61000009A999999997952C09A99999999594440, ST_Polygon, [{"numer_id": "us.census.acs.B01003001"}], 1000) - obs_metadatavalidation ------------------------- - (t,{}) -(1 row) - -SELECT CDB_Conf_RemoveConf('api_keys_postgres'); - cdb_conf_removeconf ---------------------- - -(1 row) - diff --git a/client/test/expected/95_data_observatory_tables_test.out b/client/test/expected/95_data_observatory_tables_test.out deleted file mode 100644 index 594305e..0000000 --- a/client/test/expected/95_data_observatory_tables_test.out +++ /dev/null @@ -1,77 +0,0 @@ --- Add to the search path the schema -SET search_path TO public,cartodb,cdb_dataservices_client; -CREATE TABLE my_table(cartodb_id int); -INSERT INTO my_table (cartodb_id) VALUES (1); --- Mock the server functions -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, table_name text) -RETURNS cdb_dataservices_client.ds_fdw_metadata AS $$ -BEGIN - RETURN ('dummy_schema'::text, 'dummy_table'::text, 'dummy_server'::text); -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_GetReturnMetadata(username text, orgname text, function_name text, params json) -RETURNS cdb_dataservices_client.ds_return_metadata AS $$ -BEGIN - RETURN (Array['total_pop'], Array['double precision']); -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_FetchJoinFdwTableData(username text, orgname text, table_schema text, table_name text, function_name text, params json) -RETURNS RECORD AS $$ -BEGIN - RETURN (23.4::double precision, 1::int); -END; -$$ LANGUAGE 'plpgsql'; -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_DisconnectUserTable(username text, orgname text, table_schema text, table_name text, servername text) -RETURNS boolean AS $$ -BEGIN - RETURN true; -END; -$$ LANGUAGE 'plpgsql'; -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": [""]}'); - cdb_conf_setconf ------------------- - -(1 row) - --- Create a sample user table -CREATE TABLE user_table (cartodb_id int, the_geom geometry); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (1, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (2, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (3, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); --- Prepare a table with the total_pop column -SELECT cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure('my_table_dst', '{"dummy":"dummy"}'::json); - _dst_preparetableobs_getmeasure ---------------------------------- - t -(1 row) - --- The table should now exist and be empty -SELECT * FROM my_table_dst; - cartodb_id | the_geom | total_pop -------------+----------+----------- -(0 rows) - --- Populate the table with measurement data -SELECT cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure('user_table', 'my_table_dst', '{"dummy":"dummy"}'::json); - _dst_populatetableobs_getmeasure ----------------------------------- - t -(1 row) - --- The table should now show the results -SELECT * FROM my_table_dst; - cartodb_id | the_geom | total_pop -------------+----------------------------------------------------+----------- - 1 | 0101000020E6100000F74FC902E07D52C05FE24CC7654B4440 | 23.4 - 2 | 0101000020E6100000F74FC902E07D52C05FE24CC7654B4440 | - 3 | 0101000020E6100000F74FC902E07D52C05FE24CC7654B4440 | -(3 rows) - --- Clean tables -DROP TABLE my_table_dst; -SELECT CDB_Conf_RemoveConf('api_keys_postgres'); - cdb_conf_removeconf ---------------------- - -(1 row) - diff --git a/client/test/sql/90_data_observatory_test.sql b/client/test/sql/90_data_observatory_test.sql deleted file mode 100644 index c46c2bd..0000000 --- a/client/test/sql/90_data_observatory_test.sql +++ /dev/null @@ -1,309 +0,0 @@ -\set VERBOSITY terse --- Add to the search path the schema -SET search_path TO public,cartodb,cdb_dataservices_client; - --- Mock the server functions - -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 $$ -DECLARE - ret json; -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_get_demographic_snapshot 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_get_segment_snapshot (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_get_segment_snapshot 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_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 NULL) -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 NULL) -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 NULL) -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 NULL, 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_getmeasurebyid (username text, orgname text, geom_ref text, measure_id text, boundary_id text, time_span text DEFAULT NULL) -RETURNS numeric AS $$ -DECLARE - ret numeric; -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getmeasurebyid invoked with params (%, %, %, %, %, %)', username, orgname, geom_ref, measure_id, 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 NULL, 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 NULL, 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 NULL) -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'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getmeta(username text, orgname text, geom geometry(Geometry, 4326), params JSON, max_timespan_rank INTEGER DEFAULT NULL, max_score_rank INTEGER DEFAULT NULL, target_geoms INTEGER DEFAULT NULL) -RETURNS JSON AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getmeta invoked with params (%, %, %, %, %, %, %)', username, orgname, geom, params, max_timespan_rank, max_score_rank, target_geoms; - RETURN '[{"id" : 1, "numer_id" : "us.census.acs.B01003001", "timespan_rank" : 1, "score_rank" : 1, "score" : 19.9580760018781868330120152747832081562684, "numer_aggregate" : "sum", "numer_colname" : "total_pop", "numer_geomref_colname" : "geoid", "numer_tablename" : "obs_209d3476ef8eaaa18e597cabcf1bdb627f37aa5e", "numer_type" : "Numeric", "denom_aggregate" : null, "denom_colname" : null, "denom_geomref_colname" : null, "denom_tablename" : null, "denom_type" : null, "geom_colname" : "the_geom", "geom_geomref_colname" : "geoid", "geom_tablename" : "obs_78fb6c1d6ff6505225175922c2c389ce48d7632c", "geom_type" : "Geometry", "geom_timespan" : "2015", "numer_timespan" : "2011 - 2015", "numer_name" : "Total Population", "denom_name" : null, "geom_name" : "US Census Block Groups", "normalization" : null, "denom_id" : null, "geom_id" : "us.census.tiger.block_group"}]'::JSON; -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdata(username text, orgname text, geomrefs text[], params json) -RETURNS TABLE (id TEXT, data JSON) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getdata invoked with params (%, %, %, %)', username, orgname, geomrefs, params; - RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data; -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_getdata(username text, orgname text, geomvals geomval[], params json, merge boolean default true) -RETURNS TABLE (id TEXT, data JSON) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_getdata invoked with params (%, %, %, %, %)', username, orgname, geomvals, params, merge; - RETURN QUERY SELECT '36047'::TEXT AS id, '[{"value" : 10349.1547875017}]'::JSON AS data; -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_metadatavalidation(username text, orgname text, geom_extent geometry(Geometry, 4326), geom_type text, params JSON, target_geoms INTEGER DEFAULT NULL) -RETURNS TABLE (valid boolean, errors text[]) AS $$ -BEGIN - RAISE NOTICE 'cdb_dataservices_server.obs_metadatavalidation invoked with params (%, %, %, %, %, %)', username, orgname, geom_extent, geom_type, params, target_geoms; - RETURN QUERY SELECT true AS valid, ARRAY[]::TEXT[] AS errors; -END; -$$ LANGUAGE 'plpgsql'; - --- -- Exercise the public and the proxied function - --- No permissions granted -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_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::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)); -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); - --- Grant other permissions but DO -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": ["routing", "isolines"]}'); -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_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::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)); -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); - --- Grant DO permissions -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": ["observatory"]}'); -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_getmeasurebyid('36047'::text, 'us.census.acs.B01001001'::text, 'us.census.tiger.county'::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)); -SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]', 1, 1, 1000); -SELECT obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001", "geom_id": "us.census.tiger.county"}]', 1, 1, 1000)); -SELECT obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), '[{"numer_id": "us.census.acs.B01003001"}]')); -SELECT obs_metadatavalidation(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 'ST_Polygon', '[{"numer_id": "us.census.acs.B01003001"}]', 1000); - -SELECT CDB_Conf_RemoveConf('api_keys_postgres'); diff --git a/client/test/sql/95_data_observatory_tables_test.sql b/client/test/sql/95_data_observatory_tables_test.sql deleted file mode 100644 index 6cf401c..0000000 --- a/client/test/sql/95_data_observatory_tables_test.sql +++ /dev/null @@ -1,60 +0,0 @@ --- Add to the search path the schema -SET search_path TO public,cartodb,cdb_dataservices_client; - -CREATE TABLE my_table(cartodb_id int); - -INSERT INTO my_table (cartodb_id) VALUES (1); - --- Mock the server functions -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, table_name text) -RETURNS cdb_dataservices_client.ds_fdw_metadata AS $$ -BEGIN - RETURN ('dummy_schema'::text, 'dummy_table'::text, 'dummy_server'::text); -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_GetReturnMetadata(username text, orgname text, function_name text, params json) -RETURNS cdb_dataservices_client.ds_return_metadata AS $$ -BEGIN - RETURN (Array['total_pop'], Array['double precision']); -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_FetchJoinFdwTableData(username text, orgname text, table_schema text, table_name text, function_name text, params json) -RETURNS RECORD AS $$ -BEGIN - RETURN (23.4::double precision, 1::int); -END; -$$ LANGUAGE 'plpgsql'; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_DisconnectUserTable(username text, orgname text, table_schema text, table_name text, servername text) -RETURNS boolean AS $$ -BEGIN - RETURN true; -END; -$$ LANGUAGE 'plpgsql'; - -SELECT CDB_Conf_SetConf('api_keys_postgres', '{"username": "test_user", "permissions": [""]}'); - --- Create a sample user table -CREATE TABLE user_table (cartodb_id int, the_geom geometry); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (1, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (2, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); -INSERT INTO user_table(cartodb_id, the_geom) VALUES (3, '0101000020E6100000F74FC902E07D52C05FE24CC7654B4440'); - --- Prepare a table with the total_pop column -SELECT cdb_dataservices_client._DST_PrepareTableOBS_GetMeasure('my_table_dst', '{"dummy":"dummy"}'::json); - --- The table should now exist and be empty -SELECT * FROM my_table_dst; - --- Populate the table with measurement data -SELECT cdb_dataservices_client._DST_PopulateTableOBS_GetMeasure('user_table', 'my_table_dst', '{"dummy":"dummy"}'::json); - --- The table should now show the results -SELECT * FROM my_table_dst; - --- Clean tables -DROP TABLE my_table_dst; - -SELECT CDB_Conf_RemoveConf('api_keys_postgres'); diff --git a/docs/developer-center/reference/07-demographic-functions.md b/docs/developer-center/reference/07-demographic-functions.md deleted file mode 100644 index 890c68b..0000000 --- a/docs/developer-center/reference/07-demographic-functions.md +++ /dev/null @@ -1,159 +0,0 @@ -### Demographic Functions - -
-

We will no longer support these demographic functions from the 1st of January 2021. If you want to collect demographic reports around a point location, we recommend using Data Observatory from our Python library CARTOframes instead.

-
- -The Demographic Snapshot enables you to collect demographic reports around a point location. For example, you can take the coordinates of a coffee shop and find the average population characteristics, such as total population, educational attainment, housing and income information around that location. You can use raw street addresses by combining the Demographic Snapshot with CARTO's geocoding features. If you need help creating coordinates from addresses, see the [Geocoding Functions]({{site.dataservicesapi_docs}}/reference/#geocoding-functions) documentation. - -_**Note:** The Demographic Snapshot functions are only available for the United States._ - -#### OBS_GetDemographicSnapshot( point geometry ) - -Fields returned include information about income, education, transportation, race, and more. Not all fields will have information for every coordinate queried. - -##### Arguments - -Name | Description | Example Values ---- | --- | --- -point geometry | A point geometry. You can use the helper function, `CDB_LatLng` to quickly generate one from latitude and longitude | `CDB_LatLng(40.760410,-73.964242)` - -##### Returns - -The Demographic Snapshot contains a broad subset of demographic measures in the Data Observatory. Over 80 measurements are returned by a single API request. For each demographic measure, the API returns the following values. - -Value | Name | Tablename | Aggregate | Type | Description ------ | ---- | --------- | --------- | ---- |------------ -The value of the measure at the point you requested | The name of the measure | The table it was drawn from | Indicated if the measure is a count or median. | postgresql | A description of the measure - -For example the "Female Population" measure returns - -```json -obs_getdemographicsnapshot: { - "value": 32.5395066379175, - "name": "Female Population", - "tablename": "obs_1a098da56badf5f32e336002b0a81708c40d29cd", - "aggregate": "sum", - "type": "Numeric", - "description": "The number of people within each geography who are female." -} -``` - -**For details, see the [Glossary of Demographic Measures](#glossary-of-demographic-measures).** - -##### Examples - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetDemographicSnapshot({{point geometry}}) -``` - -####### Get the Geographic Snapshot of a Demographic - -__Get the Demographic Snapshot at Camp David__ - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetDemographicSnapshot(CDB_LatLng(39.648333, -77.465)) -``` - -__Get the Demographic Snapshot in the Upper West Side__ - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetDemographicSnapshot(CDB_LatLng(40.80, -73.960)) -``` - -#### Glossary of Demographic Measures - -This list contains the demographic measures and response names for results from the ```OBS_GetDemographicSnapshot``` function. - - Measure name | Measure Description | Response Mame | Response Units ---- | --- | --- | --- -Total Population | The total number of all people living in a given geographic area. This is a very useful catch-all denominator when calculating rates. | total_pop | Count per sq. km -Male Population | The number of people within each geography who are male. | male_pop | Count per sq. km -Female Population | The number of people within each geography who are female.| female_pop | Count per sq. km -Population not Hispanic | The number of people not identifying as Hispanic or Latino in each geography. | not_hispanic_pop | Count per sq. km -White Population | The number of people identifying as white, non-Hispanic in each geography. | white_pop | Count per sq. km -Black or African American Population| The number of people identifying as black or African American, non-Hispanic in each geography. | black_pop | Count per sq. km -American Indian and Alaska Native Population | The number of people identifying as American Indian or Alaska native in each geography.| amerindian_pop| Count per sq. km -Asian Population | The number of people identifying as Asian, non-Hispanic in each geography.| asian_pop | Count per sq. km -Other Race population | The number of people identifying as another race in each geography. | other_race_pop | Count per sq. km -Two or more races population| The number of people identifying as two or more races in each geography | two_or_more_races_pop | Count per sq. km -Hispanic Population | The number of people identifying as Hispanic or Latino in each geography. | hispanic_pop | Count per sq. km -Not a U.S. Citizen Population | The number of people within each geography who indicated that they are not U.S. citizens. | not_us_citizen_pop | Count per sq. km -Median Age | The median age of all people in a given geographic area.| median_age | Years -Children under 18 Years of Age | The number of people within each geography who are under 18 years of age.| children | Count per sq. km -Population 15 Years and Over | The number of people in a geographic area who are over the age of 15. This is used mostly as a denominator of marital status. | pop_15_and_over | Count per sq. km -Population 3 Years and Over | The total number of people in each geography age 3 years and over. This denominator is mostly used to calculate rates of school enrollment. | population_3_years_over | Count per sq. km -Population 5 Years and Over | The number of people in a geographic area who are over the age of 5. This is primarily used as a denominator of measures of language spoken at home.| pop_5_years_over | Count per sq. km -Workers over the Age of 16 | The number of people in each geography who work. Workers include those employed at private for-profit companies, the self-employed, government workers and non-profit employees. | workers_16_and_over | Count per sq. km -Workers age 16 and over who do not work from home| The number of workers over the age of 16 who do not work from home in a geographic area| commuters_16_over | Count per sq. km -Commuters by Car, Truck, or Van | The number of workers age 16 years and over within a geographic area who primarily traveled to work by car, truck or van. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_car_truck_van | Count per sq. km -Commuters who drove alone | The number of workers age 16 years and over within a geographic area who primarily traveled by car driving alone. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_drove_alone | Count per sq. km -Commuters by Carpool| The number of workers age 16 years and over within a geographic area who primarily traveled to work by carpool. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_carpool | Count per sq. km -Commuters by Public Transportation | The number of workers age 16 years and over within a geographic area who primarily traveled to work by public transportation. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_public_transportation | Count per sq. km | -Commuters by Bus | The number of workers age 16 years and over within a geographic area who primarily traveled to work by bus. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. This is a subset of workers who commuted by public transport. | commuters_by_bus| Count per sq. km -Commuters by Subway or Elevated | The number of workers age 16 years and over within a geographic area who primarily traveled to work by subway or elevated train. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. This is a subset of workers who commuted by public transport. | commuters_by_subway_or_elevated | Count per sq. km -Walked to Work | The number of workers age 16 years and over within a geographic area who primarily walked to work. This would mean that of any way of getting to work, they travelled the most distance walking. | walked_to_work | Count per sq. km -Worked at Home | The count within a geographical area of workers over the age of 16 who worked at home. | worked_at_home | Count per sq. km -Number of workers with less than 10 minute commute | The number of workers over the age of 16 who do not work from home and commute in less than 10 minutes in a geographic area. | commute_less_10_mins | Count per sq. km -Number of workers with a commute between 10 and 14 minutes| The number of workers over the age of 16 who do not work from home and commute in between 10 and 14 minutes in a geographic area. | commute_10_14_mins | Count per sq. km -Number of workers with a commute between 15 and 19 minutes | The number of workers over the age of 16 who do not work from home and commute in between 15 and 19 minutes in a geographic area. | commute_15_19_mins | Count per sq. km -Number of workers with a commute between 20 and 24 minutes | The number of workers over the age of 16 who do not work from home and commute in between 20 and 24 minutes in a geographic area. | commute_20_24_mins | Count per sq. km -Number of workers with a commute between 25 and 29 minutes | The number of workers over the age of 16 who do not work from home and commute in between 25 and 29 minutes in a geographic area. | commute_25_29_mins| Count per sq. km -Number of workers with a commute between 30 and 34 minutes | The number of workers over the age of 16 who do not work from home and commute in between 30 and 34 minutes in a geographic area. | commute_30_34_mins | Count per sq. km -Number of workers with a commute between 35 and 44 minutes | The number of workers over the age of 16 who do not work from home and commute in between 35 and 44 minutes in a geographic area. | commute_35_44_mins | Count per sq. km -Number of workers with a commute between 45 and 59 minutes | The number of workers over the age of 16 who do not work from home and commute in between 45 and 59 minutes in a geographic area. | commute_45_59_mins | Count per sq. km -Number of workers with a commute of over 60 minutes | The number of workers over the age of 16 who do not work from home and commute in over 60 minutes in a geographic area.| commute_60_more_mins | Count per sq. km -Aggregate travel time to work | The total number of minutes every worker over the age of 16 who did not work from home spent spent commuting to work in one day in a geographic area. | aggregate_travel_time_to_work | Minutes -Households | A count of the number of households in each geography. A household consists of one or more people who live in the same dwelling and also share at meals or living accommodation, and may consist of a single family or some other grouping of people. | households | Count per sq. km -Never Married | The number of people in a geographic area who have never been married. | pop_never_married | Count per sq. km -Currently married| The number of people in a geographic area who are currently married. | pop_now_married | Count per sq. km -Married but separated | The number of people in a geographic area who are married but separated.| pop_separated | Count per sq. km -Widowed | The number of people in a geographic area who are widowed.| pop_widowed | Count per sq. km -Divorced | The number of people in a geographic area who are divorced. | pop_divorced | Count per sq. km -Students Enrolled in School | The total number of people in each geography currently enrolled at any level of school, from nursery or pre-school to advanced post-graduate education. Only includes those over the age of 3. | in_school | Count per sq. km -Students Enrolled in Grades 1 to 4 | The total number of people in each geography currently enrolled in grades 1 through 4 inclusive. This corresponds roughly to elementary school. | in_grades_1_to_4 | Count per sq. km -Students Enrolled in Grades 5 to 8 | The total number of people in each geography currently enrolled in grades 5 through 8 inclusive. This corresponds roughly to middle school. | in_grades_5_to_8 | Count per sq. km -Students Enrolled in Grades 9 to 12 | The total number of people in each geography currently enrolled in grades 9 through 12 inclusive. This corresponds roughly to high school. | in_grades_9_to_12 | Count per sq. km -Students Enrolled as Undergraduate in College | The number of people in a geographic area who are enrolled in college at the undergraduate level. Enrollment refers to being registered or listed as a student in an educational program leading to a college degree. This may be a public school or college, a private school or college. | in_undergrad_college | Count per sq. km -Population 25 Years and Over | The number of people in a geographic area who are over the age of 25. This is used mostly as a denominator of educational attainment. | pop_25_years_over | Count per sq. km -Population Completed High School | The number of people in a geographic area over the age of 25 who completed high school, and did not complete a more advanced degree. | high_school_diploma| Count per sq. km -Population completed less than one year of college, no degree | The number of people in a geographic area over the age of 25 who attended college for less than one year and no further. | less_one_year_college | Count per sq. km -Population completed more than one year of college, no degree | The number of people in a geographic area over the age of 25 who attended college for more than one year but did not obtain a degree. | one_year_more_college | Count per sq. km -Population Completed Associate's Degree | The number of people in a geographic area over the age of 25 who obtained a associate's degree, and did not complete a more advanced degree.| associates_degree | Count per sq. km -Population Completed Bachelor's Degree| The number of people in a geographic area over the age of 25 who obtained a bachelor's degree, and did not complete a more advanced degree. | bachelors_degree| Count per sq. km -Population Completed Master's Degree | The number of people in a geographic area over the age of 25 who obtained a master's degree, but did not complete a more advanced degree. | masters_degree | Count per sq. km -Speaks only English at Home | The number of people in a geographic area over age 5 who speak only English at home. | speak_only_english_at_home | Count per sq. km -Speaks Spanish at Home | The number of people in a geographic area over age 5 who speak Spanish at home, possibly in addition to other languages. | speak_spanish_at_home | Count per sq. km -Population for Whom Poverty Status Determined | The number of people in each geography who could be identified as either living in poverty or not. This should be used as the denominator when calculating poverty rates, as it excludes people for whom it was not possible to determine poverty. | pop_determined_poverty_status | Count per sq. km -Income In The Past 12 Months Below Poverty Level | The number of people in a geographic area who are part of a family (which could be just them as an individual) determined to be "in poverty" following the [Office of Management and Budget's Directive 14](https://www.census.gov/hhes/povmeas/methodology/ombdir14.html). | poverty | Count per sq. km -Households with income less than $10,000 | The number of households in a geographic area whose annual income was less than $10,000. | income_less_10000 | Count per sq. km -Households with income of $10,000 to $14,999 | The number of households in a geographic area whose annual income was between $10,000 and $14,999. | income_10000_14999 | Count per sq. km -Households with income of $15,000 to $19,999 | The number of households in a geographic area whose annual income was between $15,000 and $19,999. | income_15000_19999 | Count per sq. km -Households with income of $20,000 To $24,999 | The number of households in a geographic area whose annual income was between $20,000 and $24,999. | income_20000_24999 | Count per sq. km -Households with income of $25,000 To $29,999 | The number of households in a geographic area whose annual income was between $20,000 and $24,999. | income_25000_29999 | Count per sq. km -Households with income of $30,000 To $34,999 | The number of households in a geographic area whose annual income was between $30,000 and $34,999. | income_30000_34999 | Count per sq. km -Households with income of $35,000 To $39,999 | The number of households in a geographic area whose annual income was between $35,000 and $39,999. | income_35000_39999 | Count per sq. km -Households with income of $40,000 To $44,999 | The number of households in a geographic area whose annual income was between $40,000 and $44,999. | income_40000_44999| Count per sq. km -Households with income of $45,000 To $49,999 | The number of households in a geographic area whose annual income was between $45,000 and $49,999. | income_45000_49999 | Count per sq. km -Households with income of $50,000 To $59,999 | The number of households in a geographic area whose annual income was between $50,000 and $59,999. | income_50000_59999 | Count per sq. km -Households with income of $60,000 To $74,999 | The number of households in a geographic area whose annual income was between $60,000 and $74,999. | income_60000_74999 | Count per sq. km -Households with income of $75,000 To $99,999 | The number of households in a geographic area whose annual income was between $75,000 and $99,999. | income_75000_99999 | Count per sq. km -Households with income of $100,000 To $124,999 | The number of households in a geographic area whose annual income was between $100,000 and $124,999. | income_100000_124999 | Count per sq. km -Households with income of $125,000 To $149,999 | The number of households in a geographic area whose annual income was between $125,000 and $149,999. | income_125000_149999 | Count per sq. km -Households with income of $150,000 To $199,999 | The number of households in a geographic area whose annual income was between $150,000 and $1999,999. | income_150000_199999 | Count per sq. km -Households with income of $200,000 Or More | The number of households in a geographic area whose annual income was more than $200,000. | income_200000_or_more | Count per sq. km -Median Household Income in the past 12 Months | Within a geographic area, the median income received by every household on a regular basis before payments for personal income taxes, social security, union dues, medicare deductions, etc. It includes income received from wages, salary, commissions, bonuses, and tips; self-employment income from own nonfarm or farm businesses, including proprietorships and partnerships; interest, dividends, net rental income, royalty income, or income from estates and trusts; Social Security or Railroad Retirement income; Supplemental Security Income (SSI); any cash public assistance or welfare payments from the state or local welfare office; retirement, survivor, or disability benefits; and any other sources of income received regularly such as Veterans' (VA) payments, unemployment and/or worker's compensation, child support, and alimony. | median_income | USD -Per Capita Income in the past 12 Months | | income_per_capita | USD -Gini Index | A measurement of the income distribution of a country's residents. | gini_index | None -Housing Units | A count of housing units in each geography. A housing unit is a house, an apartment, a mobile home or trailer, a group of rooms, or a single room occupied as separate living quarters, or if vacant, intended for occupancy as separate living quarters. | housing_units | Count per sq. km -Vacant Housing Units | The count of vacant housing units in a geographic area. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units | Count per sq. km -Vacant Housing Units for Rent | The count of vacant housing units in a geographic area that are for rent. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units_for_rent | Count per sq. km -Vacant Housing Units for Sale| The count of vacant housing units in a geographic area that are for sale. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units_for_sale | Count per sq. km -Owner-occupied Housing Units | The count of owner occupied housing units in a geographic area. | owner_occupied_housing_units | Count per sq. km -Owner-occupied Housing Units valued at $1,000,000 or more. | The count of owner occupied housing units in a geographic area that are valued at $1,000,000 or more. Value is the respondent's estimate of how much the property (house and lot, mobile home and lot, or condominium unit) would sell for if it were for sale. | million_dollar_housing_units | Count per sq. km -Owner-occupied Housing Units with a Mortgage | The count of housing units within a geographic area that are mortagaged. "Mortgage" refers to all forms of debt where the property is pledged as security for repayment of the debt, including deeds of trust, trust deed, contracts to purchase, land contracts, junior mortgages, and home equity loans. | mortgaged_housing_units | Count per sq. km -Median Rent | The median contract rent within a geographic area. The contract rent is the monthly rent agreed to or contracted for, regardless of any furnishings, utilities, fees, meals, or services that may be included. For vacant units, it is the monthly rent asked for the rental unit at the time of interview.| median_rent | USD -Percent of Household Income Spent on Rent | Within a geographic area, the median percentage of household income which was spent on gross rent. Gross rent is the amount of the contract rent plus the estimated average monthly cost of utilities (electricity, gas, water, sewer etc.) and fuels (oil, coal, wood, etc.) if these are paid by the renter. Household income is the sum of the income of all people 15 years and older living in the household. | percent_income_spent_on_rent | Percent diff --git a/docs/developer-center/reference/08-routing-functions.md b/docs/developer-center/reference/07-routing-functions.md similarity index 100% rename from docs/developer-center/reference/08-routing-functions.md rename to docs/developer-center/reference/07-routing-functions.md diff --git a/docs/developer-center/reference/09-segmentation-functions.md b/docs/developer-center/reference/09-segmentation-functions.md deleted file mode 100644 index b1fb46c..0000000 --- a/docs/developer-center/reference/09-segmentation-functions.md +++ /dev/null @@ -1,185 +0,0 @@ -## Segmentation Functions - -
-

We will no longer support these segmentations functions from the 1st of January 2021. For a similar functionality, we recommend using Data Observatory from our Python library CARTOframes instead.

-
- -The Segmentation Snapshot functions enable you to determine the pre-calculated population segment for a location. Segmentation is a method that divides a populations into subclassifications based on common traits. For example, you can take the a store location and determine what classification of population exists around that location. If you need help creating coordinates from addresses, see the [Geocoding Functions]({{site.dataservicesapi_docs}}/reference/#geocoding-functions) documentation. - -_**Note:** The Segmentation Snapshot functions are only available for the United States. Our first release (May 18, 2016) is derived from Census 2010 variables. Our next release will be based on Census 2014 data. For the latest information, see the [Open Segments](https://github.com/CartoDB/open-segments) project repository._ - -### OBS_GetSegmentSnapshot( Point Geometry ) - -#### Arguments - -Name | Description | Example Values ---- | --- | --- -point geometry | A point geometry. You can use the helper function, `CDB_LatLng` to quickly generate one from latitude and longitude | `CDB_LatLng(40.760410,-73.964242)` - -#### Returns - -The segmentation function returns two segment levels for the point you requests, the x10\_segment and x55\_segment. These segmentation levels contain different classifications of population within with each segment. The function also returns the quantile of a number of census variables. For example, if total_poulation is at 90% quantile level then this tract has a higher total population than 90% of the other tracts. - -Name | Type | Description ----- | ---- | ----------- -x10\_segment | text | The demographic segment location at the 10 segment level, containing populations at high-levels, broken down into 10 broad categories -x55\_segment | text | The demographic segment location at the 55 segment level, containing more granular sub-levels to categorize the population - -An example response appears as follows: - -```json -obs_getsegmentsnapshot: { - "x10_segment": "Wealthy, urban without Kids", - "x55_segment": "Wealthy city commuters", - "us.census.acs.B01001001_quantile": "0.0180540540540541", - "us.census.acs.B01001002_quantile": "0.0279864864864865", - "us.census.acs.B01001026_quantile": "0.016527027027027", - "us.census.acs.B01002001_quantile": "0.507297297297297", - "us.census.acs.B03002003_quantile": "0.133162162162162", - "us.census.acs.B03002004_quantile": "0.283743243243243", - "us.census.acs.B03002006_quantile": "0.683945945945946", - "us.census.acs.B03002012_quantile": "0.494594594594595", - "us.census.acs.B05001006_quantile": "0.670972972972973", - "us.census.acs.B08006001_quantile": "0.0607567567567568", - "us.census.acs.B08006002_quantile": "0.0684324324324324", - "us.census.acs.B08006008_quantile": "0.565135135135135", - "us.census.acs.B08006009_quantile": "0.638081081081081", - "us.census.acs.B08006011_quantile": "0", - "us.census.acs.B08006015_quantile": "0.900932432432432", - "us.census.acs.B08006017_quantile": "0.186648648648649", - "us.census.acs.B09001001_quantile": "0.0193513513513514", - "us.census.acs.B11001001_quantile": "0.0617972972972973", - "us.census.acs.B14001001_quantile": "0.0179594594594595", - "us.census.acs.B14001002_quantile": "0.0140405405405405", - "us.census.acs.B14001005_quantile": "0", - "us.census.acs.B14001006_quantile": "0", - "us.census.acs.B14001007_quantile": "0", - "us.census.acs.B14001008_quantile": "0.0609054054054054", - "us.census.acs.B15003001_quantile": "0.0314594594594595", - "us.census.acs.B15003017_quantile": "0.0403378378378378", - "us.census.acs.B15003022_quantile": "0.285972972972973", - "us.census.acs.B15003023_quantile": "0.214567567567568", - "us.census.acs.B16001001_quantile": "0.0181621621621622", - "us.census.acs.B16001002_quantile": "0.0463108108108108", - "us.census.acs.B16001003_quantile": "0.540540540540541", - "us.census.acs.B17001001_quantile": "0.0237567567567568", - "us.census.acs.B17001002_quantile": "0.155972972972973", - "us.census.acs.B19013001_quantile": "0.380662162162162", - "us.census.acs.B19083001_quantile": "0.986891891891892", - "us.census.acs.B19301001_quantile": "0.989594594594595", - "us.census.acs.B25001001_quantile": "0.998418918918919", - "us.census.acs.B25002003_quantile": "0.999824324324324", - "us.census.acs.B25004002_quantile": "0.999986486486486", - "us.census.acs.B25004004_quantile": "0.999662162162162", - "us.census.acs.B25058001_quantile": "0.679054054054054", - "us.census.acs.B25071001_quantile": "0.569716216216216", - "us.census.acs.B25075001_quantile": "0.0415", - "us.census.acs.B25075025_quantile": "0.891702702702703" -} -``` - -The possible segments are: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
X10 segment X55 Segment
Hispanic and kids
Middle Class, Educated, Suburban, Mixed Race
Low Income on Urban Periphery
Suburban, Young and Low-income
low-income, urban, young, unmarried
Low education, mainly suburban
Young, working class and rural
Low-Income with gentrification
Low Income and Diverse
High school education Long Commuters, Black, White Hispanic mix
Rural, Bachelors or college degree, Rent owned mix
Rural,High School Education, Owns property
Young, City based renters in Sparse neighborhoods, Low poverty
Low income, minority mix
Predominantly black, high high school attainment, home owners
White and minority mix multilingual, mixed income / education. Married
Hispanic Black mix multilingual, high poverty, renters, uses public transport
Predominantly black renters, rent own mix
Middle income, single family homes
Lower Middle Income with higher rent burden
Black and mixed community with rent burden
Lower Middle Income with affordable housing
Relatively affordable, satisfied lower middle class
Satisfied Lower Middle Income Higher Rent Costs
Suburban/Rural Satisfied, decently educated lower middle class
Struggling lower middle class with rent burden
Older white home owners, less comfortable financially
Older home owners, more financially comfortable, some diversity
Native American
Younger, poorer,single parent family Native Americans
Older, middle income Native Americans once married and Educated
Old Wealthy, White
Older, mixed race professionals
Works from home, Highly Educated, Super Wealthy
Retired Grandparents
Wealthy and Rural Living
Wealthy, Retired Mountains/Coasts
Wealthy Diverse Suburbanites On the Coasts
Retirement Communitties
Low Income African American
Urban - Inner city
Rural families
Residential institutions, young people
College towns
College town with poverty
University campus wider area
City Outskirt University Campuses
City Center University Campuses
Wealthy Nuclear Families
Lower educational attainment, Homeowner, Low rent
Younger, Long Commuter in dense neighborhood
Long commuters White black mix
Low rent in built up neighborhoods
Renters within cities, mixed income areas, White/Hispanic mix, Unmarried
Older Home owners with high income
Older home owners and very high income
White Asian Mix Big City Burbs Dwellers
Bachelors degree Mid income With Mortgages
Asian Hispanic Mix, Mid income
Bachelors degree Higher income Home Owners
Wealthy, urban, and kid-free
Wealthy city commuters
New Developments
Very wealthy, multiple million dollar homes
High rise, dense urbanites
- - -#### Examples - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetSegmentSnapshot({{point geometry}}) -``` - -###### Get the Geographic Snapshot of a Segmentation - -__Get the Segmentation Snapshot around the MGM Grand__ - - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetSegmentSnapshot(CDB_LatLng(36.10222, -115.169516)) -``` - -__Get the Segmentation Snapshot at CARTO's NYC HQ__ - - -```bash -https://{username}.carto.com/api/v2/sql?q=SELECT * FROM -OBS_GetSegmentSnapshot(CDB_LatLng(40.704512, -73.936669)) -``` diff --git a/docs/developer-center/support/03-quota-information.md b/docs/developer-center/support/03-quota-information.md index 1a50dc9..74d29d1 100644 --- a/docs/developer-center/support/03-quota-information.md +++ b/docs/developer-center/support/03-quota-information.md @@ -39,7 +39,6 @@ Service Types: * `'isolines'` [Isoline/Isochrones (isochrone/isodistance lines) service]({{site.dataservicesapi_docs}}/reference/#isoline_functions/) * `'hires_geocoder'` [Street level geocoding]({{site.dataservicesapi_docs}}/reference/#street-level-geocoder) * `'routing'` [Routing functions]({{site.dataservicesapi_docs}}/reference/#routing_functions/) -* `'observatory'` Data Observatory services ([demographic]({{site.dataservicesapi_docs}}/reference/#demographic_functions/) and [segmentation]({{site.dataservicesapi_docs}}/reference/#segmentation_functions/) functions) **Notes** @@ -62,12 +61,11 @@ Result: isolines | 100 | 0 | f | tomtom hires_geocoder | 100 | 0 | f | tomtom routing | 50 | 0 | f | tomtom - observatory | 0 | 0 | f | data observatory (4 rows) ``` -In this case, notice that the user has no access to the observatory services. All quotas are *hard-limited* (no soft limits), and no quota has been used in the present period. +All quotas are *hard-limited* (no soft limits), and no quota has been used in the present period. ### cdb_enough_quota(service text ,input_size numeric) diff --git a/docs/internal/quota_management.md b/docs/internal/quota_management.md index 7ce35c9..f0ecf52 100644 --- a/docs/internal/quota_management.md +++ b/docs/internal/quota_management.md @@ -56,11 +56,9 @@ This operation could be done through the rails console: - Geocoding (street level): `geocoding_quota`, `soft_geocoding_limit` - Isolines: `here_isolines_quota`, `soft_here_isolines_limit` - - Data observatory snapshot: `obs_snapshot_quota`, `soft_obs_snapshot_limit` - - Data observatory general: `obs_general_quota`, `soft_obs_general_limit` ### How is the quota spent?### -Almost in all the services: geocoding, data observatory snapshot and general the number of spent credits is calculated per request made (either successful or empty request). +Almost in all the services: geocoding and general the number of spent credits is calculated per request made (either successful or empty request). In the case of the isolines service, the number of credits is calculated based on the number of isolines generated by the request. Ie. If your query generates 3 isolines for the request, you've spent 3 isolines credits. \ No newline at end of file diff --git a/server/extension/Makefile b/server/extension/Makefile index 07763ed..1dbe317 100644 --- a/server/extension/Makefile +++ b/server/extension/Makefile @@ -1,7 +1,7 @@ # Makefile to generate the extension out of separate sql source files. # Once a version is released, it is not meant to be changed. E.g: once version 0.0.1 is out, it SHALL NOT be changed. EXTENSION = cdb_dataservices_server -EXTVERSION = 0.39.3 +EXTVERSION = 0.40.0 # The new version to be generated from templates SED ?= sed diff --git a/server/extension/carto-package.json b/server/extension/carto-package.json index 2091a1a..68f3168 100644 --- a/server/extension/carto-package.json +++ b/server/extension/carto-package.json @@ -7,8 +7,7 @@ "carto_postgresql_ext": "^0.36.0" }, "works_with": { - "dataservices-api-server-python-lib": "^0.23.1", - "observatory-server-extension": "^1.9.0" + "dataservices-api-server-python-lib": "^0.23.1" } } } \ No newline at end of file diff --git a/server/extension/cdb_dataservices_server--0.39.3--0.40.0.sql b/server/extension/cdb_dataservices_server--0.39.3--0.40.0.sql new file mode 100644 index 0000000..6880789 --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.39.3--0.40.0.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.40.0'" to load this file. \quit + +-- HERE goes your code to upgrade/downgrade + +DROP FUNCTION IF EXISTS cdb_dataservices_server._obs_server_conn_str(TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_demographic_snapshot(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_GetDemographicSnapshot(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_segment_snapshot(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_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_GetMeasureById(TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetMeasureById(TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetData(TEXT, TEXT, geomval[], JSON, BOOLEAN); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetData(TEXT, TEXT, geomval[], JSON, BOOLEAN); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetData(TEXT, TEXT, TEXT[], JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetData(TEXT, TEXT, TEXT[], JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetMeta(TEXT, TEXT, geometry(Geometry, 4326), JSON, INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetMeta(TEXT, TEXT, geometry(Geometry, 4326), JSON, INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_MetadataValidation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, JSON, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_MetadataValidation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, JSON, INTEGER); +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, geometry(Point, 4326), NUMERIC, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius(TEXT, TEXT, geometry(Point, 4326), 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); +DROP FUNCTION IF EXISTS cdb_dataservices_server._DST_ConnectUserTable(TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.__DST_ConnectUserTable(TEXT, TEXT, TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._DST_GetReturnMetadata(TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_server._DST_FetchJoinFdwTableData(TEXT, TEXT, TEXT, TEXT, TEXT, JSON); +DROP FUNCTION IF EXISTS cdb_dataservices_server._DST_DisconnectUserTable(TEXT, TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_DumpVersion(TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableNumerators(TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableDenominators(TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableGeometries(TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT, INTEGER); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableTimespans(TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_LegacyBuilderMetadata(TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetNumerators (TEXT, TEXT, geometry(Geometry, 4326), TEXT[], TEXT[] , TEXT[], TEXT[] , TEXT, TEXT, TEXT, TEXT); +DROP FUNCTION IF EXISTS cdb_dataservices_server._get_obs_config(TEXT, TEXT); + +DELETE FROM pg_enum +WHERE enumlabel = 'observatory' +AND enumtypid = ( + SELECT pg_type.oid + FROM pg_type INNER JOIN pg_namespace ON (pg_type.typnamespace = pg_namespace.oid) + WHERE pg_type.typname = 'service_type' AND pg_namespace.nspname = 'cdb_dataservices_server' +); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_quota_info( + username TEXT, + orgname TEXT) +RETURNS SETOF cdb_dataservices_server.service_quota_info AS $$ + from cartodb_services.metrics.user import UserMetricsService + from datetime import date + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + + today = date.today() + ret = [] + + #-- Isolines + service = 'isolines' + plpy.execute("SELECT cdb_dataservices_server._get_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_isolines_config, redis_conn) + + monthly_quota = user_isolines_config.isolines_quota + used_quota = user_service.used_quota(user_isolines_config.service_type, today) + soft_limit = user_isolines_config.soft_isolines_limit + provider = user_isolines_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Hires Geocoder + service = 'hires_geocoder' + plpy.execute("SELECT cdb_dataservices_server._get_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + user_service = UserMetricsService(user_geocoder_config, redis_conn) + + monthly_quota = user_geocoder_config.geocoding_quota + used_quota = user_service.used_quota(user_geocoder_config.service_type, today) + soft_limit = user_geocoder_config.soft_geocoding_limit + provider = user_geocoder_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Routing + service = 'routing' + plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_routing_config = GD["user_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_routing_config, redis_conn) + + monthly_quota = user_routing_config.monthly_quota + used_quota = user_service.used_quota(user_routing_config.service_type, today) + soft_limit = user_routing_config.soft_limit + provider = user_routing_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Observatory + service = 'observatory' + 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)] + user_service = UserMetricsService(user_obs_config, redis_conn) + + monthly_quota = user_obs_config.monthly_quota + used_quota = user_service.used_quota(user_obs_config.service_type, today) + soft_limit = user_obs_config.soft_limit + provider = user_obs_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + return ret +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/cdb_dataservices_server--0.40.0--0.39.3.sql b/server/extension/cdb_dataservices_server--0.40.0--0.39.3.sql new file mode 100644 index 0000000..29b8c87 --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.40.0--0.39.3.sql @@ -0,0 +1,1513 @@ +--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.39.3'" to load this file. \quit + +-- HERE goes your code to upgrade/downgrade + +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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + return user_obs_config.connection_str +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + 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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getdemographicsnapshot', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to obs_get_demographic_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to obs_get_demographic_snapshot') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getdemographicsnapshot', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to obs_get_demographic_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to obs_get_demographic_snapshot') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + 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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getsegmentsnapshot', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to obs_get_segment_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to obs_get_segment_snapshot') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getsegmentsnapshot', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetSegmentSnapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetSegmentSnapshot') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT NULL, + 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 VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + measure_id TEXT, + normalize TEXT DEFAULT NULL, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getmeasure', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetMeasure', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetMeasure') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getcategory', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetCategory', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetCategory') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT NULL, + 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 VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + name TEXT, + normalize TEXT DEFAULT NULL, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getuscensusmeasure', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetUSCensusMeasure', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetUSCensusMeasure') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getuscensuscategory', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetUSCensusCategory', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetUSCensusCategory') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT NULL, + 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 VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation( + username TEXT, + orgname TEXT, + geom geometry(Geometry, 4326), + normalize TEXT DEFAULT NULL, + boundary_id TEXT DEFAULT NULL, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getpopulation', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetPopulation', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetPopulation') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasureById( + username TEXT, + orgname TEXT, + geom_ref TEXT, + measure_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetMeasureById(geom_ref, measure_id, boundary_id, time_span); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasureById( + username TEXT, + orgname TEXT, + geom_ref TEXT, + measure_id TEXT, + boundary_id TEXT, + time_span TEXT DEFAULT NULL) +RETURNS NUMERIC AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getmeasurebyid', user_obs_config, logger): + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasureById($1, $2, $3, $4, $5, $6) as measure;", ["text", "text", "text", "text", "text", "text"]) + result = plpy.execute(obs_plan, [username, orgname, geom_ref, measure_id, 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetMeasureById', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetMeasureById') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetData( + username TEXT, + orgname TEXT, + geomvals geomval[], + params JSON, + merge BOOLEAN DEFAULT True) +RETURNS TABLE ( + id INT, + data JSON +) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetData(geomvals, params, merge); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData( + username TEXT, + orgname TEXT, + geomvals geomval[], + params JSON, + merge BOOLEAN DEFAULT True) +RETURNS TABLE ( + id INT, + data JSON +) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getdata', user_obs_config, logger, params): + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4, $5);", ["text", "text", "geomval[]", "json", "boolean"]) + result = plpy.execute(obs_plan, [username, orgname, geomvals, params, merge]) + empty_results = len(geomvals) - len(result) + if empty_results > 0: + quota_service.increment_empty_service_use(empty_results) + if result: + quota_service.increment_success_service_use(len(result)) + return result + else: + return [] + except BaseException as e: + import sys + quota_service.increment_failed_service_use(len(geomvals)) + logger.error('Error trying to OBS_GetData', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetData') + finally: + quota_service.increment_total_service_use(len(geomvals)) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetData( + username TEXT, + orgname TEXT, + geomrefs TEXT[], + params JSON) +RETURNS TABLE ( + id TEXT, + data JSON +) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetData(geomrefs, params); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData( + username TEXT, + orgname TEXT, + geomrefs TEXT[], + params JSON) +RETURNS TABLE ( + id TEXT, + data JSON +) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getdata', user_obs_config, logger, params): + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4);", ["text", "text", "text[]", "json"]) + result = plpy.execute(obs_plan, [username, orgname, geomrefs, params]) + empty_results = len(geomrefs) - len(result) + if empty_results > 0: + quota_service.increment_empty_service_use(empty_results) + if result: + quota_service.increment_success_service_use(len(result)) + return result + else: + return [] + except BaseException as e: + import sys + quota_service.increment_failed_service_use(len(geomrefs)) + exc_info = sys.exc_info() + logger.error('%s, %s, %s' % (exc_info[0], exc_info[1], exc_info[2])) + logger.error('Error trying to OBS_GetData', exc_info, data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetData') + finally: + quota_service.increment_total_service_use(len(geomrefs)) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeta( + username TEXT, + orgname TEXT, + geom Geometry(Geometry, 4326), + params JSON, + max_timespan_rank INTEGER DEFAULT NULL, + max_score_rank INTEGER DEFAULT NULL, + target_geoms INTEGER DEFAULT NULL) +RETURNS JSON AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.OBS_GetMeta(geom, params, max_timespan_rank, max_score_rank, target_geoms); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeta( + username TEXT, + orgname TEXT, + geom Geometry(Geometry, 4326), + params JSON, + max_timespan_rank INTEGER DEFAULT NULL, + max_score_rank INTEGER DEFAULT NULL, + target_geoms INTEGER DEFAULT NULL) +RETURNS JSON AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + with metrics('obs_getmeta', user_obs_config, logger, params): + try: + obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeta($1, $2, $3, $4, $5, $6, $7) as meta;", ["text", "text", "Geometry (Geometry, 4326)", "json", "integer", "integer", "integer"]) + result = plpy.execute(obs_plan, [username, orgname, geom, params, max_timespan_rank, max_score_rank, target_geoms]) + if result: + return result[0]['meta'] + else: + return None + except BaseException as e: + import sys + logger.error('Error trying to OBS_GetMeta', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetMeta') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_MetadataValidation( + username TEXT, + orgname TEXT, + geometry_extent Geometry(Geometry, 4326), + geometry_type text, + params JSON, + target_geoms INTEGER DEFAULT NULL) +RETURNS TABLE(valid boolean, errors text[]) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_MetadataValidation(geometry_extent, geometry_type, params, target_geoms); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_MetadataValidation( + username TEXT, + orgname TEXT, + geometry_extent Geometry(Geometry, 4326), + geometry_type text, + params JSON, + target_geoms INTEGER DEFAULT NULL) +RETURNS TABLE(valid boolean, errors text[]) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + with metrics('obs_metadatavalidation', user_obs_config, logger): + try: + obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_MetadataValidation($1, $2, $3, $4, $5, $6);", ["text", "text", "Geometry (Geometry, 4326)", "text", "json", "integer"]) + result = plpy.execute(obs_plan, [username, orgname, geometry_extent, geometry_type, params, target_geoms]) + if result: + return result + else: + return [] + except BaseException as e: + import sys + logger.error('Error trying to OBS_MetadataValidation', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_MetadataValidation') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_search', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_Search', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_Search') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getavailableboundaries', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetMeasureById', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetMeasureById') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getboundary', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetBoundary', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetBoundary') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getboundaryid', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetBoundaryId', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetBoundaryId') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 VOLATILE PARALLEL UNSAFE; + +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 metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getboundarybyid', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetBoundaryById', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetBoundaryById') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 NULL) +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 VOLATILE PARALLEL UNSAFE; + +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 NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getboundariesbygeometry', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetBoundariesByGeometry', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetBoundariesByGeometry') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 NULL) +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 VOLATILE PARALLEL UNSAFE; + +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 NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getboundariesbypointandradius', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetBoundariesByPointAndRadius', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetBoundariesByPointAndRadius') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 NULL) +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 VOLATILE PARALLEL UNSAFE; + +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 NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getpointsbygeometry', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetPointsByGeometry', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetPointsByGeometry') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +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 NULL) +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 VOLATILE PARALLEL UNSAFE; + +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 NULL) +RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_obs_config = GD["user_obs_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_obs_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + with metrics('obs_getpointsbypointandradius', user_obs_config, logger): + 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 + quota_service.increment_failed_service_use() + logger.error('Error trying to OBS_GetPointsByPointAndRadius', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to OBS_GetPointsByPointAndRadius') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE TYPE cdb_dataservices_server.ds_fdw_metadata as (schemaname text, tabname text, servername text); + +CREATE TYPE cdb_dataservices_server.ds_return_metadata as (colnames text[], coltypes text[]); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, table_name text) +RETURNS cdb_dataservices_server.ds_fdw_metadata AS $$ + host_addr = plpy.execute("SELECT split_part(inet_client_addr()::text, '/', 1) as user_host")[0]['user_host'] + return plpy.execute("SELECT * FROM cdb_dataservices_server.__DST_ConnectUserTable({username}::text, {orgname}::text, {user_db_role}::text, {schema}::text, {dbname}::text, {host_addr}::text, {table_name}::text)" + .format(username=plpy.quote_nullable(username), orgname=plpy.quote_nullable(orgname), user_db_role=plpy.quote_literal(user_db_role), schema=plpy.quote_literal(input_schema), dbname=plpy.quote_literal(dbname), table_name=plpy.quote_literal(table_name), host_addr=plpy.quote_literal(host_addr)) + )[0] +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.__DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, host_addr text, table_name text) +RETURNS cdb_dataservices_server.ds_fdw_metadata AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + TARGET cdb_observatory._OBS_ConnectUserTable; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_GetReturnMetadata(username text, orgname text, function_name text, params json) +RETURNS cdb_dataservices_server.ds_return_metadata AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + TARGET cdb_observatory._OBS_GetReturnMetadata; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_FetchJoinFdwTableData(username text, orgname text, table_schema text, table_name text, function_name text, params json) +RETURNS SETOF record AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + TARGET cdb_observatory._OBS_FetchJoinFdwTableData; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_DisconnectUserTable(username text, orgname text, table_schema text, table_name text, servername text) +RETURNS boolean AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + TARGET cdb_observatory._OBS_DisconnectUserTable; +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_dumpversion(username text, orgname text) +RETURNS text AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT cdb_observatory.obs_dumpversion(); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +-- We could create a super type for the common data like id, name and so on but we need to parse inside the functions because the -- the return data tha comes from OBS is a TABLE() with them +CREATE TYPE cdb_dataservices_server.obs_meta_numerator AS (numer_id text, numer_name text, numer_description text, numer_weight text, numer_license text, numer_source text, numer_type text, numer_aggregate text, numer_extra jsonb, numer_tags jsonb, valid_denom boolean, valid_geom boolean, valid_timespan boolean); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableNumerators( + username TEXT, + orgname TEXT, + bounds geometry(Geometry, 4326) DEFAULT NULL, + filter_tags TEXT[] DEFAULT NULL, + denom_id TEXT DEFAULT NULL, + geom_id TEXT DEFAULT NULL, + timespan TEXT DEFAULT NULL) +RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(bounds, filter_tags, denom_id, geom_id, timespan); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetNumerators( + username TEXT, + orgname TEXT, + bounds geometry(Geometry, 4326) DEFAULT NULL, + section_tags TEXT[] DEFAULT ARRAY[]::TEXT[], + subsection_tags TEXT[] DEFAULT ARRAY[]::TEXT[], + other_tags TEXT[] DEFAULT ARRAY[]::TEXT[], + ids TEXT[] DEFAULT ARRAY[]::TEXT[], + name TEXT DEFAULT NULL, + denom_id TEXT DEFAULT '', + geom_id TEXT DEFAULT '', + timespan TEXT DEFAULT '') +RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory._OBS_GetNumerators(bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE TYPE cdb_dataservices_server.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableDenominators( + username TEXT, + orgname TEXT, + bounds geometry(Geometry, 4326) DEFAULT NULL, + filter_tags TEXT[] DEFAULT NULL, + numer_id TEXT DEFAULT NULL, + geom_id TEXT DEFAULT NULL, + timespan TEXT DEFAULT NULL) +RETURNS SETOF cdb_dataservices_server.obs_meta_denominator AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableDenominators(bounds, filter_tags, numer_id, geom_id, timespan); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE TYPE cdb_dataservices_server.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableGeometries( + username TEXT, + orgname TEXT, + bounds geometry(Geometry, 4326) DEFAULT NULL, + filter_tags TEXT[] DEFAULT NULL, + numer_id TEXT DEFAULT NULL, + denom_id TEXT DEFAULT NULL, + timespan TEXT DEFAULT NULL, + number_geometries INTEGER DEFAULT NULL) +RETURNS SETOF cdb_dataservices_server.obs_meta_geometry AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableGeometries(bounds, filter_tags, numer_id, denom_id, timespan, number_geometries); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE TYPE cdb_dataservices_server.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableTimespans( + username TEXT, + orgname TEXT, + bounds geometry(Geometry, 4326) DEFAULT NULL, + filter_tags TEXT[] DEFAULT NULL, + numer_id TEXT DEFAULT NULL, + denom_id TEXT DEFAULT NULL, + geom_id TEXT DEFAULT NULL) +RETURNS SETOF cdb_dataservices_server.obs_meta_timespan AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_GetAvailableTimespans(bounds, filter_tags, numer_id, denom_id, geom_id); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_LegacyBuilderMetadata( + username TEXT, + orgname TEXT, + aggregate_type TEXT DEFAULT NULL) +RETURNS TABLE(name TEXT, subsection JSON) AS $$ + CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); + SELECT * FROM cdb_observatory.OBS_LegacyBuilderMetadata(aggregate_type); +$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; + +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 STABLE PARALLEL RESTRICTED; + +ALTER TYPE cdb_dataservices_server.service_type ADD VALUE 'observatory' AFTER 'routing'; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_quota_info( + username TEXT, + orgname TEXT) +RETURNS SETOF cdb_dataservices_server.service_quota_info AS $$ + from cartodb_services.metrics.user import UserMetricsService + from datetime import date + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + + today = date.today() + ret = [] + + #-- Isolines + service = 'isolines' + plpy.execute("SELECT cdb_dataservices_server._get_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_isolines_config, redis_conn) + + monthly_quota = user_isolines_config.isolines_quota + used_quota = user_service.used_quota(user_isolines_config.service_type, today) + soft_limit = user_isolines_config.soft_isolines_limit + provider = user_isolines_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Hires Geocoder + service = 'hires_geocoder' + plpy.execute("SELECT cdb_dataservices_server._get_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + user_service = UserMetricsService(user_geocoder_config, redis_conn) + + monthly_quota = user_geocoder_config.geocoding_quota + used_quota = user_service.used_quota(user_geocoder_config.service_type, today) + soft_limit = user_geocoder_config.soft_geocoding_limit + provider = user_geocoder_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Routing + service = 'routing' + plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_routing_config = GD["user_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_routing_config, redis_conn) + + monthly_quota = user_routing_config.monthly_quota + used_quota = user_service.used_quota(user_routing_config.service_type, today) + soft_limit = user_routing_config.soft_limit + provider = user_routing_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Observatory + service = 'observatory' + 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)] + user_service = UserMetricsService(user_obs_config, redis_conn) + + monthly_quota = user_obs_config.monthly_quota + used_quota = user_service.used_quota(user_obs_config.service_type, today) + soft_limit = user_obs_config.soft_limit + provider = user_obs_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + return ret +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/cdb_dataservices_server--0.40.0.sql b/server/extension/cdb_dataservices_server--0.40.0.sql new file mode 100644 index 0000000..6d2124c --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.40.0.sql @@ -0,0 +1,2414 @@ +--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 "CREATE EXTENSION cdb_dataservices_server" to load this file. \quit +CREATE TYPE cdb_dataservices_server.simple_route AS ( + shape geometry(LineString,4326), + length real, + duration integer +); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_route_with_waypoints( + username TEXT, + orgname TEXT, + waypoints geometry(Point, 4326)[], + mode TEXT, + options text[] DEFAULT ARRAY[]::text[], + units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_server.simple_route AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.mapbox import MapboxRouting + from cartodb_services.mapbox.types import TRANSPORT_MODE_TO_MAPBOX + from cartodb_services.tools import Coordinate + from cartodb_services.tools.polyline import polyline_to_linestring + from cartodb_services.tools.normalize import options_to_dict + from cartodb_services.refactor.service.mapbox_routing_config import MapboxRoutingConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('routing', MapboxRoutingConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + client = MapboxRouting(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params) + + if not waypoints or len(waypoints) < 2: + service_manager.logger.info("Empty origin or destination") + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + + if len(waypoints) > 25: + service_manager.logger.info("Too many waypoints (max 25)") + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + + waypoint_coords = [] + for waypoint in waypoints: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoint)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoint)[0]['lon'] + waypoint_coords.append(Coordinate(lon,lat)) + + profile = TRANSPORT_MODE_TO_MAPBOX.get(mode) + options_dict = options_to_dict(options) + if 'mode_type' in options_dict: + plpy.warning('Mapbox provider doesnt support route type parameter') + + resp = client.directions(waypoint_coords, profile) + if resp and resp.shape: + shape_linestring = polyline_to_linestring(resp.shape) + if shape_linestring: + service_manager.quota_service.increment_success_service_use() + return [shape_linestring, resp.length, int(round(resp.duration))] + else: + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + else: + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to calculate Mapbox routing', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to calculate Mapbox routing: ' + str(e)) + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_route_with_waypoints( + username TEXT, + orgname TEXT, + waypoints geometry(Point, 4326)[], + mode TEXT, + options text[] DEFAULT ARRAY[]::text[], + units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_server.simple_route AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.tomtom import TomTomRouting + from cartodb_services.tomtom.types import TRANSPORT_MODE_TO_TOMTOM, DEFAULT_ROUTE_TYPE, MODE_TYPE_TO_TOMTOM + from cartodb_services.tools import Coordinate + from cartodb_services.tools.polyline import polyline_to_linestring + from cartodb_services.tools.normalize import options_to_dict + from cartodb_services.refactor.service.tomtom_routing_config import TomTomRoutingConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('routing', TomTomRoutingConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + client = TomTomRouting(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params) + + if not waypoints or len(waypoints) < 2: + service_manager.logger.info("Empty origin or destination") + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + + if len(waypoints) > 25: + service_manager.logger.info("Too many waypoints (max 25)") + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + + waypoint_coords = [] + for waypoint in waypoints: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoint)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoint)[0]['lon'] + waypoint_coords.append(Coordinate(lon,lat)) + + profile = TRANSPORT_MODE_TO_TOMTOM.get(mode) + route_type = DEFAULT_ROUTE_TYPE + options_dict = options_to_dict(options) + if 'mode_type' in options_dict: + route_type = MODE_TYPE_TO_TOMTOM.get(options_dict['mode_type']) + + resp = client.directions(waypoint_coords, profile=profile, route_type=route_type) + if resp and resp.shape: + shape_linestring = polyline_to_linestring(resp.shape) + if shape_linestring: + service_manager.quota_service.increment_success_service_use() + return [shape_linestring, resp.length, int(round(resp.duration))] + else: + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + else: + service_manager.quota_service.increment_empty_service_use() + return [None, None, None] + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to calculate TomTom routing', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to calculate TomTom routing: ' + str(e)) + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_with_waypoints( + username TEXT, + orgname TEXT, + waypoints geometry(Point, 4326)[], + mode TEXT, + options text[] DEFAULT ARRAY[]::text[], + units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_server.simple_route AS $$ + import json + from cartodb_services.mapzen import MapzenRouting, MapzenRoutingResponse + from cartodb_services.mapzen.types import polyline_to_linestring + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Coordinate + from cartodb_services.tools import Logger,LoggerConfig + + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + user_routing_config = GD["user_routing_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + quota_service = QuotaService(user_routing_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + try: + client = MapzenRouting(user_routing_config.mapzen_api_key, logger, user_routing_config.mapzen_service_params) + + if not waypoints or len(waypoints) < 2: + logger.info("Empty origin or destination") + quota_service.increment_empty_service_use() + return [None, None, None] + + waypoint_coords = [] + for waypoint in waypoints: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoint)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoint)[0]['lon'] + waypoint_coords.append(Coordinate(lon,lat)) + + resp = client.calculate_route_point_to_point(waypoint_coords, mode, options, units) + if resp and resp.shape: + shape_linestring = polyline_to_linestring(resp.shape) + if shape_linestring: + quota_service.increment_success_service_use() + return [shape_linestring, resp.length, resp.duration] + else: + quota_service.increment_empty_service_use() + return [None, None, None] + else: + quota_service.increment_empty_service_use() + return [None, None, None] + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to calculate mapzen routing', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to calculate mapzen routing') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_point_to_point( + username TEXT, + orgname TEXT, + origin geometry(Point, 4326), + destination geometry(Point, 4326), + mode TEXT, + options text[] DEFAULT ARRAY[]::text[], + units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_server.simple_route AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger + + 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_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_routing_config = GD["user_routing_config_{0}".format(username)] + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'origin': origin, 'destination': destination, 'mode': mode, 'options': options, 'units': units} + + with metrics('cdb_route_with_point', user_routing_config, logger, params): + waypoints = [origin, destination] + + if user_routing_config.mapzen_provider: + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + elif user_routing_config.mapbox_provider: + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapbox_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(mapbox_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + elif user_routing_config.tomtom_provider: + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_tomtom_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(tomtom_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + else: + raise Exception('Requested routing method is not available') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_with_waypoints( + username TEXT, + orgname TEXT, + waypoints geometry(Point, 4326)[], + mode TEXT, + options text[] DEFAULT ARRAY[]::text[], + units text DEFAULT 'kilometers') +RETURNS cdb_dataservices_server.simple_route AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger + + 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_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_routing_config = GD["user_routing_config_{0}".format(username)] + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'waypoints': waypoints, 'mode': mode, 'options': options, 'units': units} + + with metrics('cdb_route_with_waypoints', user_routing_config, logger, params): + if user_routing_config.mapzen_provider: + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + elif user_routing_config.mapbox_provider: + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapbox_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(mapbox_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + elif user_routing_config.tomtom_provider: + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_tomtom_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"]) + result = plpy.execute(tomtom_plan, [username, orgname, waypoints, mode, options, units]) + return [result[0]['shape'],result[0]['length'], result[0]['duration']] + else: + raise Exception('Requested routing method is not available') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +-- Get the connection to redis from cache or create a new one +CREATE OR REPLACE FUNCTION cdb_dataservices_server._connect_to_redis(user_id text) +RETURNS boolean AS $$ + cache_key = "redis_connection_{0}".format(user_id) + if cache_key in GD: + return False + else: + from cartodb_services.tools import RedisConnection, RedisDBConfig + metadata_config = RedisDBConfig('redis_metadata_config', plpy) + metrics_config = RedisDBConfig('redis_metrics_config', plpy) + redis_metadata_connection = RedisConnection(metadata_config).redis_connection() + redis_metrics_connection = RedisConnection(metrics_config).redis_connection() + GD[cache_key] = { + 'redis_metadata_connection': redis_metadata_connection, + 'redis_metrics_connection': redis_metrics_connection, + } + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_logger_config() +RETURNS boolean AS $$ + cache_key = "logger_config" + if cache_key in GD: + return False + else: + from cartodb_services.tools import LoggerConfig + logger_config = LoggerConfig(plpy) + GD[cache_key] = logger_config + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +-- This is done in order to avoid an undesired depedency on cartodb extension +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_conf_getconf(input_key text) +RETURNS JSON AS $$ + SELECT VALUE FROM cartodb.cdb_conf WHERE key = input_key; +$$ LANGUAGE SQL SECURITY DEFINER STABLE PARALLEL SAFE; + +CREATE OR REPLACE +FUNCTION cdb_dataservices_server.CDB_Conf_SetConf(key text, value JSON) + RETURNS void AS $$ +BEGIN + PERFORM cdb_dataservices_server.CDB_Conf_RemoveConf(key); + EXECUTE 'INSERT INTO cartodb.CDB_CONF (KEY, VALUE) VALUES ($1, $2);' USING key, value; +END +$$ LANGUAGE PLPGSQL SECURITY DEFINER VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE +FUNCTION cdb_dataservices_server.CDB_Conf_RemoveConf(key text) + RETURNS void AS $$ +BEGIN + EXECUTE 'DELETE FROM cartodb.CDB_CONF WHERE KEY = $1;' USING key; +END +$$ LANGUAGE PLPGSQL SECURITY DEFINER VOLATILE PARALLEL UNSAFE ; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_geocoder_config(username text, orgname text, provider text DEFAULT NULL) +RETURNS boolean AS $$ + cache_key = "user_geocoder_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import GeocoderConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + geocoder_config = GeocoderConfig(redis_conn, plpy, username, orgname, provider) + GD[cache_key] = geocoder_config + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_internal_geocoder_config(username text, orgname text) +RETURNS boolean AS $$ + cache_key = "user_internal_geocoder_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import InternalGeocoderConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + geocoder_config = InternalGeocoderConfig(redis_conn, plpy, username, orgname) + GD[cache_key] = geocoder_config + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_isolines_routing_config(username text, orgname text) +RETURNS boolean AS $$ + cache_key = "user_isolines_routing_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import IsolinesRoutingConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + isolines_routing_config = IsolinesRoutingConfig(redis_conn, plpy, username, orgname) + GD[cache_key] = isolines_routing_config + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_routing_config(username text, orgname text) +RETURNS boolean AS $$ + cache_key = "user_routing_config_{0}".format(username) + if cache_key in GD: + return False + else: + from cartodb_services.metrics import RoutingConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection'] + routing_config = RoutingConfig(redis_conn, plpy, username, orgname) + GD[cache_key] = routing_config + return True +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER; +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type inner join pg_namespace ON (pg_type.typnamespace = pg_namespace.oid) + WHERE pg_type.typname = 'service_type' + AND pg_namespace.nspname = 'cdb_dataservices_server') THEN + CREATE TYPE cdb_dataservices_server.service_type AS ENUM ( + 'isolines', + 'hires_geocoder', + 'routing' + ); + END IF; +END $$; + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type inner join pg_namespace ON (pg_type.typnamespace = pg_namespace.oid) + WHERE pg_type.typname = 'service_quota_info' + AND pg_namespace.nspname = 'cdb_dataservices_server') THEN + CREATE TYPE cdb_dataservices_server.service_quota_info AS ( + service cdb_dataservices_server.service_type, + monthly_quota NUMERIC, + used_quota NUMERIC, + soft_limit BOOLEAN, + provider TEXT + ); + END IF; +END $$; + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type inner join pg_namespace ON (pg_type.typnamespace = pg_namespace.oid) + WHERE pg_type.typname = 'service_quota_info_batch' + AND pg_namespace.nspname = 'cdb_dataservices_server') THEN + CREATE TYPE cdb_dataservices_server.service_quota_info_batch AS ( + service cdb_dataservices_server.service_type, + monthly_quota NUMERIC, + used_quota NUMERIC, + soft_limit BOOLEAN, + provider TEXT, + max_batch_size NUMERIC + ); + END IF; +END $$; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_quota_info( + username TEXT, + orgname TEXT) +RETURNS SETOF cdb_dataservices_server.service_quota_info AS $$ + from cartodb_services.metrics.user import UserMetricsService + from datetime import date + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + + today = date.today() + ret = [] + + #-- Isolines + service = 'isolines' + plpy.execute("SELECT cdb_dataservices_server._get_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_isolines_config, redis_conn) + + monthly_quota = user_isolines_config.isolines_quota + used_quota = user_service.used_quota(user_isolines_config.service_type, today) + soft_limit = user_isolines_config.soft_isolines_limit + provider = user_isolines_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Hires Geocoder + service = 'hires_geocoder' + plpy.execute("SELECT cdb_dataservices_server._get_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + user_service = UserMetricsService(user_geocoder_config, redis_conn) + + monthly_quota = user_geocoder_config.geocoding_quota + used_quota = user_service.used_quota(user_geocoder_config.service_type, today) + soft_limit = user_geocoder_config.soft_geocoding_limit + provider = user_geocoder_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + #-- Routing + service = 'routing' + plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_routing_config = GD["user_routing_config_{0}".format(username)] + user_service = UserMetricsService(user_routing_config, redis_conn) + + monthly_quota = user_routing_config.monthly_quota + used_quota = user_service.used_quota(user_routing_config.service_type, today) + soft_limit = user_routing_config.soft_limit + provider = user_routing_config.provider + ret += [[service, monthly_quota, used_quota, soft_limit, provider]] + + return ret +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_quota_info_batch( + username TEXT, + orgname TEXT) +RETURNS SETOF cdb_dataservices_server.service_quota_info_batch AS $$ + from cartodb_services.bulk_geocoders import BATCH_GEOCODER_CLASS_BY_PROVIDER + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + sqi = plpy.execute("SELECT * from cdb_dataservices_server.cdb_service_quota_info({0},{1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + + ret = [] + for info in sqi: + if info['service'] == 'hires_geocoder': + provider = info['provider'] + batch_geocoder_class = BATCH_GEOCODER_CLASS_BY_PROVIDER.get(provider, None) + if batch_geocoder_class and hasattr(batch_geocoder_class, 'MAX_BATCH_SIZE'): + max_batch_size = batch_geocoder_class.MAX_BATCH_SIZE + else: + max_batch_size = 1 + + info['max_batch_size'] = max_batch_size + else: + info['max_batch_size'] = 1 + + ret += [[info['service'], info['monthly_quota'], info['used_quota'], info['soft_limit'], info['provider'], info['max_batch_size']]] + + return ret +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_enough_quota( + username TEXT, + orgname TEXT, + service_ TEXT, + input_size NUMERIC) +returns BOOLEAN AS $$ + DECLARE + params cdb_dataservices_server.service_quota_info; + BEGIN + SELECT * INTO params + FROM cdb_dataservices_server.cdb_service_quota_info(username, orgname) AS p + WHERE p.service = service_::cdb_dataservices_server.service_type; + RETURN params.soft_limit OR ((params.used_quota + input_size) <= params.monthly_quota); + END +$$ LANGUAGE plpgsql STABLE PARALLEL RESTRICTED; +-- Geocodes a street address given a searchtext and a state and/or country + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger,LoggerConfig + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'searchtext': searchtext, 'city': city, 'state_province': state_province, 'country': country} + + with metrics('cdb_geocode_street_point', user_geocoder_config, logger, params): + if user_geocoder_config.heremaps_geocoder: + here_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_here_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(here_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + elif user_geocoder_config.google_geocoder: + google_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_google_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(google_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + elif user_geocoder_config.mapzen_geocoder: + mapzen_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapzen_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(mapzen_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + elif user_geocoder_config.mapbox_geocoder: + mapbox_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapbox_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(mapbox_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + elif user_geocoder_config.tomtom_geocoder: + tomtom_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_tomtom_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(tomtom_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + elif user_geocoder_config.geocodio_geocoder: + geocodio_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocodio_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(geocodio_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + else: + raise Exception('Requested geocoder is not available') + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_here_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + if user_geocoder_config.heremaps_geocoder: + here_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_here_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(here_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + else: + raise Exception('Here geocoder is not available for your account.') + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_google_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + if user_geocoder_config.google_geocoder: + google_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_google_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(google_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + else: + raise Exception('Google geocoder is not available for your account.') + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + # The configuration is retrieved but no checks are performed on it + 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + mapzen_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapzen_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(mapzen_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapbox_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + # The configuration is retrieved but no checks are performed on it + 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + mapbox_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapbox_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(mapbox_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_tomtom_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + # The configuration is retrieved but no checks are performed on it + 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + tomtom_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_tomtom_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(tomtom_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocodio_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + # The configuration is retrieved but no checks are performed on it + 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + geocodio_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocodio_geocode_street_point($1, $2, $3, $4, $5, $6) as point; ", ["text", "text", "text", "text", "text", "text"]) + return plpy.execute(geocodio_plan, [username, orgname, searchtext, city, state_province, country], 1)[0]['point'] + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.tools import LegacyServiceManager + from cartodb_services.tools import QuotaExceededException + from cartodb_services.here import HereMapsGeocoder + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + service_manager = LegacyServiceManager('geocoder', username, orgname, GD) + + try: + service_manager.assert_within_limits() + geocoder = HereMapsGeocoder(service_manager.config.heremaps_app_id, service_manager.config.heremaps_app_code, service_manager.logger, service_manager.config.heremaps_service_params) + coordinates = geocoder.geocode(searchtext=searchtext, city=city, state=state_province, country=country) + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using here maps', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using here maps') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_google_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.tools import LegacyServiceManager, QuotaExceededException + from cartodb_services.google import GoogleMapsGeocoder + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + service_manager = LegacyServiceManager('geocoder', username, orgname, GD) + + try: + service_manager.assert_within_limits(quota=False) + geocoder = GoogleMapsGeocoder(service_manager.config.google_client_id, service_manager.config.google_api_key, service_manager.logger) + coordinates = geocoder.geocode(searchtext=searchtext, city=city, state=state_province, country=country) + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using google maps', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using google maps') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.tools import ServiceManager, QuotaExceededException + from cartodb_services.mapzen import MapzenGeocoder + from cartodb_services.tools.country import country_to_iso3 + from cartodb_services.refactor.service.mapzen_geocoder_config import MapzenGeocoderConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('geocoder', MapzenGeocoderConfigBuilder, username, orgname) + + try: + service_manager.assert_within_limits() + geocoder = MapzenGeocoder(service_manager.config.mapzen_api_key, service_manager.logger, service_manager.config.service_params) + country_iso3 = None + if country: + country_iso3 = country_to_iso3(country) + coordinates = geocoder.geocode(searchtext=searchtext, city=city, + state_province=state_province, + country=country_iso3, search_type='address') + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using mapzen', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using mapzen') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from iso3166 import countries + from cartodb_services.tools import ServiceManager, QuotaExceededException + from cartodb_services.mapbox import MapboxGeocoder + from cartodb_services.tools.country import country_to_iso3 + from cartodb_services.refactor.service.mapbox_geocoder_config import MapboxGeocoderConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('geocoder', MapboxGeocoderConfigBuilder, username, orgname, GD) + + try: + service_manager.assert_within_limits() + geocoder = MapboxGeocoder(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params) + + country_iso3166 = None + if country: + country_iso3 = country_to_iso3(country) + if country_iso3: + country_iso3166 = countries.get(country_iso3).alpha2.lower() + + coordinates = geocoder.geocode(searchtext=searchtext, city=city, + state_province=state_province, + country=country_iso3166) + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using Mapbox', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using Mapbox') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.tools import ServiceManager, QuotaExceededException + from cartodb_services.tomtom import TomTomGeocoder + from cartodb_services.refactor.service.tomtom_geocoder_config import TomTomGeocoderConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('geocoder', TomTomGeocoderConfigBuilder, username, orgname, GD) + + try: + service_manager.assert_within_limits() + geocoder = TomTomGeocoder(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params) + + coordinates = geocoder.geocode(searchtext=searchtext, city=city, + state_province=state_province, + country=country) + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using TomTom', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using TomTom') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocodio_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL) +RETURNS Geometry AS $$ + from iso3166 import countries + from cartodb_services.tools import ServiceManager, QuotaExceededException + from cartodb_services.geocodio import GeocodioGeocoder + from cartodb_services.tools.country import country_to_iso3 + from cartodb_services.refactor.service.geocodio_geocoder_config import GeocodioGeocoderConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('geocoder', GeocodioGeocoderConfigBuilder, username, orgname, GD) + + try: + service_manager.assert_within_limits() + geocoder = GeocodioGeocoder(service_manager.config.geocodio_api_key, service_manager.logger, service_manager.config.service_params) + + country_iso3166 = None + if country: + country_iso3 = country_to_iso3(country) + if country_iso3: + country_iso3166 = countries.get(country_iso3).alpha2.lower() + + coordinates = geocoder.geocode(searchtext=searchtext, city=city, + state_province=state_province, + country=country_iso3166) + if coordinates: + service_manager.quota_service.increment_success_service_use() + plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"]) + point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0] + return point['st_setsrid'] + else: + service_manager.quota_service.increment_empty_service_use() + return None + except QuotaExceededException as qe: + service_manager.quota_service.increment_failed_service_use() + return None + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to geocode street point using Geocodio', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode street point using Geocodio') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_get_rate_limit( + username TEXT, + orgname TEXT, + service TEXT) +RETURNS JSON AS $$ + import json + from cartodb_services.config import ServiceConfiguration, RateLimitsConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_config = ServiceConfiguration(service, username, orgname) + rate_limit_config = RateLimitsConfigBuilder(service_config.server, service_config.user, service_config.org, service=service, username=username, orgname=orgname).get() + if rate_limit_config.is_limited(): + return json.dumps({'limit': rate_limit_config.limit, 'period': rate_limit_config.period}) + else: + return None +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_set_user_rate_limit( + username TEXT, + orgname TEXT, + service TEXT, + rate_limit_json JSON) +RETURNS VOID AS $$ + import json + from cartodb_services.config import RateLimitsConfig, RateLimitsConfigSetter + + import cartodb_services + cartodb_services.init(plpy, GD) + + config_setter = RateLimitsConfigSetter(service=service, username=username, orgname=orgname) + if rate_limit_json: + rate_limit = json.loads(rate_limit_json) + limit = rate_limit.get('limit', None) + period = rate_limit.get('period', None) + else: + limit = None + period = None + config = RateLimitsConfig(service=service, username=username, limit=limit, period=period) + config_setter.set_user_rate_limits(config) +$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_set_org_rate_limit( + username TEXT, + orgname TEXT, + service TEXT, + rate_limit_json JSON) +RETURNS VOID AS $$ + import json + from cartodb_services.config import RateLimitsConfig, RateLimitsConfigSetter + + import cartodb_services + cartodb_services.init(plpy, GD) + + config_setter = RateLimitsConfigSetter(service=service, username=username, orgname=orgname) + if rate_limit_json: + rate_limit = json.loads(rate_limit_json) + limit = rate_limit.get('limit', None) + period = rate_limit.get('period', None) + else: + limit = None + period = None + config = RateLimitsConfig(service=service, username=username, limit=limit, period=period) + config_setter.set_org_rate_limits(config) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_service_set_server_rate_limit( + username TEXT, + orgname TEXT, + service TEXT, + rate_limit_json JSON) +RETURNS VOID AS $$ + import json + from cartodb_services.config import RateLimitsConfig, RateLimitsConfigSetter + + import cartodb_services + cartodb_services.init(plpy, GD) + + config_setter = RateLimitsConfigSetter(service=service, username=username, orgname=orgname) + if rate_limit_json: + rate_limit = json.loads(rate_limit_json) + limit = rate_limit.get('limit', None) + period = rate_limit.get('period', None) + else: + limit = None + period = None + config = RateLimitsConfig(service=service, username=username, limit=limit, period=period) + config_setter.set_server_rate_limits(config) +$$ LANGUAGE @@plpythonu@@ VOLATILE PARALLEL UNSAFE; +-- TODO: could cartodb_id be replaced by rowid, maybe needing extra care for offset? +CREATE TYPE cdb_dataservices_server.geocoding AS ( + cartodb_id integer, + the_geom geometry(Point,4326), + metadata jsonb +); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger + 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_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'searches': json.loads(searches)} + + with metrics('cdb_bulk_geocode_street_point', user_geocoder_config, logger, params): + if user_geocoder_config.google_geocoder: + provider_function = "_cdb_bulk_google_geocode_street_point"; + elif user_geocoder_config.heremaps_geocoder: + provider_function = "_cdb_bulk_heremaps_geocode_street_point"; + elif user_geocoder_config.tomtom_geocoder: + provider_function = "_cdb_bulk_tomtom_geocode_street_point"; + elif user_geocoder_config.mapbox_geocoder: + provider_function = "_cdb_bulk_mapbox_geocode_street_point"; + elif user_geocoder_config.geocodio_geocoder: + provider_function = "_cdb_bulk_geocodio_geocode_street_point"; + else: + raise Exception('Requested geocoder is not available') + + plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.{}($1, $2, $3); ".format(provider_function), ["text", "text", "jsonb"]) + return plpy.execute(plan, [username, orgname, searches]) + +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_google_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services import run_street_point_geocoder + from cartodb_services.tools import LegacyServiceManager + from cartodb_services.google import GoogleMapsBulkGeocoder + + service_manager = LegacyServiceManager('geocoder', username, orgname, GD) + geocoder = GoogleMapsBulkGeocoder(service_manager.config.google_client_id, service_manager.config.google_api_key, service_manager.logger) + return run_street_point_geocoder(plpy, GD, geocoder, service_manager, username, orgname, searches) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_heremaps_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services import run_street_point_geocoder + from cartodb_services.tools import LegacyServiceManager + from cartodb_services.here import HereMapsBulkGeocoder + + service_manager = LegacyServiceManager('geocoder', username, orgname, GD) + geocoder = HereMapsBulkGeocoder(service_manager.config.heremaps_app_id, service_manager.config.heremaps_app_code, service_manager.logger, service_manager.config.heremaps_service_params) + return run_street_point_geocoder(plpy, GD, geocoder, service_manager, username, orgname, searches) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_tomtom_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services import run_street_point_geocoder + from cartodb_services.tools import ServiceManager + from cartodb_services.refactor.service.tomtom_geocoder_config import TomTomGeocoderConfigBuilder + from cartodb_services.tomtom import TomTomBulkGeocoder + from cartodb_services.tools import Logger + import cartodb_services + cartodb_services.init(plpy, GD) + + logger_config = GD["logger_config"] + logger = Logger(logger_config) + service_manager = ServiceManager('geocoder', TomTomGeocoderConfigBuilder, username, orgname, GD) + geocoder = TomTomBulkGeocoder(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params) + return run_street_point_geocoder(plpy, GD, geocoder, service_manager, username, orgname, searches) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_mapbox_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services import run_street_point_geocoder + from cartodb_services.tools import ServiceManager + from cartodb_services.refactor.service.mapbox_geocoder_config import MapboxGeocoderConfigBuilder + from cartodb_services.mapbox import MapboxBulkGeocoder + from cartodb_services.tools import Logger + import cartodb_services + cartodb_services.init(plpy, GD) + + logger_config = GD["logger_config"] + logger = Logger(logger_config) + service_manager = ServiceManager('geocoder', MapboxGeocoderConfigBuilder, username, orgname, GD) + geocoder = MapboxBulkGeocoder(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params) + return run_street_point_geocoder(plpy, GD, geocoder, service_manager, username, orgname, searches) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_bulk_geocodio_geocode_street_point(username TEXT, orgname TEXT, searches jsonb) +RETURNS SETOF cdb_dataservices_server.geocoding AS $$ + from cartodb_services import run_street_point_geocoder + from cartodb_services.tools import ServiceManager + from cartodb_services.refactor.service.geocodio_geocoder_config import GeocodioGeocoderConfigBuilder + from cartodb_services.geocodio import GeocodioBulkGeocoder + from cartodb_services.tools import Logger + import cartodb_services + cartodb_services.init(plpy, GD) + + logger_config = GD["logger_config"] + logger = Logger(logger_config) + service_manager = ServiceManager('geocoder', GeocodioGeocoderConfigBuilder, username, orgname, GD) + geocoder = GeocodioBulkGeocoder(service_manager.config.geocodio_api_key, service_manager.logger, service_manager.config.service_params) + return run_street_point_geocoder(plpy, GD, geocoder, service_manager, username, orgname, searches) +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_admin0_polygon(username text, orgname text, country_name text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + params = {'username': username, 'orgname': orgname, 'country_name': country_name} + + with metrics('cdb_geocode_admin0_polygon', user_geocoder_config, logger, params): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_admin0_polygon(trim($1)) AS mypolygon", ["text"]) + rv = plpy.execute(plan, [country_name], 1) + result = rv[0]["mypolygon"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode admin0 polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode admin0 polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + + +-------------------------------------------------------------------------------- + +-- Implementation of the server extension +-- Note: these functions depend on the cdb_geocoder extension +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_admin0_polygon(country_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT n.the_geom as geom INTO ret + FROM (SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x + FROM (SELECT country_name q) g) d + LEFT OUTER JOIN admin0_synonyms s ON name_ = d.x + LEFT OUTER JOIN ne_admin0_v3 n ON s.adm0_a3 = n.adm0_a3 GROUP BY d.q, n.the_geom, s.adm0_a3; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; +---- cdb_geocode_admin1_polygon(admin1_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_admin1_polygon(username text, orgname text, admin1_name text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + params = {'username': username, 'orgname': orgname, 'admin1_name': admin1_name} + + with metrics('cdb_geocode_admin1_polygon', user_geocoder_config, logger, params): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_admin1_polygon(trim($1)) AS mypolygon", ["text"]) + rv = plpy.execute(plan, [admin1_name], 1) + result = rv[0]["mypolygon"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode admin1 polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode admin1 polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +---- cdb_geocode_admin1_polygon(admin1_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_admin1_polygon(username text, orgname text, admin1_name text, country_name text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + with metrics('cdb_geocode_admin1_polygon', user_geocoder_config, logger): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_admin1_polygon(trim($1), trim($2)) AS mypolygon", ["text", "text"]) + rv = plpy.execute(plan, [admin1_name, country_name], 1) + result = rv[0]["mypolygon"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode admin1 polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode admin1 polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-------------------------------------------------------------------------------- + +-- Implementation of the server extension +-- Note: these functions depend on the cdb_geocoder extension + +---- cdb_geocode_admin1_polygon(admin1_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_admin1_polygon(admin1_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + SELECT q, ( + SELECT the_geom + FROM global_province_polygons + WHERE d.c = ANY (synonyms) + ORDER BY frequency DESC LIMIT 1 + ) geom + FROM ( + SELECT + trim(replace(lower(admin1_name),'.',' ')) c, admin1_name q + ) d + ) v; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +---- cdb_geocode_admin1_polygon(admin1_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_admin1_polygon(admin1_name text, country_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + WITH p AS (SELECT r.c, r.q, (SELECT iso3 FROM country_decoder WHERE lower(country_name) = ANY (synonyms)) i FROM (SELECT trim(replace(lower(admin1_name),'.',' ')) c, country_name q) r) + SELECT + geom INTO ret + FROM ( + SELECT + q, ( + SELECT the_geom + FROM global_province_polygons + WHERE p.c = ANY (synonyms) + AND iso3 = p.i + ORDER BY frequency DESC LIMIT 1 + ) geom + FROM p) n; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +---- cdb_geocode_namedplace_point(city_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text) +RETURNS Geometry AS $$ + from plpy import spiexceptions + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + try: + street_point = plpy.prepare("SELECT cdb_dataservices_server.cdb_geocode_street_point($1, $2, $3) as point;", ["text", "text", "text"]) + return plpy.execute(street_point, [username, orgname, city_name])[0]['point'] + except spiexceptions.ExternalRoutineException as e: + import sys + logger.error('Error geocoding namedplace using geocode street point, falling back to internal geocoder', sys.exc_info(), data={"username": username, "orgname": orgname}) + internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3) as point;", ["text", "text", "text"]) + return plpy.execute(internal_plan, [username, orgname, city_name])[0]['point'] +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +---- cdb_geocode_namedplace_point(city_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text, country_name text) +RETURNS Geometry AS $$ + from plpy import spiexceptions + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + try: + street_point = plpy.prepare("SELECT cdb_dataservices_server.cdb_geocode_street_point($1, $2, $3, NULL, NULL, $4) as point;", ["text", "text", "text", "text"]) + return plpy.execute(street_point, [username, orgname, city_name, country_name])[0]['point'] + except spiexceptions.ExternalRoutineException as e: + import sys + logger.error('Error geocoding namedplace using geocode street point, falling back to internal geocoder', sys.exc_info(), data={"username": username, "orgname": orgname}) + internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3, NULL, $4) as point;", ["text", "text", "text", "text"]) + return plpy.execute(internal_plan, [username, orgname, city_name, country_name])[0]['point'] +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +---- cdb_geocode_namedplace_point(city_name text, admin1_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text, admin1_name text, country_name text) +RETURNS Geometry AS $$ + from plpy import spiexceptions + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + try: + street_point = plpy.prepare("SELECT cdb_dataservices_server.cdb_geocode_street_point($1, $2, $3, NULL, $4, $5) as point;", ["text", "text", "text", "text", "text"]) + return plpy.execute(street_point, [username, orgname, city_name, admin1_name, country_name])[0]['point'] + except spiexceptions.ExternalRoutineException as e: + import sys + logger.error('Error geocoding namedplace using geocode street point, falling back to internal geocoder', sys.exc_info(), data={"username": username, "orgname": orgname}) + internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3, $4, $5) as point;", ["text", "text", "text", "text", "text"]) + return plpy.execute(internal_plan, [username, orgname, city_name, admin1_name, country_name])[0]['point'] +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_internal_geocode_namedplace(username text, orgname text, city_name text, admin1_name text DEFAULT NULL, country_name text DEFAULT NULL) +RETURNS Geometry AS $$ + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig, metrics + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + params = {'username': username, 'orgname': orgname, 'city_name': city_name, 'admin1_name': admin1_name, 'country_name': country_name} + + with metrics('cdb_geocode_namedplace_point', user_geocoder_config, logger, params): + try: + if admin1_name and country_name: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_namedplace_point(trim($1), trim($2), trim($3)) AS mypoint", ["text", "text", "text"]) + rv = plpy.execute(plan, [city_name, admin1_name, country_name], 1) + elif country_name: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_namedplace_point(trim($1), trim($2)) AS mypoint", ["text", "text"]) + rv = plpy.execute(plan, [city_name, country_name], 1) + else: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_namedplace_point(trim($1)) AS mypoint", ["text"]) + rv = plpy.execute(plan, [city_name], 1) + result = rv[0]["mypoint"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode namedplace point', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode namedplace point') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-------------------------------------------------------------------------------- + +-- Implementation of the server extension +-- Note: these functions depend on the cdb_geocoder extension + +---- cdb_geocode_namedplace_point(city_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_namedplace_point(city_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + WITH best AS (SELECT s AS q, (SELECT the_geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) ORDER BY population DESC LIMIT 1) AS geom FROM (SELECT city_name as s) p), + next AS (SELECT p.s AS q, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM (SELECT city_name as s) p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL)) + SELECT q, geom, TRUE AS success FROM best WHERE geom IS NOT NULL + UNION ALL + SELECT q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next + ) v; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +---- cdb_geocode_namedplace_point(city_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_namedplace_point(city_name text, country_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + WITH p AS (SELECT r.s, r.c, (SELECT iso2 FROM country_decoder WHERE lower(r.c) = ANY (synonyms)) i FROM (SELECT city_name AS s, country_name::text AS c) r), + best AS (SELECT p.s AS q, p.c AS c, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.iso2 = p.i ORDER BY population DESC LIMIT 1) AS geom FROM p), + next AS (SELECT p.s AS q, p.c AS c, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND gp.iso2 = p.i AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM p WHERE p.s NOT IN (SELECT q FROM best WHERE c = p.c AND geom IS NOT NULL)) + SELECT geom FROM best WHERE geom IS NOT NULL + UNION ALL + SELECT geom FROM next + ) v; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +---- cdb_geocode_namedplace_point(city_name text, admin1_name text, country_name text) +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_namedplace_point(city_name text, admin1_name text, country_name text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + WITH inputcountry AS ( + SELECT iso2 as isoTwo FROM country_decoder WHERE lower(country_name) = ANY (synonyms) LIMIT 1 + ), + p AS ( + SELECT r.s, r.a1, (SELECT admin1 FROM admin1_decoder, inputcountry WHERE lower(r.a1) = ANY (synonyms) AND admin1_decoder.iso2 = inputcountry.isoTwo LIMIT 1) i FROM (SELECT city_name AS s, admin1_name::text AS a1) r), + best AS (SELECT p.s AS q, p.a1 as a1, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.admin1 = p.i ORDER BY population DESC LIMIT 1) AS geom FROM p), + next AS (SELECT p.s AS q, p.a1 AS a1, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND ga.admin1 = p.i AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL)) + SELECT geom FROM best WHERE geom IS NOT NULL + UNION ALL + SELECT geom FROM next + ) v; + + RETURN ret; + END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_point(username text, orgname text, code text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + params = {'username': username, 'orgname': orgname, 'code': code} + + with metrics('cdb_geocode_postalcode_point', user_geocoder_config, logger, params): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_postalcode_point(trim($1)) AS mypoint", ["text"]) + rv = plpy.execute(plan, [code], 1) + result = rv[0]["mypoint"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode postal code point', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode postal code point') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_point(username text, orgname text, code double precision) +RETURNS Geometry AS $$ + SELECT cdb_dataservices_server.cdb_geocode_postalcode_point(username, orgname, code::text); +$$ LANGUAGE SQL STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_point(username text, orgname text, code text, country text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + with metrics('cdb_geocode_postalcode_point', user_geocoder_config, logger): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_postalcode_point(trim($1), trim($2)) AS mypoint", ["TEXT", "TEXT"]) + rv = plpy.execute(plan, [code, country], 1) + result = rv[0]["mypoint"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode postal code point', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode postal code point') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_point(username text, orgname text, code double precision, country text) +RETURNS Geometry AS $$ + SELECT cdb_dataservices_server.cdb_geocode_postalcode_point(username, orgname, code::text, country); +$$ LANGUAGE SQL STABLE PARALLEL RESTRICTED; + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_polygon(username text, orgname text, code text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + with metrics('cdb_geocode_postalcode_point', user_geocoder_config, logger): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_postalcode_polygon(trim($1)) AS mypolygon", ["text"]) + rv = plpy.execute(plan, [code], 1) + result = rv[0]["mypolygon"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode postal code polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode postal code polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_polygon(username text, orgname text, code double precision) +RETURNS Geometry AS $$ + SELECT cdb_dataservices_server.cdb_geocode_postalcode_polygon(username, orgname, code::text) +$$ LANGUAGE SQL STABLE PARALLEL RESTRICTED; + + + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_polygon(username text, orgname text, code text, country text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + with metrics('cdb_geocode_postalcode_point', user_geocoder_config, logger): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_postalcode_polygon(trim($1), trim($2)) AS mypolygon", ["TEXT", "TEXT"]) + rv = plpy.execute(plan, [code, country], 1) + result = rv[0]["mypolygon"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode postal code polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode postal code polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_postalcode_polygon(username text, orgname text, code double precision, country text) +RETURNS Geometry AS $$ + SELECT cdb_dataservices_server.cdb_geocode_postalcode_polygon(username, orgname, code::text, country); +$$ LANGUAGE SQL STABLE PARALLEL RESTRICTED; + +-------------------------------------------------------------------------------- + +-- Implementation of the server extension +-- Note: these functions depend on the cdb_geocoder extension +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_postalcode_point(code text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + SELECT + q, ( + SELECT the_geom + FROM global_postal_code_points + WHERE postal_code = upper(d.q) + LIMIT 1 + ) geom + FROM (SELECT code q) d + ) v; + + RETURN ret; +END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_postalcode_point(code text, country text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + SELECT + q, ( + SELECT the_geom + FROM global_postal_code_points + WHERE postal_code = upper(d.q) + AND iso3 = ( + SELECT iso3 FROM country_decoder WHERE + lower(country) = ANY (synonyms) LIMIT 1 + ) + LIMIT 1 + ) geom + FROM (SELECT code q) d + ) v; + + RETURN ret; +END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_postalcode_polygon(code text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + SELECT + q, ( + SELECT the_geom + FROM global_postal_code_polygons + WHERE postal_code = upper(d.q) + LIMIT 1 + ) geom + FROM (SELECT code q) d + ) v; + + RETURN ret; +END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_postalcode_polygon(code text, country text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + BEGIN + SELECT geom INTO ret + FROM ( + SELECT + q, ( + SELECT the_geom + FROM global_postal_code_polygons + WHERE postal_code = upper(d.q) + AND iso3 = ( + SELECT iso3 FROM country_decoder WHERE + lower(country) = ANY (synonyms) LIMIT 1 + ) + LIMIT 1 + ) geom + FROM (SELECT code q) d + ) v; + + RETURN ret; +END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_ipaddress_point(username text, orgname text, ip text) +RETURNS Geometry AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.metrics import QuotaService + from cartodb_services.metrics import InternalGeocoderConfig + from cartodb_services.tools import Logger,LoggerConfig + + plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + plpy.execute("SELECT cdb_dataservices_server._get_internal_geocoder_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_geocoder_config = GD["user_internal_geocoder_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_geocoder_config, redis_conn) + + params = {'username': username, 'orgname': orgname, 'ip': ip} + + with metrics('cdb_geocode_ipaddress_point', user_geocoder_config, logger): + try: + plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_geocode_ipaddress_point(trim($1)) AS mypoint", ["TEXT"]) + rv = plpy.execute(plan, [ip], 1) + result = rv[0]["mypoint"] + if result: + quota_service.increment_success_service_use() + return result + else: + quota_service.increment_empty_service_use() + return None + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to geocode postal code polygon', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to geocode postal code polygon') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-------------------------------------------------------------------------------- + +-- Implementation of the server extension +-- Note: these functions depend on the cdb_geocoder extension +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_geocode_ipaddress_point(ip text) +RETURNS Geometry AS $$ + DECLARE + ret Geometry; + + new_ip INET; + BEGIN + BEGIN + IF family(ip::inet) = 6 THEN + new_ip := ip::inet; + ELSE + new_ip := ('::ffff:' || ip)::inet; + END IF; + EXCEPTION WHEN OTHERS THEN + SELECT NULL as geom INTO ret; + RETURN ret; + END; + + WITH + ips AS (SELECT ip s, new_ip net), + matches AS (SELECT s, (SELECT the_geom FROM ip_address_locations WHERE network_start_ip <= ips.net ORDER BY network_start_ip DESC LIMIT 1) geom FROM ips) + SELECT geom INTO ret + FROM matches; + RETURN ret; +END +$$ LANGUAGE plpgsql STABLE PARALLEL SAFE; +CREATE TYPE cdb_dataservices_server.isoline AS (center geometry(Geometry,4326), data_range integer, the_geom geometry(Multipolygon,4326)); + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_routing_isolines(username TEXT, orgname TEXT, type TEXT, source geometry(Geometry, 4326), mode TEXT, data_range integer[], options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + import json + from cartodb_services.here import HereMapsRoutingIsoline + from cartodb_services.metrics import QuotaService + from cartodb_services.here.types import geo_polyline_to_multipolygon + from cartodb_services.tools import Logger,LoggerConfig + + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + # -- Check the quota + quota_service = QuotaService(user_isolines_routing_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + try: + client = HereMapsRoutingIsoline(user_isolines_routing_config.heremaps_app_id, + user_isolines_routing_config.heremaps_app_code, logger) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + source_str = 'geo!%f,%f' % (lat, lon) + else: + source_str = None + + if type == 'isodistance': + resp = client.calculate_isodistance(source_str, mode, data_range, options) + elif type == 'isochrone': + resp = client.calculate_isochrone(source_str, mode, data_range, options) + + if resp: + result = [] + for isoline in resp: + data_range_n = isoline['range'] + polyline = isoline['geom'] + multipolygon = geo_polyline_to_multipolygon(polyline) + result.append([source, data_range_n, multipolygon]) + quota_service.increment_success_service_use() + quota_service.increment_isolines_service_use(len(resp)) + return result + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get mapzen isolines') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isodistance( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + import json + from cartodb_services.mapzen import MatrixClient, MapzenIsolines + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + quota_service = QuotaService(user_isolines_routing_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + try: + client = MatrixClient(user_isolines_routing_config.mapzen_matrix_api_key, logger, user_isolines_routing_config.mapzen_matrix_service_params) + mapzen_isolines = MapzenIsolines(client, logger) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = {'lat': lat, 'lon': lon} + else: + raise Exception('source is NULL') + + # -- TODO Support options properly + isolines = {} + for r in data_range: + isoline = mapzen_isolines.calculate_isodistance(origin, mode, r) + isolines[r] = isoline + + result = [] + for r in data_range: + + if len(isolines[r]) >= 3: + # -- TODO encapsulate this block into a func/method + locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point + wkt_coordinates = ','.join(["%f %f" % (l['lon'], l['lat']) for l in locations]) + sql = "SELECT ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326) as geom".format(wkt_coordinates) + multipolygon = plpy.execute(sql, 1)[0]['geom'] + else: + multipolygon = None + + result.append([source, r, multipolygon]) + + quota_service.increment_success_service_use() + quota_service.increment_isolines_service_use(len(isolines)) + return result + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get mapzen isolines') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_isodistance( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.mapbox import MapboxIsolines + from cartodb_services.mapbox.types import TRANSPORT_MODE_TO_MAPBOX + from cartodb_services.tools import Coordinate + from cartodb_services.refactor.service.mapbox_isolines_config import MapboxIsolinesConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('isolines', MapboxIsolinesConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + mapbox_isolines = MapboxIsolines(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = Coordinate(lon,lat) + else: + raise Exception('source is NULL') + + profile = TRANSPORT_MODE_TO_MAPBOX.get(mode) + + # -- TODO Support options properly + isolines = {} + for r in data_range: + isoline = mapbox_isolines.calculate_isodistance(origin, r, profile) + isolines[r] = isoline + + result = [] + for r in data_range: + + if len(isolines[r]) >= 3: + # -- TODO encapsulate this block into a func/method + locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point + wkt_coordinates = ','.join(["%f %f" % (l.longitude, l.latitude) for l in locations]) + sql = "SELECT ST_CollectionExtract(ST_MakeValid(ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326)),3) as geom".format(wkt_coordinates) + multipolygon = plpy.execute(sql, 1)[0]['geom'] + else: + multipolygon = None + + result.append([source, r, multipolygon]) + + service_manager.quota_service.increment_success_service_use() + service_manager.quota_service.increment_isolines_service_use(len(isolines)) + return result + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to get Mapbox isolines', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get Mapbox isolines') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_isodistance( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.tomtom import TomTomIsolines + from cartodb_services.tomtom.types import TRANSPORT_MODE_TO_TOMTOM + from cartodb_services.tools import Coordinate + from cartodb_services.refactor.service.tomtom_isolines_config import TomTomIsolinesConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('isolines', TomTomIsolinesConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + tomtom_isolines = TomTomIsolines(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = Coordinate(lon,lat) + else: + raise Exception('source is NULL') + + profile = TRANSPORT_MODE_TO_TOMTOM.get(mode) + + # -- TODO Support options properly + isolines = {} + for r in data_range: + isoline = tomtom_isolines.calculate_isodistance(origin, r, profile) + isolines[r] = isoline + + result = [] + for r in data_range: + + if len(isolines[r]) >= 3: + # -- TODO encapsulate this block into a func/method + locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point + wkt_coordinates = ','.join(["%f %f" % (l.longitude, l.latitude) for l in locations]) + sql = "SELECT ST_CollectionExtract(ST_MakeValid(ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326)),3) as geom".format(wkt_coordinates) + multipolygon = plpy.execute(sql, 1)[0]['geom'] + else: + multipolygon = None + + result.append([source, r, multipolygon]) + + service_manager.quota_service.increment_success_service_use() + service_manager.quota_service.increment_isolines_service_use(len(isolines)) + return result + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to get TomTom isolines', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get TomTom isolines') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isochrones( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + import json + from cartodb_services.mapzen import MatrixClient, MapzenIsochrones + from cartodb_services.metrics import QuotaService + from cartodb_services.tools import Logger,LoggerConfig + from cartodb_services.mapzen.types import coordinates_to_polygon + + redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] + user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)] + + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + # -- Check the quota + quota_service = QuotaService(user_isolines_routing_config, redis_conn) + if not quota_service.check_user_quota(): + raise Exception('You have reached the limit of your quota') + + try: + mapzen_isochrones = MapzenIsochrones(user_isolines_routing_config.mapzen_matrix_api_key, + logger, user_isolines_routing_config.mapzen_isochrones_service_params) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = {'lat': lat, 'lon': lon} + else: + raise Exception('source is NULL') + + resp = mapzen_isochrones.isochrone(origin, mode, data_range) + + if resp: + result = [] + for isochrone in resp: + result_polygon = coordinates_to_polygon(isochrone.coordinates) + if result_polygon: + result.append([source, isochrone.duration, result_polygon]) + else: + result.append([source, isochrone.duration, None]) + quota_service.increment_success_service_use() + quota_service.increment_isolines_service_use(len(result)) + return result + else: + quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys + quota_service.increment_failed_service_use() + logger.error('Error trying to get mapzen isochrones', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get mapzen isochrones') + finally: + quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_isochrones( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.mapbox import MapboxIsolines + from cartodb_services.mapbox.types import TRANSPORT_MODE_TO_MAPBOX + from cartodb_services.tools import Coordinate + from cartodb_services.tools.coordinates import coordinates_to_polygon + from cartodb_services.refactor.service.mapbox_isolines_config import MapboxIsolinesConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('isolines', MapboxIsolinesConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + mapbox_isolines = MapboxIsolines(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = Coordinate(lon,lat) + else: + raise Exception('source is NULL') + + profile = TRANSPORT_MODE_TO_MAPBOX.get(mode) + + resp = mapbox_isolines.calculate_isochrone(origin, data_range, profile) + + if resp: + result = [] + for isochrone in resp: + result_polygon = coordinates_to_polygon(isochrone.coordinates) + if result_polygon: + result.append([source, isochrone.duration, result_polygon]) + else: + result.append([source, isochrone.duration, None]) + service_manager.quota_service.increment_success_service_use() + service_manager.quota_service.increment_isolines_service_use(len(result)) + return result + else: + service_manager.quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to get Mapbox isochrones', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get Mapbox isochrones') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_isochrones( + username TEXT, + orgname TEXT, + source geometry(Geometry, 4326), + mode TEXT, + data_range integer[], + options text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.tools import ServiceManager + from cartodb_services.tomtom import TomTomIsolines + from cartodb_services.tomtom.types import TRANSPORT_MODE_TO_TOMTOM + from cartodb_services.tools import Coordinate + from cartodb_services.tools.coordinates import coordinates_to_polygon + from cartodb_services.refactor.service.tomtom_isolines_config import TomTomIsolinesConfigBuilder + + import cartodb_services + cartodb_services.init(plpy, GD) + + service_manager = ServiceManager('isolines', TomTomIsolinesConfigBuilder, username, orgname, GD) + service_manager.assert_within_limits() + + try: + tomtom_isolines = TomTomIsolines(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params) + + if source: + lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat'] + lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon'] + origin = Coordinate(lon,lat) + else: + raise Exception('source is NULL') + + profile = TRANSPORT_MODE_TO_TOMTOM.get(mode) + + resp = tomtom_isolines.calculate_isochrone(origin, data_range, profile) + + if resp: + result = [] + for isochrone in resp: + result_polygon = coordinates_to_polygon(isochrone.coordinates) + if result_polygon: + result.append([source, isochrone.duration, result_polygon]) + else: + result.append([source, isochrone.duration, None]) + service_manager.quota_service.increment_success_service_use() + service_manager.quota_service.increment_isolines_service_use(len(result)) + return result + else: + service_manager.quota_service.increment_empty_service_use() + return [] + except BaseException as e: + import sys + service_manager.quota_service.increment_failed_service_use() + service_manager.logger.error('Error trying to get TomTom isochrones', sys.exc_info(), data={"username": username, "orgname": orgname}) + raise Exception('Error trying to get TomTom isochrones') + finally: + service_manager.quota_service.increment_total_service_use() +$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_isodistance(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger + + 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'source': source, 'mode': mode, 'range': range, 'options': options} + + with metrics('cdb_isodistance', user_isolines_config, logger, params): + if user_isolines_config.heremaps_provider: + here_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_here_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(here_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.mapzen_provider: + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_mapzen_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(mapzen_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.mapbox_provider: + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_mapbox_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(mapbox_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.tomtom_provider: + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_tomtom_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(tomtom_plan, [username, orgname, source, mode, range, options]) + else: + raise Exception('Requested isolines provider is not available') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- heremaps isodistance +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_here_isodistance(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + type = 'isodistance' + + here_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_here_routing_isolines($1, $2, $3, $4, $5, $6, $7) as isoline; ", ["text", "text", "text", "geometry(Geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(here_plan, [username, orgname, type, source, mode, range, options]) + + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- mapzen isodistance +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapzen_isodistance(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(mapzen_plan, [username, orgname, source, mode, range, options]) + + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- mapbox isodistance +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapbox_isodistance(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapbox_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(mapbox_plan, [username, orgname, source, mode, range, options]) + + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- tomtom isodistance +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_tomtom_isodistance(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_tomtom_isodistance($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(tomtom_plan, [username, orgname, source, mode, range, options]) + + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_isochrone(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline AS $$ + from cartodb_services.metrics import metrics + from cartodb_services.tools import Logger + + 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") + logger_config = GD["logger_config"] + logger = Logger(logger_config) + + params = {'username': username, 'orgname': orgname, 'source': source, 'mode': mode, 'range': range, 'options': options} + + with metrics('cdb_isochrone', user_isolines_config, logger, params): + if user_isolines_config.heremaps_provider: + here_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_here_isochrone($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(here_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.mapzen_provider: + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_mapzen_isochrone($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(mapzen_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.mapbox_provider: + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_mapbox_isochrone($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(mapbox_plan, [username, orgname, source, mode, range, options]) + elif user_isolines_config.tomtom_provider: + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server.cdb_tomtom_isochrone($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + return plpy.execute(tomtom_plan, [username, orgname, source, mode, range, options]) + else: + raise Exception('Requested isolines provider is not available') +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- heremaps isochrone +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_here_isochrone(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + type = 'isochrone' + + here_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_here_routing_isolines($1, $2, $3, $4, $5, $6, $7) as isoline; ", ["text", "text", "text", "geometry(Geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(here_plan, [username, orgname, type, source, mode, range, options]) + + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- mapzen isochrone +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapzen_isochrone(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_isochrones($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(mapzen_plan, [username, orgname, source, mode, range, options]) + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- mapbox isochrone +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_mapbox_isochrone(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + mapbox_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapbox_isochrones($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(mapbox_plan, [username, orgname, source, mode, range, options]) + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; + +-- tomtom isochrone +CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_tomtom_isochrone(username TEXT, orgname TEXT, source geometry(Geometry, 4326), mode TEXT, range integer[], options text[] DEFAULT array[]::text[]) +RETURNS SETOF cdb_dataservices_server.isoline 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_isolines_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) + user_isolines_config = GD["user_isolines_routing_config_{0}".format(username)] + + tomtom_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_tomtom_isochrones($1, $2, $3, $4, $5, $6) as isoline; ", ["text", "text", "geometry(geometry, 4326)", "text", "integer[]", "text[]"]) + result = plpy.execute(tomtom_plan, [username, orgname, source, mode, range, options]) + return result +$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT * + FROM pg_catalog.pg_user + WHERE usename = 'geocoder_api') THEN + + CREATE USER geocoder_api; + END IF; + GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_dataservices_server TO geocoder_api; + GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO geocoder_api; + GRANT USAGE ON SCHEMA cdb_dataservices_server TO geocoder_api; + GRANT USAGE ON SCHEMA public TO geocoder_api; + GRANT SELECT ON ALL TABLES IN SCHEMA public TO geocoder_api; +END$$; diff --git a/server/extension/cdb_dataservices_server--0.39.2--0.39.3.sql b/server/extension/old_versions/cdb_dataservices_server--0.39.2--0.39.3.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.39.2--0.39.3.sql rename to server/extension/old_versions/cdb_dataservices_server--0.39.2--0.39.3.sql diff --git a/server/extension/cdb_dataservices_server--0.39.3--0.39.2.sql b/server/extension/old_versions/cdb_dataservices_server--0.39.3--0.39.2.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.39.3--0.39.2.sql rename to server/extension/old_versions/cdb_dataservices_server--0.39.3--0.39.2.sql diff --git a/server/extension/cdb_dataservices_server--0.39.3.sql b/server/extension/old_versions/cdb_dataservices_server--0.39.3.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.39.3.sql rename to server/extension/old_versions/cdb_dataservices_server--0.39.3.sql diff --git a/server/extension/sql/110_data_observatory_augmentation.sql b/server/extension/sql/110_data_observatory_augmentation.sql deleted file mode 100644 index 738262f..0000000 --- a/server/extension/sql/110_data_observatory_augmentation.sql +++ /dev/null @@ -1,785 +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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - return user_obs_config.connection_str -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - 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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getdemographicsnapshot', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to obs_get_demographic_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to obs_get_demographic_snapshot') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getdemographicsnapshot', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to obs_get_demographic_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to obs_get_demographic_snapshot') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - 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_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getsegmentsnapshot', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to obs_get_segment_snapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to obs_get_segment_snapshot') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getsegmentsnapshot', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetSegmentSnapshot', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetSegmentSnapshot') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - measure_id TEXT, - normalize TEXT DEFAULT NULL, - 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 VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - measure_id TEXT, - normalize TEXT DEFAULT NULL, - boundary_id TEXT DEFAULT NULL, - time_span TEXT DEFAULT NULL) -RETURNS NUMERIC AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getmeasure', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetMeasure', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetMeasure') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getcategory', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetCategory', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetCategory') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - name TEXT, - normalize TEXT DEFAULT NULL, - 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 VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - name TEXT, - normalize TEXT DEFAULT NULL, - boundary_id TEXT DEFAULT NULL, - time_span TEXT DEFAULT NULL) -RETURNS NUMERIC AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getuscensusmeasure', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetUSCensusMeasure', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetUSCensusMeasure') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getuscensuscategory', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetUSCensusCategory', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetUSCensusCategory') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - normalize TEXT DEFAULT NULL, - 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 VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation( - username TEXT, - orgname TEXT, - geom geometry(Geometry, 4326), - normalize TEXT DEFAULT NULL, - boundary_id TEXT DEFAULT NULL, - time_span TEXT DEFAULT NULL) -RETURNS NUMERIC AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getpopulation', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetPopulation', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetPopulation') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasureById( - username TEXT, - orgname TEXT, - geom_ref TEXT, - measure_id TEXT, - boundary_id TEXT, - time_span TEXT DEFAULT NULL) -RETURNS NUMERIC AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT cdb_observatory.OBS_GetMeasureById(geom_ref, measure_id, boundary_id, time_span); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasureById( - username TEXT, - orgname TEXT, - geom_ref TEXT, - measure_id TEXT, - boundary_id TEXT, - time_span TEXT DEFAULT NULL) -RETURNS NUMERIC AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getmeasurebyid', user_obs_config, logger): - try: - obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasureById($1, $2, $3, $4, $5, $6) as measure;", ["text", "text", "text", "text", "text", "text"]) - result = plpy.execute(obs_plan, [username, orgname, geom_ref, measure_id, 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetMeasureById', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetMeasureById') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetData( - username TEXT, - orgname TEXT, - geomvals geomval[], - params JSON, - merge BOOLEAN DEFAULT True) -RETURNS TABLE ( - id INT, - data JSON -) AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetData(geomvals, params, merge); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData( - username TEXT, - orgname TEXT, - geomvals geomval[], - params JSON, - merge BOOLEAN DEFAULT True) -RETURNS TABLE ( - id INT, - data JSON -) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getdata', user_obs_config, logger, params): - try: - obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4, $5);", ["text", "text", "geomval[]", "json", "boolean"]) - result = plpy.execute(obs_plan, [username, orgname, geomvals, params, merge]) - empty_results = len(geomvals) - len(result) - if empty_results > 0: - quota_service.increment_empty_service_use(empty_results) - if result: - quota_service.increment_success_service_use(len(result)) - return result - else: - return [] - except BaseException as e: - import sys - quota_service.increment_failed_service_use(len(geomvals)) - logger.error('Error trying to OBS_GetData', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetData') - finally: - quota_service.increment_total_service_use(len(geomvals)) -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetData( - username TEXT, - orgname TEXT, - geomrefs TEXT[], - params JSON) -RETURNS TABLE ( - id TEXT, - data JSON -) AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetData(geomrefs, params); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetData( - username TEXT, - orgname TEXT, - geomrefs TEXT[], - params JSON) -RETURNS TABLE ( - id TEXT, - data JSON -) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getdata', user_obs_config, logger, params): - try: - obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetData($1, $2, $3, $4);", ["text", "text", "text[]", "json"]) - result = plpy.execute(obs_plan, [username, orgname, geomrefs, params]) - empty_results = len(geomrefs) - len(result) - if empty_results > 0: - quota_service.increment_empty_service_use(empty_results) - if result: - quota_service.increment_success_service_use(len(result)) - return result - else: - return [] - except BaseException as e: - import sys - quota_service.increment_failed_service_use(len(geomrefs)) - exc_info = sys.exc_info() - logger.error('%s, %s, %s' % (exc_info[0], exc_info[1], exc_info[2])) - logger.error('Error trying to OBS_GetData', exc_info, data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetData') - finally: - quota_service.increment_total_service_use(len(geomrefs)) -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeta( - username TEXT, - orgname TEXT, - geom Geometry(Geometry, 4326), - params JSON, - max_timespan_rank INTEGER DEFAULT NULL, - max_score_rank INTEGER DEFAULT NULL, - target_geoms INTEGER DEFAULT NULL) -RETURNS JSON AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT cdb_observatory.OBS_GetMeta(geom, params, max_timespan_rank, max_score_rank, target_geoms); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeta( - username TEXT, - orgname TEXT, - geom Geometry(Geometry, 4326), - params JSON, - max_timespan_rank INTEGER DEFAULT NULL, - max_score_rank INTEGER DEFAULT NULL, - target_geoms INTEGER DEFAULT NULL) -RETURNS JSON AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - - with metrics('obs_getmeta', user_obs_config, logger, params): - try: - obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeta($1, $2, $3, $4, $5, $6, $7) as meta;", ["text", "text", "Geometry (Geometry, 4326)", "json", "integer", "integer", "integer"]) - result = plpy.execute(obs_plan, [username, orgname, geom, params, max_timespan_rank, max_score_rank, target_geoms]) - if result: - return result[0]['meta'] - else: - return None - except BaseException as e: - import sys - logger.error('Error trying to OBS_GetMeta', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetMeta') -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_MetadataValidation( - username TEXT, - orgname TEXT, - geometry_extent Geometry(Geometry, 4326), - geometry_type text, - params JSON, - target_geoms INTEGER DEFAULT NULL) -RETURNS TABLE(valid boolean, errors text[]) AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_MetadataValidation(geometry_extent, geometry_type, params, target_geoms); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_MetadataValidation( - username TEXT, - orgname TEXT, - geometry_extent Geometry(Geometry, 4326), - geometry_type text, - params JSON, - target_geoms INTEGER DEFAULT NULL) -RETURNS TABLE(valid boolean, errors text[]) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - - with metrics('obs_metadatavalidation', user_obs_config, logger): - try: - obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_MetadataValidation($1, $2, $3, $4, $5, $6);", ["text", "text", "Geometry (Geometry, 4326)", "text", "json", "integer"]) - result = plpy.execute(obs_plan, [username, orgname, geometry_extent, geometry_type, params, target_geoms]) - if result: - return result - else: - return [] - except BaseException as e: - import sys - logger.error('Error trying to OBS_MetadataValidation', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_MetadataValidation') -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/sql/115_data_observatory_exploration.sql b/server/extension/sql/115_data_observatory_exploration.sql deleted file mode 100644 index faab9a7..0000000 --- a/server/extension/sql/115_data_observatory_exploration.sql +++ /dev/null @@ -1,116 +0,0 @@ -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_search', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_Search', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_Search') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getavailableboundaries', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetMeasureById', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetMeasureById') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/sql/120_data_observatory_geometries.sql b/server/extension/sql/120_data_observatory_geometries.sql deleted file mode 100644 index 9524378..0000000 --- a/server/extension/sql/120_data_observatory_geometries.sql +++ /dev/null @@ -1,402 +0,0 @@ -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getboundary', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetBoundary', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetBoundary') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getboundaryid', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetBoundaryId', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetBoundaryId') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 VOLATILE PARALLEL UNSAFE; - -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 metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getboundarybyid', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetBoundaryById', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetBoundaryById') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 NULL) -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 VOLATILE PARALLEL UNSAFE; - -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 NULL) -RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getboundariesbygeometry', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetBoundariesByGeometry', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetBoundariesByGeometry') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 NULL) -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 VOLATILE PARALLEL UNSAFE; - -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 NULL) -RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getboundariesbypointandradius', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetBoundariesByPointAndRadius', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetBoundariesByPointAndRadius') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 NULL) -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 VOLATILE PARALLEL UNSAFE; - -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 NULL) -RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getpointsbygeometry', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetPointsByGeometry', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetPointsByGeometry') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -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 NULL) -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 VOLATILE PARALLEL UNSAFE; - -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 NULL) -RETURNS TABLE(the_geom geometry, geom_refs text) AS $$ - from cartodb_services.metrics import metrics - from cartodb_services.metrics import QuotaService - from cartodb_services.tools import Logger,LoggerConfig - - plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username)) - redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection'] - plpy.execute("SELECT cdb_dataservices_server._get_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname))) - user_obs_config = GD["user_obs_config_{0}".format(username)] - - plpy.execute("SELECT cdb_dataservices_server._get_logger_config()") - logger_config = GD["logger_config"] - logger = Logger(logger_config) - quota_service = QuotaService(user_obs_config, redis_conn) - if not quota_service.check_user_quota(): - raise Exception('You have reached the limit of your quota') - - with metrics('obs_getpointsbypointandradius', user_obs_config, logger): - 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 - quota_service.increment_failed_service_use() - logger.error('Error trying to OBS_GetPointsByPointAndRadius', sys.exc_info(), data={"username": username, "orgname": orgname}) - raise Exception('Error trying to OBS_GetPointsByPointAndRadius') - finally: - quota_service.increment_total_service_use() -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/sql/125_data_observatory_table_augment.sql b/server/extension/sql/125_data_observatory_table_augment.sql deleted file mode 100644 index 6e1bad3..0000000 --- a/server/extension/sql/125_data_observatory_table_augment.sql +++ /dev/null @@ -1,36 +0,0 @@ -CREATE TYPE cdb_dataservices_server.ds_fdw_metadata as (schemaname text, tabname text, servername text); - -CREATE TYPE cdb_dataservices_server.ds_return_metadata as (colnames text[], coltypes text[]); - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, table_name text) -RETURNS cdb_dataservices_server.ds_fdw_metadata AS $$ - host_addr = plpy.execute("SELECT split_part(inet_client_addr()::text, '/', 1) as user_host")[0]['user_host'] - return plpy.execute("SELECT * FROM cdb_dataservices_server.__DST_ConnectUserTable({username}::text, {orgname}::text, {user_db_role}::text, {schema}::text, {dbname}::text, {host_addr}::text, {table_name}::text)" - .format(username=plpy.quote_nullable(username), orgname=plpy.quote_nullable(orgname), user_db_role=plpy.quote_literal(user_db_role), schema=plpy.quote_literal(input_schema), dbname=plpy.quote_literal(dbname), table_name=plpy.quote_literal(table_name), host_addr=plpy.quote_literal(host_addr)) - )[0] -$$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.__DST_ConnectUserTable(username text, orgname text, user_db_role text, input_schema text, dbname text, host_addr text, table_name text) -RETURNS cdb_dataservices_server.ds_fdw_metadata AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - TARGET cdb_observatory._OBS_ConnectUserTable; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_GetReturnMetadata(username text, orgname text, function_name text, params json) -RETURNS cdb_dataservices_server.ds_return_metadata AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - TARGET cdb_observatory._OBS_GetReturnMetadata; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_FetchJoinFdwTableData(username text, orgname text, table_schema text, table_name text, function_name text, params json) -RETURNS SETOF record AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - TARGET cdb_observatory._OBS_FetchJoinFdwTableData; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._DST_DisconnectUserTable(username text, orgname text, table_schema text, table_name text, servername text) -RETURNS boolean AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - TARGET cdb_observatory._OBS_DisconnectUserTable; -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; diff --git a/server/extension/sql/130_data_observatory_helper.sql b/server/extension/sql/130_data_observatory_helper.sql deleted file mode 100644 index 9b72d3f..0000000 --- a/server/extension/sql/130_data_observatory_helper.sql +++ /dev/null @@ -1,93 +0,0 @@ -CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_dumpversion(username text, orgname text) -RETURNS text AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT cdb_observatory.obs_dumpversion(); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - --- We could create a super type for the common data like id, name and so on but we need to parse inside the functions because the -- the return data tha comes from OBS is a TABLE() with them -CREATE TYPE cdb_dataservices_server.obs_meta_numerator AS (numer_id text, numer_name text, numer_description text, numer_weight text, numer_license text, numer_source text, numer_type text, numer_aggregate text, numer_extra jsonb, numer_tags jsonb, valid_denom boolean, valid_geom boolean, valid_timespan boolean); - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableNumerators( - username TEXT, - orgname TEXT, - bounds geometry(Geometry, 4326) DEFAULT NULL, - filter_tags TEXT[] DEFAULT NULL, - denom_id TEXT DEFAULT NULL, - geom_id TEXT DEFAULT NULL, - timespan TEXT DEFAULT NULL) -RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetAvailableNumerators(bounds, filter_tags, denom_id, geom_id, timespan); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetNumerators( - username TEXT, - orgname TEXT, - bounds geometry(Geometry, 4326) DEFAULT NULL, - section_tags TEXT[] DEFAULT ARRAY[]::TEXT[], - subsection_tags TEXT[] DEFAULT ARRAY[]::TEXT[], - other_tags TEXT[] DEFAULT ARRAY[]::TEXT[], - ids TEXT[] DEFAULT ARRAY[]::TEXT[], - name TEXT DEFAULT NULL, - denom_id TEXT DEFAULT '', - geom_id TEXT DEFAULT '', - timespan TEXT DEFAULT '') -RETURNS SETOF cdb_dataservices_server.obs_meta_numerator AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory._OBS_GetNumerators(bounds, section_tags, subsection_tags, other_tags, ids, name, denom_id, geom_id, timespan); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE TYPE cdb_dataservices_server.obs_meta_denominator AS (denom_id text, denom_name text, denom_description text, denom_weight text, denom_license text, denom_source text, denom_type text, denom_aggregate text, denom_extra jsonb, denom_tags jsonb, valid_numer boolean, valid_geom boolean, valid_timespan boolean); - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableDenominators( - username TEXT, - orgname TEXT, - bounds geometry(Geometry, 4326) DEFAULT NULL, - filter_tags TEXT[] DEFAULT NULL, - numer_id TEXT DEFAULT NULL, - geom_id TEXT DEFAULT NULL, - timespan TEXT DEFAULT NULL) -RETURNS SETOF cdb_dataservices_server.obs_meta_denominator AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetAvailableDenominators(bounds, filter_tags, numer_id, geom_id, timespan); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE TYPE cdb_dataservices_server.obs_meta_geometry AS (geom_id text, geom_name text, geom_description text, geom_weight text, geom_aggregate text, geom_license text, geom_source text, valid_numer boolean, valid_denom boolean, valid_timespan boolean, score numeric, numtiles bigint, notnull_percent numeric, numgeoms numeric, percentfill numeric, estnumgeoms numeric, meanmediansize numeric, geom_type text, geom_extra jsonb, geom_tags jsonb); - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableGeometries( - username TEXT, - orgname TEXT, - bounds geometry(Geometry, 4326) DEFAULT NULL, - filter_tags TEXT[] DEFAULT NULL, - numer_id TEXT DEFAULT NULL, - denom_id TEXT DEFAULT NULL, - timespan TEXT DEFAULT NULL, - number_geometries INTEGER DEFAULT NULL) -RETURNS SETOF cdb_dataservices_server.obs_meta_geometry AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetAvailableGeometries(bounds, filter_tags, numer_id, denom_id, timespan, number_geometries); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE TYPE cdb_dataservices_server.obs_meta_timespan AS (timespan_id text, timespan_name text, timespan_description text, timespan_weight text, timespan_aggregate text, timespan_license text, timespan_source text, valid_numer boolean, valid_denom boolean, valid_geom boolean, timespan_type text, timespan_extra jsonb, timespan_tags jsonb); - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableTimespans( - username TEXT, - orgname TEXT, - bounds geometry(Geometry, 4326) DEFAULT NULL, - filter_tags TEXT[] DEFAULT NULL, - numer_id TEXT DEFAULT NULL, - denom_id TEXT DEFAULT NULL, - geom_id TEXT DEFAULT NULL) -RETURNS SETOF cdb_dataservices_server.obs_meta_timespan AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_GetAvailableTimespans(bounds, filter_tags, numer_id, denom_id, geom_id); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; - -CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_LegacyBuilderMetadata( - username TEXT, - orgname TEXT, - aggregate_type TEXT DEFAULT NULL) -RETURNS TABLE(name TEXT, subsection JSON) AS $$ - CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname); - SELECT * FROM cdb_observatory.OBS_LegacyBuilderMetadata(aggregate_type); -$$ LANGUAGE plproxy VOLATILE PARALLEL UNSAFE; diff --git a/server/extension/sql/15_config_helper.sql b/server/extension/sql/15_config_helper.sql index 49f7735..8b2d0e4 100644 --- a/server/extension/sql/15_config_helper.sql +++ b/server/extension/sql/15_config_helper.sql @@ -89,17 +89,3 @@ RETURNS boolean AS $$ GD[cache_key] = routing_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 STABLE PARALLEL RESTRICTED; diff --git a/server/extension/sql/200_quotas.sql b/server/extension/sql/200_quotas.sql index 23ee403..dbde577 100644 --- a/server/extension/sql/200_quotas.sql +++ b/server/extension/sql/200_quotas.sql @@ -6,8 +6,7 @@ BEGIN CREATE TYPE cdb_dataservices_server.service_type AS ENUM ( 'isolines', 'hires_geocoder', - 'routing', - 'observatory' + 'routing' ); END IF; END $$; @@ -93,18 +92,6 @@ RETURNS SETOF cdb_dataservices_server.service_quota_info AS $$ provider = user_routing_config.provider ret += [[service, monthly_quota, used_quota, soft_limit, provider]] - #-- Observatory - service = 'observatory' - 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)] - user_service = UserMetricsService(user_obs_config, redis_conn) - - monthly_quota = user_obs_config.monthly_quota - used_quota = user_service.used_quota(user_obs_config.service_type, today) - soft_limit = user_obs_config.soft_limit - provider = user_obs_config.provider - ret += [[service, monthly_quota, used_quota, soft_limit, provider]] - return ret $$ LANGUAGE @@plpythonu@@ STABLE PARALLEL RESTRICTED; diff --git a/server/extension/test/expected/00_install_test.out b/server/extension/test/expected/00_install_test.out index 8bc5c36..3015221 100644 --- a/server/extension/test/expected/00_install_test.out +++ b/server/extension/test/expected/00_install_test.out @@ -53,12 +53,6 @@ SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null (1 row) -SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=contrib_regression user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}'); - cdb_conf_setconf ------------------- - -(1 row) - -- Mock the varnish invalidation function -- (used by cdb_geocoder tests) CREATE OR REPLACE FUNCTION public.cdb_invalidate_varnish(table_name text) RETURNS void AS $$ diff --git a/server/extension/test/expected/100_data_observatory_tables_test.out b/server/extension/test/expected/100_data_observatory_tables_test.out deleted file mode 100644 index cea6734..0000000 --- a/server/extension/test/expected/100_data_observatory_tables_test.out +++ /dev/null @@ -1,44 +0,0 @@ -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 = '_dst_connectusertable' - AND oidvectortypes(p.proargtypes) = 'text, 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 = '_dst_getreturnmetadata' - AND oidvectortypes(p.proargtypes) = 'text, text, text, json'); - 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 = '_dst_fetchjoinfdwtabledata' - AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text, json'); - 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 = '_dst_disconnectusertable' - AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text'); - exists --------- - t -(1 row) - diff --git a/server/extension/test/expected/100_data_observatory_test.out b/server/extension/test/expected/100_data_observatory_test.out deleted file mode 100644 index b3d7d58..0000000 --- a/server/extension/test/expected/100_data_observatory_test.out +++ /dev/null @@ -1,287 +0,0 @@ -\set ECHO none -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_getdemographicsnapshot' - 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_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_getmeasurebyid' - AND oidvectortypes(p.proargtypes) = 'text, 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_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_getmeta' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, json, integer, integer, integer'); - 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_getdata' - AND oidvectortypes(p.proargtypes) = 'text, text, geomval[], json, boolean'); - 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_getdata' - AND oidvectortypes(p.proargtypes) = 'text, text, text[], json'); - 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) - -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_getavailablenumerators' - 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_getavailabledenominators' - 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_getavailablegeometries' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text[], text, text, text, integer'); - 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_getavailabletimespans' - 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_legacybuildermetadata' - AND oidvectortypes(p.proargtypes) = '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_metadatavalidation' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, json, integer'); - exists --------- - t -(1 row) - diff --git a/server/extension/test/sql/00_install_test.sql b/server/extension/test/sql/00_install_test.sql index c8e41eb..37093b7 100644 --- a/server/extension/test/sql/00_install_test.sql +++ b/server/extension/test/sql/00_install_test.sql @@ -15,7 +15,6 @@ SELECT cartodb.cdb_conf_setconf('mapbox_conf', '{"routing": {"api_keys": ["routi SELECT cartodb.cdb_conf_setconf('tomtom_conf', '{"routing": {"api_keys": ["routing_dummy_api_key"], "monthly_quota": 1500000}, "geocoder": {"api_keys": ["geocoder_dummy_api_key"], "monthly_quota": 1500000}, "isolines": {"api_keys": ["isolines_dummy_api_key"], "monthly_quota": 1500000}}'); SELECT cartodb.cdb_conf_setconf('geocodio_conf', '{"geocoder": {"api_keys": ["geocoder_dummy_api_key"], "monthly_quota": 1500000}}'); SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null"}'); -SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=contrib_regression user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}'); -- Mock the varnish invalidation function -- (used by cdb_geocoder tests) diff --git a/server/extension/test/sql/100_data_observatory_tables_test.sql b/server/extension/test/sql/100_data_observatory_tables_test.sql deleted file mode 100644 index 74a7b2c..0000000 --- a/server/extension/test/sql/100_data_observatory_tables_test.sql +++ /dev/null @@ -1,28 +0,0 @@ -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 = '_dst_connectusertable' - AND oidvectortypes(p.proargtypes) = 'text, 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 = '_dst_getreturnmetadata' - AND oidvectortypes(p.proargtypes) = 'text, text, text, json'); - -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 = '_dst_fetchjoinfdwtabledata' - AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text, json'); - -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 = '_dst_disconnectusertable' - AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text'); - diff --git a/server/extension/test/sql/100_data_observatory_test.sql b/server/extension/test/sql/100_data_observatory_test.sql deleted file mode 100644 index 2f9c374..0000000 --- a/server/extension/test/sql/100_data_observatory_test.sql +++ /dev/null @@ -1,188 +0,0 @@ -\set ECHO none --- add the schema cdb_dataservices_server to the SEARCH_PATH -DO $$ BEGIN - PERFORM set_config('search_path', current_setting('search_path')||', cdb_dataservices_server', false); -END $$; -\set ECHO all - -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_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_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_getmeasurebyid' - AND oidvectortypes(p.proargtypes) = 'text, 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_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_getmeta' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, json, integer, integer, integer'); - -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_getdata' - AND oidvectortypes(p.proargtypes) = 'text, text, geomval[], json, boolean'); - -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_getdata' - AND oidvectortypes(p.proargtypes) = 'text, text, text[], json'); - -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'); - -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_getavailablenumerators' - 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_getavailabledenominators' - 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_getavailablegeometries' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text[], text, text, text, integer'); - -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_getavailabletimespans' - 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_legacybuildermetadata' - AND oidvectortypes(p.proargtypes) = 'text, text, text'); - -SELECT exists(SELECT * - FROM pg_proc p - INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid) - WHERE ns.nspname = 'cdb_dataservices_server' - AND proname = 'obs_metadatavalidation' - AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, json, integer'); diff --git a/server/extension/test/sql/366_empty_table_test.sql.template b/server/extension/test/sql/366_empty_table_test.sql.template index 7b24a74..276fe98 100644 --- a/server/extension/test/sql/366_empty_table_test.sql.template +++ b/server/extension/test/sql/366_empty_table_test.sql.template @@ -9,62 +9,7 @@ END $$; -- Set configuration for a user 'foo' DO $$ - import json - from cartodb_services.config import ServiceConfiguration - import cartodb_services cartodb_services.init(plpy, GD) - service_config = ServiceConfiguration('observatory', 'foo', None) - service_config.user.set('soft_obs_general_limit', True) - service_config.user.set('period_end_date', '20170516') - $$ LANGUAGE @@plpythonu@@; - - --- Mock Observatory backend function -CREATE SCHEMA cdb_observatory; -CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetData(geomvals geomval[], params JSON, merge BOOLEAN DEFAULT TRUE) -RETURNS TABLE ( - id INT, - data JSON -) AS $$ -BEGIN - -- this will return an empty set - RAISE NOTICE 'Mocked OBS_GetData()'; -END; -$$ LANGUAGE plpgsql; -GRANT USAGE ON SCHEMA cdb_observatory TO geocoder_api; -GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO geocoder_api; - - --- Test it -SELECT * FROM cdb_dataservices_server.OBS_GetData( - 'foo', - NULL, - '{"(0103000020E61000000100000005000000010000E0F67F52C096D88AE6B25F4440010000E0238052C0BF6D8A1A8D5D4440010000D0DA7E52C05F03F3CC265D444001000020F47E52C0F2DD78AB5D5F4440010000E0F67F52C096D88AE6B25F4440,1)"}'::_geomval, - '[{"id": 1, "score": 52.7515548093083898758340051256007949661290516400338, "geom_id": "us.census.tiger.census_tract", "denom_id": "us.census.acs.B01003001", "numer_id": "us.census.acs.B03002003", "geom_name": "US Census Tracts", "geom_type": "Geometry", "num_geoms": 2.86483076549783307739486952736, "denom_name": "Total Population", "denom_type": "Numeric", "numer_name": "White Population", "numer_type": "Numeric", "score_rank": 1, "target_area": 0.000307374806576033, "geom_colname": "the_geom", "score_rownum": 1, "target_geoms": null, "denom_colname": "total_pop", "denom_reltype": ' - '"denominator", "geom_timespan": "2015", "normalization": "prenormalized", "numer_colname": "white_pop", "timespan_rank": 1, "geom_tablename": "obs_87a814e485deabe3b12545a537f693d16ca702c2", "max_score_rank": null, "numer_timespan": "2010 - 2014", "suggested_name": "white_pop_2010_2014", "denom_aggregate": "sum", "denom_tablename": "obs_b393b5b88c6adda634b2071a8005b03c551b609a", "numer_aggregate": "sum", "numer_tablename": "obs_b393b5b88c6adda634b2071a8005b03c551b609a", "timespan_rownum": 1, "geom_description": "Census tracts are small, relatively permanent statistical subdivisions of a county or equivalent entity that are updated by local participants prior to each decennial census as part of the Census Bureau’s Participant Statistical Areas Program. The Census Bureau delineates census tracts in situations where no local participant existed or where state, local, or tribal governments' - 'declined to participate. The primary purpose of census tracts is to provide a stable set of geographic units for the presentation of statistical data.\r\n\r\nCensus tracts generally have a population size between 1,200 and 8,000 people, with an optimum size of 4,000 people. A census tract usually covers a contiguous area; however, the spatial size of census tracts varies widely depending on the density of settlement. Census tract boundaries are delineated with the intention of being maintained over a long time so that statistical comparisons can be made from census to census. Census tracts occasionally are split due to population growth or merged as a result of substantial population decline.\r\n\r\nCensus tract boundaries generally follow visible and identifiable features. They may follow nonvisible legal boundaries, such as minor civil division (MCD) or incorporated place boundaries' - 'in some states and situations, to allow for census-tract-to-governmental-unit relationships where the governmental boundaries tend to remain unchanged between censuses. State and county boundaries always are census tract boundaries in the standard census geographic hierarchy. Tribal census tracts are a unique geographic entity defined within federally recognized American Indian reservations and off-reservation trust lands and can cross state and county boundaries. Tribal census tracts may be completely different from the census tracts and block groups defined by state and county (see “Tribal Census Tract”).", "denom_description": "The total number of all people living in a given geographic area. This is a very useful catch-all denominator when calculating rates.", "max_timespan_rank": null, "numer_description": "The number of people identifying as white, non-Hispanic in each' - 'geography.", "geom_t_description": null, "denom_t_description": null, "numer_t_description": null, "geom_geomref_colname": "geoid", "denom_geomref_colname": "geoid", "numer_geomref_colname": "geoid"}]'::json, - true); - - - --- Mock another observatory backend function (overloaded, different params) -CREATE OR REPLACE FUNCTION cdb_observatory.OBS_GetData(geomrefs TEXT[], params JSON) -RETURNS TABLE ( - id INT, - data JSON -) AS $$ -BEGIN - -- this will return an empty set - RAISE NOTICE 'Mocked OBS_GetData()'; -END; -$$ LANGUAGE plpgsql; -GRANT USAGE ON SCHEMA cdb_observatory TO geocoder_api; -GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA cdb_observatory TO geocoder_api; - --- Test it -SELECT * FROM cdb_dataservices_server.OBS_GetData('foo', NULL, '{bar, baz}'::TEXT[], '[]'::JSON); 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 52cf7f3..55a3203 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/__init__.py @@ -1,4 +1,4 @@ -from cartodb_services.metrics.config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException, ObservatoryConfig +from cartodb_services.metrics.config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException from cartodb_services.metrics.quota import QuotaService from cartodb_services.metrics.user import UserMetricsService from cartodb_services.metrics.log import metrics, MetricsDataGatherer, Traceable 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 0c323f8..7b2b8be 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/config.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/config.py @@ -57,57 +57,6 @@ class ServiceConfig(object): return None -class DataObservatoryConfig(ServiceConfig): - - METRICS_LOG_KEY = 'do_log_path' - - def __init__(self, redis_connection, db_conn, username, orgname=None): - super(DataObservatoryConfig, self).__init__(redis_connection, db_conn, - username, orgname) - - @property - def monthly_quota(self): - return self._monthly_quota - - @property - def period_end_date(self): - return self._period_end_date - - @property - def soft_limit(self): - return self._soft_limit - - @property - def connection_str(self): - return self._connection_str - - @property - def provider(self): - return 'data observatory' - - -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 = self._get_effective_monthly_quota(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' @@ -624,7 +573,6 @@ class ServicesDBConfig: self._get_mapbox_config() self._get_tomtom_config() self._get_geocodio_config() - self._get_data_observatory_config() def _get_server_config(self): server_config_json = self._get_conf('server_conf') @@ -716,19 +664,6 @@ class ServicesDBConfig: self._geocodio_geocoder_quota = geocodio_conf['geocoder']['monthly_quota'] self._geocodio_geocoder_service_params = geocodio_conf['geocoder'].get('service', {}) - def _get_data_observatory_config(self): - do_conf_json = self._get_conf('data_observatory_conf') - if not do_conf_json: - raise ConfigException('Data Observatory configuration missing') - else: - do_conf = json.loads(do_conf_json) - 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']: - self._data_observatory_connection_str = do_conf['connection']['staging'] - else: - self._data_observatory_connection_str = do_conf['connection']['production'] - def _get_conf(self, key): try: sql = "SELECT cdb_dataservices_server.CDB_Conf_GetConf('{0}') as conf".format(key) @@ -897,10 +832,6 @@ class ServicesDBConfig: def geocodio_geocoder_service_params(self): return self._geocodio_geocoder_service_params - @property - def data_observatory_connection_str(self): - return self._data_observatory_connection_str - @property def logger_config(self): logger_conf_json = self._get_conf('logger_conf') @@ -917,7 +848,6 @@ class ServicesRedisConfig: QUOTA_KEY = 'geocoding_quota' ISOLINES_QUOTA_KEY = 'here_isolines_quota' ROUTING_QUOTA_KEY = 'mapzen_routing_quota' - OBS_GENERAL_QUOTA_KEY = 'obs_general_quota' PERIOD_END_DATE = 'period_end_date' GEOCODER_PROVIDER_KEY = 'geocoder_provider' ISOLINES_PROVIDER_KEY = 'isolines_provider' @@ -960,8 +890,6 @@ class ServicesRedisConfig: user_config[self.ISOLINES_QUOTA_KEY] = org_config[self.ISOLINES_QUOTA_KEY] if self.ROUTING_QUOTA_KEY in org_config: user_config[self.ROUTING_QUOTA_KEY] = org_config[self.ROUTING_QUOTA_KEY] - if self.OBS_GENERAL_QUOTA_KEY in org_config: - user_config[self.OBS_GENERAL_QUOTA_KEY] = org_config[self.OBS_GENERAL_QUOTA_KEY] if self.PERIOD_END_DATE in org_config: user_config[self.PERIOD_END_DATE] = org_config[self.PERIOD_END_DATE] if self.GOOGLE_GEOCODER_CLIENT_ID in org_config: diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/log.py b/server/lib/python/cartodb_services/cartodb_services/metrics/log.py index bf66d18..aff8ea7 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/log.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/log.py @@ -127,8 +127,6 @@ class MetricsServiceLoggerFactory: return MetricsGenericLogger(service_config, logger) elif re.search('_isolines$', service_config.service_type): return MetricsIsolinesLogger(service_config, logger) - elif re.search('^obs_*', service_config.service_type): - return MetricsGenericLogger(service_config, logger) else: return None 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 c532abb..6339166 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/quota.py @@ -78,9 +78,6 @@ class QuotaChecker: elif re.match('^routing_', self._user_service_config.service_type) is not None: return self.__check_routing_quota() - elif re.match('^obs_', - self._user_service_config.service_type) is not None: - return self.__check_data_observatory_quota() else: return False @@ -123,18 +120,3 @@ class QuotaChecker: return True else: return False - - 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) - - # Quick workaround so we don't take into account numer of credits - # spent for users that have defined the quota. - # See https://github.com/CartoDB/bigmetadata/issues/215 - if soft_limit or (user_quota > 0): - return True - else: - return False diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/user.py b/server/lib/python/cartodb_services/cartodb_services/metrics/user.py index 70bc9a3..2a79ecd 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/user.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/user.py @@ -26,7 +26,6 @@ class UserMetricsService: SERVICE_MAPZEN_ROUTING = 'routing_mapzen' SERVICE_MAPBOX_ROUTING = 'routing_mapbox' SERVICE_TOMTOM_ROUTING = 'routing_tomtom' - SERVICE_OBSERVATORY = 'obs_general' DAY_OF_MONTH_ZERO_PADDED = '%d' def __init__(self, user_geocoder_config, redis_connection): @@ -45,8 +44,6 @@ class UserMetricsService: self.SERVICE_MAPBOX_ROUTING, self.SERVICE_TOMTOM_ROUTING]: return self.__used_routing_quota(service_type, date) - elif service_type == self.SERVICE_OBSERVATORY: - return self.__used_observatory_quota(service_type, date) else: return self.__used_geocoding_quota(service_type, date) @@ -97,19 +94,6 @@ class UserMetricsService: return current_use - def __used_observatory_quota(self, service_type, date): - date_from, date_to = self.__current_billing_cycle() - current_use = 0 - success_responses = self.get_metrics(service_type, - 'success_responses', date_from, - date_to) - empty_responses = self.get_metrics(service_type, - 'empty_responses', date_from, - date_to) - current_use += (success_responses + empty_responses) - - return current_use - def increment_service_use(self, service_type, metric, date=date.today(), amount=1): """ Increment the services uses in monthly and daily basis""" diff --git a/server/lib/python/cartodb_services/setup.py b/server/lib/python/cartodb_services/setup.py index b47b393..76dee21 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.23.5', + version='0.24.0', description='CartoDB Services API Python Library', diff --git a/server/lib/python/cartodb_services/test/metrics/test_config.py b/server/lib/python/cartodb_services/test/metrics/test_config.py index a933a66..e423949 100644 --- a/server/lib/python/cartodb_services/test/metrics/test_config.py +++ b/server/lib/python/cartodb_services/test/metrics/test_config.py @@ -344,102 +344,6 @@ class TestRoutingConfig(TestCase): assert config.soft_limit == True -class TestDataObservatoryUserConfig(TestCase): - - def setUp(self): - self.redis_conn = MockRedis() - plpy_mock_config() - - def test_should_return_config_for_obs_config(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=100, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user') - assert do_config.monthly_quota == 100 - assert do_config.soft_limit is False - assert do_config.period_end_date.date() == yesterday.date() - - def test_should_return_0_if_quota_is_0_in_redis(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=0, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user') - assert do_config.monthly_quota == 0 - - def test_should_return_0_if_quota_is_empty_in_redis(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota='', end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user') - assert do_config.monthly_quota == 0 - - def test_should_return_true_if_soft_limit_is_true_in_redis(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=0, soft_limit=True, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user') - assert do_config.soft_limit is True - - def test_should_return_true_if_soft_limit_is_empty_string_in_redis(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=0, soft_limit='', end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user') - assert do_config.soft_limit is False - -class TestDataObservatoryOrgConfig(TestCase): - - def setUp(self): - self.redis_conn = MockRedis() - plpy_mock_config() - - def test_should_return_organization_config(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=100, end_date=yesterday) - build_redis_org_config(self.redis_conn, 'test_org', 'data_observatory', - quota=200, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user', 'test_org') - assert do_config.monthly_quota == 200 - assert do_config.period_end_date.date() == yesterday.date() - - def test_should_return_quota_0_for_0_in_org_quota_config(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=100) - build_redis_org_config(self.redis_conn, 'test_org', 'data_observatory', - quota=0, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user', 'test_org') - assert do_config.monthly_quota == 0 - - def test_should_return_quota_0_for_empty_in_org_quota_config(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=100) - build_redis_org_config(self.redis_conn, 'test_org', 'data_observatory', - quota='', end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user', 'test_org') - assert do_config.monthly_quota == 0 - - def test_should_return_user_config_when_org_quota_is_not_defined(self): - yesterday = datetime.today() - timedelta(days=1) - build_redis_user_config(self.redis_conn, 'test_user', 'data_observatory', - quota=100) - build_redis_org_config(self.redis_conn, 'test_org', 'data_observatory', - quota=None, end_date=yesterday) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - 'test_user', 'test_org') - assert do_config.monthly_quota == 100 - - class TestServicesRedisConfig(TestCase): def test_it_picks_mapzen_routing_quota_from_redis(self): redis_conn = MockRedis() diff --git a/server/lib/python/cartodb_services/test/test_geocodiogeocoder.py b/server/lib/python/cartodb_services/test/test_geocodiogeocoder.py index c6d79e9..8922bbb 100644 --- a/server/lib/python/cartodb_services/test/test_geocodiogeocoder.py +++ b/server/lib/python/cartodb_services/test/test_geocodiogeocoder.py @@ -26,16 +26,18 @@ VALID_CITY_3='San Francisco' VALID_STATE_PROVINCE_3='California' VALID_COUNTRY_3='United States' -WELL_KNOWN_LONGITUDE_1 = -73.960 -WELL_KNOWN_LATITUDE_1 = 40.774 -WELL_KNOWN_LONGITUDE_2 = -73.983 -WELL_KNOWN_LATITUDE_2 = 40.731 -WELL_KNOWN_LONGITUDE_3 = -122.412 -WELL_KNOWN_LATITUDE_3 = 37.803207 +WELL_KNOWN_LONGITUDE_1 = -73.96 +WELL_KNOWN_LATITUDE_1 = 40.77 +WELL_KNOWN_LONGITUDE_2 = -74.00 +WELL_KNOWN_LATITUDE_2 = 40.75 +WELL_KNOWN_LONGITUDE_3 = -122.41 +WELL_KNOWN_LATITUDE_3 = 37.80 SEARCH_ID_1 = 1 SEARCH_ID_2 = 2 +PRECISION_FORMAT = '%.2f' + class GeocodioGeocoderTestCase(unittest.TestCase): def setUp(self): @@ -52,18 +54,18 @@ class GeocodioGeocoderTestCase(unittest.TestCase): def test_valid_requests(self): place = self.geocoder.geocode(VALID_ADDRESS_1) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_1) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_1) place = self.geocoder.geocode(VALID_ADDRESS_2) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_2) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_2) place = self.geocoder.geocode(VALID_ADDRESS_3) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_3) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_3) def test_valid_request_components(self): place = self.geocoder.geocode(searchtext=VALID_SEARCH_TEXT_1, @@ -71,24 +73,24 @@ class GeocodioGeocoderTestCase(unittest.TestCase): state_province=VALID_STATE_PROVINCE_1, country=VALID_COUNTRY_1) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_1) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_1) place = self.geocoder.geocode(searchtext=VALID_SEARCH_TEXT_2, city=VALID_CITY_2, state_province=VALID_STATE_PROVINCE_2, country=VALID_COUNTRY_2) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_2) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_2) place = self.geocoder.geocode(searchtext=VALID_SEARCH_TEXT_3, city=VALID_CITY_3, state_province=VALID_STATE_PROVINCE_3, country=VALID_COUNTRY_3) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE_3) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_3) def test_valid_request_namedplace(self): place = self.geocoder.geocode(searchtext='New York') @@ -131,39 +133,39 @@ class GeocodioGeocoderTestCase(unittest.TestCase): place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_ADDRESS_1, None, None, None)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_1) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_1) place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_ADDRESS_2, None, None, None)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_2) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_2) place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_ADDRESS_3, None, None, None)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_3) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_3) def test_valid_request_components_bulk_one(self): place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_SEARCH_TEXT_1, VALID_CITY_1, VALID_STATE_PROVINCE_1, VALID_COUNTRY_1)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_1) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_1) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_1) place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_SEARCH_TEXT_2, VALID_CITY_2, VALID_STATE_PROVINCE_2, VALID_COUNTRY_2)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_2) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_2) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_2) place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_SEARCH_TEXT_3, VALID_CITY_3, VALID_STATE_PROVINCE_3, VALID_COUNTRY_3)]) self.assertEqual(place[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % place[0][1], '%.3f' % WELL_KNOWN_LONGITUDE_3) - self.assertEqual('%.3f' % place[0][2], '%.3f' % WELL_KNOWN_LATITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0][1], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_3) + self.assertEqual(PRECISION_FORMAT % place[0][2], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_3) def test_valid_request_namedplace_bulk_one(self): place = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, 'New York', None, None, None)]) @@ -208,12 +210,12 @@ class GeocodioGeocoderTestCase(unittest.TestCase): (SEARCH_ID_2, VALID_ADDRESS_2, None, None, None)]) self.assertEqual(places[0][0], SEARCH_ID_1) - self.assertEqual('%.3f' % places[0][1][0], '%.3f' % WELL_KNOWN_LONGITUDE_1) - self.assertEqual('%.3f' % places[0][1][1], '%.3f' % WELL_KNOWN_LATITUDE_1) + self.assertEqual(PRECISION_FORMAT % places[0][1][0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_1) + self.assertEqual(PRECISION_FORMAT % places[0][1][1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_1) self.assertEqual(places[1][0], SEARCH_ID_2) - self.assertEqual('%.3f' % places[1][1][0], '%.3f' % WELL_KNOWN_LONGITUDE_2) - self.assertEqual('%.3f' % places[1][1][1], '%.3f' % WELL_KNOWN_LATITUDE_2) + self.assertEqual(PRECISION_FORMAT % places[1][1][0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE_2) + self.assertEqual(PRECISION_FORMAT % places[1][1][1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE_2) def test_valid_request_components_bulk_many(self): places = self.bulk_geocoder._batch_geocode([(SEARCH_ID_1, VALID_SEARCH_TEXT_1, VALID_CITY_1, VALID_STATE_PROVINCE_1, VALID_COUNTRY_1), diff --git a/server/lib/python/cartodb_services/test/test_helper.py b/server/lib/python/cartodb_services/test/test_helper.py index 79ec6e2..b8fa4d7 100644 --- a/server/lib/python/cartodb_services/test/test_helper.py +++ b/server/lib/python/cartodb_services/test/test_helper.py @@ -27,9 +27,6 @@ def build_redis_user_config(redis_conn, username, service, quota=100, redis_conn.hset(user_redis_name, 'routing_provider', provider) redis_conn.hset(user_redis_name, 'mapzen_routing_quota', str(quota)) redis_conn.hset(user_redis_name, 'soft_mapzen_routing_limit', str(soft_limit).lower()) - elif service is 'data_observatory': - redis_conn.hset(user_redis_name, 'obs_general_quota', str(quota)) - redis_conn.hset(user_redis_name, 'soft_obs_general_limit', str(soft_limit).lower()) redis_conn.hset(user_redis_name, 'google_maps_client_id', '') redis_conn.hset(user_redis_name, 'google_maps_api_key', '') @@ -53,9 +50,6 @@ def build_redis_org_config(redis_conn, orgname, service, quota=100, redis_conn.hset(org_redis_name, 'routing_provider', provider) if quota is not None: redis_conn.hset(org_redis_name, 'mapzen_routing_quota', str(quota)) - elif service is 'data_observatory': - if quota is not None: - redis_conn.hset(org_redis_name, 'obs_general_quota', str(quota)) redis_conn.hset(org_redis_name, 'google_maps_client_id', '') redis_conn.hset(org_redis_name, 'google_maps_api_key', '') @@ -80,6 +74,5 @@ def plpy_mock_config(): plpy_mock._define_result("CDB_Conf_GetConf\('tomtom_conf'\)", [{'conf': '{"routing": {"api_keys": ["api_key_rou"], "monthly_quota": 1500000}, "geocoder": {"api_keys": ["api_key_geo"], "monthly_quota": 1500000}, "isolines": {"api_keys": ["api_key_mat"], "monthly_quota": 1500000}}'}]) plpy_mock._define_result("CDB_Conf_GetConf\('geocodio_conf'\)", [{'conf': '{"geocoder": {"api_keys": ["api_key_geo"], "monthly_quota": 1500000}}'}]) plpy_mock._define_result("CDB_Conf_GetConf\('logger_conf'\)", [{'conf': '{"geocoder_log_path": "/dev/null"}'}]) - plpy_mock._define_result("CDB_Conf_GetConf\('data_observatory_conf'\)", [{'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"}}'}]) plpy_mock._define_result("CDB_Conf_GetConf\('server_conf'\)", [{'conf': '{"environment": "testing"}'}]) plpy_mock._define_result("select txid_current", [{'txid': random.randint(0, 1000)}]) diff --git a/server/lib/python/cartodb_services/test/test_mapboxgeocoder.py b/server/lib/python/cartodb_services/test/test_mapboxgeocoder.py index 06da8bb..bf52799 100644 --- a/server/lib/python/cartodb_services/test/test_mapboxgeocoder.py +++ b/server/lib/python/cartodb_services/test/test_mapboxgeocoder.py @@ -9,6 +9,7 @@ VALID_ADDRESS = 'Calle Siempreviva 3, Valladolid' WELL_KNOWN_LONGITUDE = -4.730947 WELL_KNOWN_LATITUDE = 41.668654 +PRECISION_FORMAT = '%.3f' class MapboxGeocoderTestCase(unittest.TestCase): def setUp(self): @@ -22,8 +23,8 @@ class MapboxGeocoderTestCase(unittest.TestCase): def test_valid_request(self): place = self.geocoder.geocode(VALID_ADDRESS) - self.assertEqual('%.3f' % place[0], '%.3f' % WELL_KNOWN_LONGITUDE) - self.assertEqual('%.3f' % place[1], '%.3f' % WELL_KNOWN_LATITUDE) + self.assertEqual(PRECISION_FORMAT % place[0], PRECISION_FORMAT % WELL_KNOWN_LONGITUDE) + self.assertEqual(PRECISION_FORMAT % place[1], PRECISION_FORMAT % WELL_KNOWN_LATITUDE) def test_valid_request_namedplace(self): place = self.geocoder.geocode(searchtext='Barcelona') diff --git a/server/lib/python/cartodb_services/test/test_quota_service.py b/server/lib/python/cartodb_services/test/test_quota_service.py index ce1ca21..844ca86 100644 --- a/server/lib/python/cartodb_services/test/test_quota_service.py +++ b/server/lib/python/cartodb_services/test/test_quota_service.py @@ -178,17 +178,6 @@ class TestQuotaService(TestCase): qs.increment_isolines_service_use(amount=1500000) assert qs.check_user_quota() is False - # Quick workaround so we don't take into account numer of credits - # spent for users that have defined the quota. - # See https://github.com/CartoDB/bigmetadata/issues/215 - def test_should_check_org_obs_quota_correctly(self): - qs = self.__build_obs_quota_service('test_user', - orgname='testorg') - qs.increment_success_service_use() - assert qs.check_user_quota() is True - qs.increment_success_service_use(amount=100000) - assert qs.check_user_quota() is True - def __prepare_quota_service(self, username, service, quota, provider, orgname, soft_limit, end_date): build_redis_user_config(self.redis_conn, username, service, @@ -226,14 +215,3 @@ class TestQuotaService(TestCase): isolines_config = IsolinesRoutingConfig(self.redis_conn, plpy_mock, username, orgname) return QuotaService(isolines_config, redis_connection=self.redis_conn) - - def __build_obs_quota_service(self, username, quota=100, - provider='obs_general', - orgname=None, - soft_limit=False, - end_date=datetime.today()): - self.__prepare_quota_service(username, 'data_observatory', quota, - None, orgname, soft_limit, end_date) - do_config = ObservatoryConfig(self.redis_conn, plpy_mock, - username, orgname) - return QuotaService(do_config, redis_connection=self.redis_conn) diff --git a/test/README.md b/test/README.md index d88fb52..1a0d5f7 100644 --- a/test/README.md +++ b/test/README.md @@ -23,7 +23,6 @@ This suite of tests test the following parts of the geocoding API through the SQ - Street address functions (This will call Heremaps or Google so it will cost you 2 credits) - Routing functions - Isolines functions -- Data Observatory functions ### How to debug the tests @@ -46,7 +45,7 @@ GEOCODER_API_TEST_USERNAME=your_username \ GEOCODER_API_TEST_API_KEY=your_api_key \ GEOCODER_API_TEST_TABLE_NAME=your_test_table \ GEOCODER_API_TEST_HOST=your_target_test_host \ -nosetests --where=integration/ test_data_observatory_functions.py:TestDataObservatoryFunctions.test_if_obs_search_is_ok +nosetests --where=integration/ test_admin1_functions.py:TestAdmin1Functions.test_if_select_with_admin1_without_country_is_ok ``` (replace the environment variables, test file, class and function according to your needs) diff --git a/test/integration/test_data_observatory_functions.py b/test/integration/test_data_observatory_functions.py deleted file mode 100644 index 23305bf..0000000 --- a/test/integration/test_data_observatory_functions.py +++ /dev/null @@ -1,329 +0,0 @@ -from unittest import TestCase -from nose.tools import assert_raises -from nose.tools import assert_not_equal, assert_in -from ..helpers.integration_test_helper import IntegrationTestHelper - - -class TestDataObservatoryFunctions(TestCase): - - def setUp(self): - self.env_variables = IntegrationTestHelper.get_environment_variables() - self.sql_api_url = "{0}://{1}.{2}/api/v1/sql".format( - self.env_variables['schema'], - self.env_variables['username'], - self.env_variables['host'], - ) - - def test_if_get_demographic_snapshot_is_ok(self): - 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_GetDemographicSnapshot(CDB_LatLng(40.704512, -73.936669));" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getdemographicsnapshot(geometry) does not exist"]) - - def test_if_get_segment_snapshot_is_ok(self): - 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_GetSegmentSnapshot(CDB_LatLng(40.704512, -73.936669));" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getsegmentsnapshot(geometry) does not exist"]) - - def test_if_get_measure_with_point_is_ok(self): - query = "SELECT OBS_GetMeasure(CDB_LatLng(40.704512, -73.936669), 'us.census.acs.B01003001') 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) - - def test_if_get_measure_with_area_is_ok(self): - query = "SELECT OBS_GetMeasure('0103000020E61000000100000021000000BB366F6D917B52C0E7BB6EA82B5A444067224C85937B52C0810205E70E5A4440596D6342997B52C09BED2952F35944400A96386CA27B52C07B6D31F9D95944402B81A0A8AE7B52C0D16B73D5C3594440C34C397FBD7B52C0D8B5B7C0B1594440CFD90A5ECE7B52C0BE8DD86CA45944405C7E229FE07B52C0A904EE5C9C59444017C1F28EF37B52C05E2745E099594440AE8A3873067C52C0FD62540F9D5944402F272292187C52C05502CBCAA5594440C3F17139297C52C0B3FBC4BCB3594440DDAE56C5377C52C00C46175CC6594440E96AB6A6437C52C0355C94F1DC5944402313AE684C7C52C05340159FF6594440B3B90FB5517C52C031F30168125A44407F43B357537C52C0DF95053B2F5A444059C17840517C52C0D9E08EFC4B5A44406580E8834B7C52C046B5B591675A444035736A5A427C52C0AF9A1AEB805A44402E721C1E367C52C0D226550F975A4440506D5C47277C52C0A2968A24A95A4440507C2868167C52C0D51FCE78B65A4440C4438226047C52C02369F888BE5A4440C9F10C36F17B52C027B1B205C15A4440AABE2451DE7B52C0F5E383D6BD5A44402A18B431CC7B52C01785C11AB55A444018320D8ABB7B52C070265B28A75A4440E28A0EFEAC7B52C09E518C88945A44401D08D61CA17B52C09E8195F27D5A4440D7C3405B987B52C0643CB044645A444047B16D0F937B52C04EC9837B485A4440BB366F6D917B52C0E7BB6EA82B5A4440'::geometry, 'us.census.acs.B01003001') 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) - - def test_if_get_measure_without_api_key_raise_error(self): - query = "SELECT OBS_GetMeasure(CDB_LatLng(40.704512, -73.936669), 'us.census.acs.B01003001');" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getmeasure(geometry, unknown) does not exist"]) - - def test_if_get_measure_by_id_ok(self): - query = "SELECT OBS_GetMeasureById('36047048500', 'us.census.acs.B01003001', 'us.census.tiger.census_tract', '2010 - 2014') 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) - - def test_if_get_measure_by_id_without_api_key_raise_error(self): - query = "SELECT OBS_GetMeasureById('36047048500', 'us.census.acs.B01003001', 'us.census.tiger.census_tract', '2010 - 2014') as measure" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getmeasurebyid(unknown, unknown, unknown, unknown) does not exist"]) - - 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', '2010 - 2014') 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) - - 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', '2010 - 2014');" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getcategory(geometry, unknown, unknown, unknown) does not exist"]) - - 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) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getuscensusmeasure(geometry, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getuscensuscategory(geometry, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getpopulation(geometry) does not exist"]) - - def test_if_obs_search_is_ok(self): - sql = "SELECT id FROM OBS_Search('total_pop') WHERE id LIKE 'es.ine%' LIMIT 1;" - import urllib - query = "{0}&api_key={1}".format(urllib.quote(sql), self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['id'], None) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_search(unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getavailableboundaries(geometry) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getboundary(geometry, unknown) does not exist"]) - - 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', '2015') 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) - - 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', '2015') as boundary_id;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getboundaryid(geometry, unknown, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getboundarybyid(unknown, unknown, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getboundariesbygeometry(geometry, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getboundariesbypointandradius(geometry, integer, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getpointsbygeometry(geometry, unknown) does not exist"]) - - 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) - - 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_in(e.message[0], ["Data Observatory permission denied", "function obs_getpointsbypointandradius(geometry, integer, unknown, unknown) does not exist"]) - - def test_if_obs_get_legacy_builder_metadata_is_ok(self): - query = "SELECT name FROM OBS_LegacyBuilderMetadata() LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['name'], None) - - def test_if_legacy_builder_metadata_without_api_key_raise_error(self): - query = "SELECT name FROM OBS_LegacyBuilderMetadata() LIMIT 1;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_legacybuildermetadata() does not exist"]) - - def test_if_obs_get_available_numerators_is_ok(self): - query = "SELECT numer_id FROM OBS_GetAvailableNumerators() LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['numer_id'], None) - - def test_if_obs_get_available_numerators_without_api_key_raise_error(self): - query = "SELECT numer_id FROM OBS_GetAvailableNumerators() LIMIT 1;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getavailablenumerators() does not exist"]) - - def test_if_obs_get_available_denominators_is_ok(self): - query = "SELECT denom_id FROM OBS_GetAvailableDenominators() LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['denom_id'], None) - - def test_if_obs_get_available_denominators_without_api_key_raise_error(self): - query = "SELECT denom_id FROM OBS_GetAvailableDenominators() LIMIT 1;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getavailabledenominators() does not exist"]) - - def test_if_obs_get_available_geometries_is_ok(self): - query = "SELECT geom_id FROM OBS_GetAvailableGeometries() 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_id'], None) - - def test_if_obs_get_available_geometries_without_api_key_raise_error(self): - query = "SELECT geom_id FROM OBS_GetAvailableGeometries() LIMIT 1;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getavailablegeometries() does not exist"]) - - def test_if_obs_get_available_timespans_is_ok(self): - query = "SELECT timespan_id FROM OBS_GetAvailableTimespans() LIMIT 1;&api_key={0}".format(self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['timespan_id'], None) - - def test_if_obs_get_available_timespans_without_api_key_raise_error(self): - query = "SELECT timespan_id FROM OBS_GetAvailableTimespans() LIMIT 1;" - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getavailabletimespans() does not exist"]) - - def test_if_obs_get_meta_is_ok(self): - params = '\'[{\"numer_id\": \"us.census.acs.B01003001\"}]\'' - query = "SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), {0}, 1, 1, 1000) as metadata LIMIT 1;&api_key={1}".format(params, self.env_variables['api_key']) - result = IntegrationTestHelper.execute_query(self.sql_api_url, query) - assert_not_equal(result['metadata'], None) - - def test_if_obs_get_meta_without_api_key_raise_error(self): - params = '\'[{\"numer_id\": \"us.census.acs.B01003001\"}]\'' - query = "SELECT obs_getmeta(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), {0}, 1, 1, 1000) LIMIT 1;".format(params) - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getmeta(geometry, unknown, integer, integer, integer) does not exist"]) - - def test_if_obs_get_data_is_ok(self): - params_1 = '\'[{\"numer_id\": \"us.census.acs.B01003001\", \"geom_id\": \"us.census.tiger.county\"}]\'' - params_2 = '\'[{\"numer_id\": \"us.census.acs.B01003001\"}]\'' - query_1 = "SELECT id as data_id FROM obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), {0}, 1, 1, 1000)) LIMIT 1;&api_key={1}".format(params_1, self.env_variables['api_key']) - query_2 = "SELECT id as data_id FROM obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), {0})) LIMIT 1;&api_key={1}".format(params_2,self.env_variables['api_key']) - result_1 = IntegrationTestHelper.execute_query(self.sql_api_url, query_1) - assert_not_equal(result_1['data_id'], None) - result_2 = IntegrationTestHelper.execute_query(self.sql_api_url, query_2) - assert_not_equal(result_2['data_id'], None) - - def test_if_obs_get_data_without_api_key_raise_error(self): - params_1 = '\'[{\"numer_id\": \"us.census.acs.B01003001\", \"geom_id\": \"us.census.tiger.county\"}]\''; - params_2 = '\'[{\"numer_id\": \"us.census.acs.B01003001\"}]\'' - query_1 = "SELECT id as data_id FROM obs_getdata(ARRAY['36047'], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), {0}, 1, 1, 1000)) LIMIT 1;".format(params_1) - query_2 = "SELECT id as data_id FROM obs_getdata(ARRAY[(ST_SetSRID(ST_Point(-73.9, 40.7), 4326), 1)::geomval], obs_getmeta(st_setsrid(st_point(-73.9, 40.7), 4326), {0})) LIMIT 1;".format(params_2) - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query_1) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getmeta(geometry, unknown, integer, integer, integer) does not exist"]) - try: - IntegrationTestHelper.execute_query(self.sql_api_url, query_2) - except Exception as e: - assert_in(e.message[0], ["Data Observatory permission denied", "function obs_getmeta(geometry, unknown) does not exist"])