(1)WindowsPostgreSQL 9.2(昨日) (3)WindowsPostgreSQL 9.4(明日) (4)CentOS 6.6 + PostgreSQL 9.3924日) (5)CentOS 7 + PostgreSQL 9.5 Alpha 1925日) (6)Scientific Linux 7 + PostgreSQL 9.5 Alpha 2926日) (7・終)Mac OS X 10.8.5 + PostgreSQL 9.5 Alpha 1927日)
Contents


実行環境、コンパイル済みファイルのダウンロード、配置


今日のPostgreSQL 9.2は、昨日と違ってポータブル化はせず通常のインストーラ(EnterpriseDB社)で入れたままの状態。PL/v8のファイルをプログラムフォルダにコピーするので、いったんサービスを止めます。止めないと問題が出るか未確認ですが念のため。


PL/v8Windows 32bit・64bitそれぞれ用のZIPが、下記からダウンロードできます。
昨日PostgreSQL 9.2用と同じくPostgres Online Journalの記事。


ZIPの構成とインストール方法は
昨日と同じで、PostgreSQLのプログラムフォルダにコピーするだけ。


PostGISpgRoutingも入れていたので、プログラムフォルダは ↓ こんな感じ。既にbin、lib、shareの各フォルダがあり、そのうちbin内の2ファイル(libgcc_s_sjlj-1.dll、libstdc++-6.dll)が元からありPL/v8の方が古かったですが、昨日と同様とりあえずそのまま上書きしました。


PostgreSQL起動、データベースへインストール

ファイルコピーができたらPostgreSQLのサービスを起動し、psqlで接続しました(画像は省略)。後のコマンドは昨日PostgreSQL 9.2用と全く同じ。最初にテスト用データベース作成、続いて当該DB上でCREATE EXTENSIONをクエリするだけでインストール完了。pg_extensionPL/v8のバージョンを見たら1.4.0でした。(最後のコマンド。昨日の9.2用は1.3.0だった)
CREATE DATABASE plv8_test
TEMPLATE = template0
LC_COLLATE = 'C'
LC_CTYPE = 'C';
# \c plv8_test

psql (9.4.1, サーバー 9.3.5)
データベース "plv8_test" にユーザ"postgres"として接続しました。
CREATE EXTENSION plv8;

SELECT extname, extversion FROM pg_extension;

 extname | extversion
---------+------------
 plpgsql | 1.0
 plv8    | 1.4.0


簡単なテスト(使えるオブジェクト、データベースアクセス)

昨日と同じ無名コードブロックの簡単なクエリは問題なく実行できました(画像は省略)。別のテストとして、使えるJavaScriptのオブジェクトを調べてみると ↓ 当然ですがブラウザ関連は全てundefined。
DO LANGUAGE plv8 $$
    var ary = ['Array', 'Boolean', 'Date', 'Function',
        'Math', 'Number', 'Object', 'RegExp', 'String', 
        'window', 'location', 'navigator'];
    for (var i in ary) {
        var j = ary[i]; 
        plv8.elog(INFO, j, eval('typeof ' + j));
    }
$$;


次に、PostgreSQL組み込み言語ならではのデータベースアクセスをテストしてみます。下記ドキュメントを見るとplv8.execute()でクエリを発行でき、戻り値はJSONになるようです。


↓ 無名コードブロック内でplv8.executeの結果を一行ずつplv8.elogに渡すと、各行が連想配列(Object)で全体が配列(Array)になってました。
DO LANGUAGE plv8 $$
    var sql = 'SELECT * FROM pg_tables LIMIT 10',
        res = plv8.execute(sql);
    for (var k in res) {
        plv8.elog(INFO, k, res[k]);
    }
$$;

INFO:  0 [object Object]
INFO:  1 [object Object]
INFO:  2 [object Object]
INFO:  3 [object Object]
INFO:  4 [object Object]
INFO:  5 [object Object]
INFO:  6 [object Object]
INFO:  7 [object Object]
INFO:  8 [object Object]
INFO:  9 [object Object]

↓ 同じく無名コードブロック内でクエリ結果を表示する例。各行の連想配列が「列名=>値」の集合になっており、一行目のみ列名を取り出してObject.keys()で配列に入れ、各行で列名(キー)から値を取得して一行に連結しました。もっと簡単な方法があるかも。
DO LANGUAGE plv8 $$
    var sql = 'SELECT * FROM pg_tables LIMIT 10',
        res = plv8.execute(sql),
        len = res.length,
        col = [];
    for (var i = 0; i < len; i++) {
        var obj = res[i], val = [];
        if (i === 0) {
            col = Object.keys(obj);
            plv8.elog(INFO, col.join(', '));
            plv8.elog(INFO, '------------');
        }
        col.forEach (function (key) {
            val.push(obj[key]);
        });
        plv8.elog(INFO, val.join(', '));
    }
$$;

INFO:  schemaname, tablename, tableowner, tablespace, hasindexes, hasrules, hastriggers
INFO:  ------------
INFO:  pg_catalog, pg_statistic, postgres, , true, false, false
INFO:  pg_catalog, pg_type, postgres, , true, false, false
INFO:  pg_catalog, pg_authid, postgres, pg_global, true, false, false
INFO:  information_schema, sql_features, postgres, , false, false, false
INFO:  pg_catalog, pg_attribute, postgres, , true, false, false
INFO:  pg_catalog, pg_class, postgres, , true, false, false
INFO:  information_schema, sql_implementation_info, postgres, , false, false, false
INFO:  pg_catalog, pg_constraint, postgres, , true, false, false
INFO:  pg_catalog, pg_inherits, postgres, , true, false, false
INFO:  pg_catalog, pg_index, postgres, , true, false, false

PL/v8に限らずJavaScript一般で「改行はそのまま文字列に入れられない」ので、↓ のようにクエリ文字列に改行を混ぜられません。長いクエリは避けた方がよさそう。この点は普通のPL/pgSQLPL/Rの方が、SQLと同様に改行を入れられるので便利。
DO LANGUAGE plv8 $$
    var res = plv8.execute('
        SELECT * FROM pg_tables LIMIT 10
    ');
    for (var k in res) {
        plv8.elog(INFO, k, res[k]);
    }
$$;

ERROR:  SyntaxError: Unexpected token ILLEGAL
DETAIL:  undefined() LINE 2:     var res = plv8.execute('

昨日の予想どおり、特に問題なく終わりました。明日は引き続きWindows版でPostgerSQL 9.4へインストールし、その後、他のOSでやってみる予定。