ダイナミックにデータベースを検索するアプリケーションなどで、アクセスするデータベースのテーブル構造を調べてから検索するような場合に利用できるテクニックです。
PostgreSQLの指定したテーブルからサンプルデータをフェッチし、その結果から列情報を取得する方法です。
const express = require('express');
const router = express.Router();
const pg = require('pg');
router.post('/describe', (req, res) => {
// HTTPリクエストでデータベース接続情報が送信されているとする
const conn = {
database: req.body.database,
user: req.body.user,
password: req.body.password,
host: req.body.host,
port: req.body.port
};
// 対象のテーブル
const table = req.body.table;
// サンプルデータのレコード件数
const limit = req.body.limit || 10;
const pool = pg.Pool(conn);
pool.connect( (err, client) => {
if(err) {
res.status(500).send('Invalid connection info');
} else {
let response = {};
// サンプルデータをフェッチする
client.query(`SELECT * FROM ${table} LIMIT ${limit}`, (err, result) => {
if(err) {
client.end();
res.status(500).send('Invalid query');
} else {
// fieldsから列名, _types._types.builtinsからデータ型を得る
const fields = result.fields;
const types = result._types._types.builtins;
const columns = [];
fields.forEach( f => {
const dt = Object.keys(types).reduce( (r, key) => {
return types[key] === f.dataTypeID ? key : r;
}, null);
columns.push({columnName: f.name, type: dt});
});
// レスポンスに列情報を設定する
response.columns = columns;
// レスポンスにサンプルデータを設定する
response.rows = result.rows;
client.end();
res.send(response);
}
});
}
});
});