概要
BunでデフォルトとなったPostgreSQLアクセス機能を使った簡単なSQLクライアントを作成してみたので、備忘のため作成
プロジェクトの作成手順
# 適当な作業ディレクトリを作成してプロジェクトを初期化
mkdir bun-sql-client
cd bun-sql-client
# Bun初期化(Blankで作成)
bun init
# types/bunを追加
bun add -D @types/bun
SQLクライアントコード
DBへの接続情報と、SQLファイルを指定して実行します。
コードの9割は、Geminiさんが作ってくれましたw
sql-client.ts
import { SQL } from "bun";
import fs from "node:fs/promises";
async function main() {
// 引数の数をチェック (実行ファイルパスを含めて8つ必要)
if (process.argv.length !== 8) {
console.error(
"Usage: bun sql-client.ts "
);
process.exit(1);
}
// コマンドライン引数を取得 (Non-null assertion operator (!) を使用)
const [_, __, host, portStr, database, user, password, sqlFilePath] =
process.argv;
const port = parseInt(portStr!, 10); // portStrがundefinedでないことを示す
// NaNチェックを追加
if (isNaN(port)) {
console.error("Invalid port number provided.");
process.exit(1);
}
let db: SQL | undefined;
try {
// PostgreSQLに接続 (bun:postgresを使用)
db = new SQL({
hostname: host!,
port: port,
database: database!,
user: user!, // 'username'ではなく'user'を使用
password: password!,
// 必要に応じて他の接続オプションを追加
});
console.log("Connected to PostgreSQL using bun:postgres");
// SQLファイルを読み込む (sqlFilePathがundefinedでないことを示す)
const sqlQuery = await fs.readFile(sqlFilePath!, "utf-8");
console.log(`Executing SQL from: ${sqlFilePath!}`);
console.log(`\n${sqlQuery}\n`);
// SQLクエリを実行
const result = await db.file(sqlFilePath!);
// 表形式で結果を出力
if (result.length > 0) {
// result は オブジェクトの配列 なので、最初の行から列名を取得
const columns = Object.keys(result[0]!); // Non-null assertion
console.log(columns.join(" | "));
// ヘッダーの下線 (より堅牢な計算方法)
const colWidths = columns.map((col) =>
Math.max(
col.length,
// result の各行 (row) の対応する列 (col) の文字列長を計算
...result.map((row: any) => String(row[col] ?? '').length) // null/undefined の場合に備えて空文字に
)
);
const separator = colWidths.map((w) => "-".repeat(w)).join("-+-");
console.log(separator);
// 各行の値を出力 (パディングを追加)
result.forEach((row: any) => {
const values = columns.map((col, i) =>
// null/undefined の場合に備えて空文字にしてから padEnd
String(row[col] ?? '').padEnd(colWidths[i]!) // Non-null assertion
);
console.log(values.join(" | "));
});
} else {
console.log("No rows returned.");
}
// result.length を使用して行数を表示
console.log(`\nQuery returned ${result.length} row(s).`);
} catch (error) {
console.error("Error:", error);
process.exit(1);
} finally {
// 接続を閉じる
if (db) {
db.end();
console.log("Disconnected from PostgreSQL");
}
}
}
main().catch(console.error);
sample.sql
select 1 as column1 , 2 as column2
実行結果
- sample.sqlを実行してみる
bun sql-client localhost 5432 sample sample sample sample.sql
Connected to PostgreSQL using bun:postgres
Executing SQL from: sample.sql
select 1 as column1 , 2 as column2
column1 | column2
--------+--------
1 | 2
Query returned 1 row(s).
Disconnected from PostgreSQL
まとめ
- BunだけでTypeScript実行もでき、PostgreSQLにもパッケージ不要でアクセスできるので、手軽なスクリプティング環境としても便利でいいですね
- この手軽さを活かして、社内DBなどにアクセスする専用MCPサーバとかも簡単に作れそうです