0

我正在尝试使用 Leaflet 和 CartoDB 创建一个 Web 应用程序。我正在尝试使用本教程将数据读取和写入公共 CartoDB 表。

本教程解释了如何使用安全定义器来完成此操作。无论出于何种原因,我在应用程序中使用 leaflet.draw 创建的功能都不会插入到我的表格中。我对编码还是很陌生,不确定如何在我的代码中实际调用 SQL 查询,但我已经尝试复制示例源代码并且没有任何执行的运气。

目标是允许用户在地图上创建和编辑他们的点,并将这些点保存到 CartoDB 中的众包数据库中。

我的项目的代码可以在这里查看:https ://github.com/zrobby/crowdsource-storymap

我在执行时遇到困难的特定 SQL 查询如下所示,来自上面链接的教程。

    DROP FUNCTION IF EXISTS leaflet_upsert_usercomments(int[], text[]);

    -- Returns a set of op,cartodb_id values where op means:
    --  deleted: -1
    --  updated: 0
    --  inserted: 1

    CREATE OR REPLACE FUNCTION leaflet_upsert_usercomments(
    cartodb_ids integer[],
    geojsons text[])
    RETURNS TABLE(op int, cartodb_id int)

    LANGUAGE plpgsql SECURITY DEFINER
    RETURNS NULL ON NULL INPUT
    AS $$
    DECLARE
    sql text;
    BEGIN

    sql := 'WITH n(cartodb_id,the_geom) AS (VALUES ';

    -- Iterate over the values
    FOR i in 1 .. array_upper(geojsons, 1)
    LOOP
    IF i > 1 THEN sql := sql || ','; END IF;
    sql :=sql || '('||cartodb_ids[i]||','
            || 'ST_SetSRID(ST_GeomFromGeoJSON(NULLIF('''|| geojsons[i] ||''','''')),4326))';
    END LOOP;

    sql := sql || '), do_update AS ('
      || 'UPDATE leaflet_data p '
      || 'SET the_geom=n.the_geom FROM n WHERE p.cartodb_id = n.cartodb_id '
      || 'AND n.the_geom IS NOT NULL '
      || 'RETURNING p.cartodb_id ), do_delete AS ('
      || 'DELETE FROM leaflet_data p WHERE p.cartodb_id IN ('
      || 'SELECT n.cartodb_id FROM n WHERE cartodb_id >= 0 AND '
      || ' n.the_geom IS NULL ) RETURNING p.cartodb_id ), do_insert AS ('
      || 'INSERT INTO leaflet_data (the_geom)'
      || 'SELECT n.the_geom FROM n WHERE n.cartodb_id < 0 AND '
      || ' n.the_geom IS NOT NULL RETURNING cartodb_id ) '
      || 'SELECT 0,cartodb_id FROM do_update UNION ALL '
      || 'SELECT 1,cartodb_id FROM do_insert UNION ALL '
      || 'SELECT -1,cartodb_id FROM do_delete';

    RAISE DEBUG '%', sql;

    RETURN QUERY EXECUTE sql;

    END;
    $$;

    -- Grant access to the public user
    GRANT EXECUTE ON FUNCTION leaflet_upsert_usercomments(integer[],text[]) TO publicuser;
4

3 回答 3

0

可能有一种更简单的方法,即授予正在使用的表(或列)的特定权限,而不是创建复杂的安全定义器函数。

由于您只是尝试添加点,因此您可以使用本示例中使用的内容:http: //bl.ocks.org/iriberri/7d84ed35ef0b5e80555d

那是前端应用程序部分。要为您的表授予足够的权限,您应该从 CARTO 编辑器的 SQL 面板或通过 SQL API 运行以下 SQL。

GRANT INSERT (column1, column2, ...) ON tableName TO publicuser;

GRANT USAGE ON SEQUENCE tableName_cartodb_id_seq_0 TO publicuser;

如果有任何错误,您可以从开发工具中的网络选项卡进行调试,sql 调用将返回错误描述。

授予权限后,您应该能够从前端运行 INSERT 查询,而无需验证您的呼叫。请注意风险。

于 2016-09-02T15:42:43.880 回答
0

我之前的回答太老套了,很快就会被弃用。

正确的方法是使用 SECURITY DEFINER 设置一个函数,该函数以函数的所有者权限运行 INSERT 查询。

在这里检查 --> https://gist.github.com/ernesmb/beb25f539f8ff38bbd891e6d114ea7f4

希望能帮助到你!

于 2016-09-15T15:45:54.673 回答
0

我不熟悉“安全定义器”,但可能有另一种方法,以防其他人有兴趣编辑使用 WFS 事务协议 (WFS-T) 的功能

在 OpenLayers 中使用 WFS-T 的示例: http ://dev.openlayers.org/examples/wfs-protocol-transactions.html

在传单中使用 WFS-T 的示例:https ://georepublic.info/en/blog/2012/leaflet-example-with-wfs-t/

于 2016-09-15T20:03:21.610 回答