2016-09-01 7 views
0

リーフレットとCartoDBを使用してWebアプリケーションを作成しようとしています。私はthis tutorialを使用して、公開のCartoDBテーブルにデータを読み書きしようとしています。Leaflet.drawとCartoDBを使用してテーブルに更新/挿入する方法

このチュートリアルでは、セキュリティ定義者を使用してこれを行う方法について説明します。何らかの理由で、アプリケーションでleaflet.drawを使用して作成した機能は、自分のテーブルに挿入されません。私はまだコーディングに新しく、SQLクエリが実際に私のコードでどのように呼び出されているのか不明ですが、サンプルソースコードを複製しようとしましたが、実行に幸運を祈ることはありませんでした。

目標は、マップ上にポイントを作成して編集し、そのポイントをCartoDBのcrowdsourceデータベースに保存できるようにすることです。

私のプロジェクトのためのコードはここで見ることができます: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; 
+1

関連質問:http://gis.stackexchange.com/questions/134544/in-cartodb-best-way-to-have- OpenLayersを中複数の寄稿者を含むテーブル – zrobby

+1

関連するソリューション:https://github.com/radumas/crowdmap-basic – zrobby

答えて

0

私の以前の回答はあまりにもハッキリでした。すぐに廃止される予定です。

これを行う適切な方法は、関数の所有者権限でINSERTクエリを実行するSECURITY DEFINER関数を設定することです。

ここでそれを確認してください - >https://gist.github.com/ernesmb/beb25f539f8ff38bbd891e6d114ea7f4

はそれが役に立てば幸い!

+0

完璧に動作します!ありがとうございました!! – zrobby

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クエリを実行できるはずです。 リスクに注意してください。

+0

Ernesto、あなたの返信に感謝します!私はセキュリティ定義者への別のアプローチは考えていませんでしたが、あなたの方法は私のアプリケーションの単純さには意味があります。私はすぐにフォローアップします。 – zrobby

関連する問題