実行環境、コンパイル済みファイルのダウンロード、配置
- Windows7 32bit + PostgreSQL 9.3.5
- ConEmu Build 150513でpsqlを使用
今日のPostgreSQL 9.2は、昨日と違ってポータブル化はせず通常のインストーラ(EnterpriseDB社)で入れたままの状態。PL/v8のファイルをプログラムフォルダにコピーするので、いったんサービスを止めます。止めないと問題が出るか未確認ですが念のため。
PL/v8のWindows 32bit・64bitそれぞれ用のZIPが、下記からダウンロードできます。昨日のPostgreSQL 9.2用と同じくPostgres Online Journalの記事。
ZIPの構成とインストール方法は昨日と同じで、PostgreSQLのプログラムフォルダにコピーするだけ。
PostGISやpgRoutingも入れていたので、プログラムフォルダは ↓ こんな感じ。既に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_extensionでPL/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/pgSQLやPL/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でやってみる予定。