plpgsql_check.dllのビルドメモ
●はじめに
postgresqlの関数は文法エラーチェックを実行時に行います。(oracleとは異なる。)
開発実装時にエラーをチェックする場合にplsql_checkが非常に便利で使っています。
エラー箇所がリアルタイムでわかるためリリース時の不具合混入を大幅に減らせます。
●用意するもの
-
plpgsql_check本体
https://github.com/okbob/plpgsql_check からcloneで丸ごとダウンロード
Clone or downloadボタンをクリック
ダウンロードしたファイルをC:\plpgsql_check に解凍しておく。 -
postgresql 12
以下のサイトからダウンロード
https://www.enterprisedb.com/downloads/postgres-postgresql-downloads -
VisualStudio 2019
MSサイトからダウンロード(無料版可)
-
icu4c-67_2-Win64-MSVC2017
https://ja.osdn.net/projects/sfnet_icu/downloads/ICU4C/64.2/icu4c-64_2-Win64-MSVC2017.zip/
C:\plpgsql_check\icu4c-67_1-Win64-MSVC2017に解凍しておく。
●plpgsql_checkのビルド
-
Visual studio2019で新規プロジェクトを作成
プロジェクト名はplpgsql_checkにしておく。
プロジェクトのテンプレートはDLL(ユニバーサル)を選択
プロジェクトのプロパティを
構成をDebug
プラットフォームをx64
に変更。 -
以下のファイルをプロジェクトから削除(これらのファイルは使用しない)
targetver.h
dllmain.cpp
pch.cpp
pch.h
plpgsql_check\plpgsql_check.cpp
plpgsql_check.h -
使用するソースとヘッダを追加
C:\plpgsql_check\srcの.cと.hを全部プロジェクトに追加する。 -
C:\plpgsql_check\lib\plpgsql.libファイルを生成
DLLをlibに変換をググれば手順がわかります。
Visual studioから開発者コマンドプロンプトを開く。
mkdir C:\plpgsql_check\lib
cd C:\plpgsql_check\lib
copy "C:\Program Files\PostgreSQL\12\lib\plpgsql.dll" C:\plpgsql_check\lib
dumpbin /exports C:\plpgsql_check\lib\plpgsql.dll > plpgsql.def
plpgsql.defをsakura.exeなどで開いて短径選択し名前だけのファイルにする。
lib /def:C:\plpgsql_check\lib\plpgsql.def /OUT:C:\plpgsql_check\lib\plpgsql.lib /machine:x64
```
5. VisuaStudioでlibとincludeパスを追加する。
プロジェクトのプロパティ設定からそれぞれのパスとファイルを指定する。
●includeパスを追加
C:\Program Files\PostgreSQL\12\include\server
C:\Program Files\PostgreSQL\12\include
C:\Program Files\PostgreSQL\12\include\server\port\win32
C:\Program Files\PostgreSQL\12\include\server\port\win32_msvc
C:\plpgsql_check\icu4c-67_1-Win64-MSVC2017\include
**●libパスを追加**(追加のライブラリディレクトリ)
C:\plpgsql_check\lib
C:\Program Files\PostgreSQL\12\lib
C:\plpgsql_check\icu4c-67_1-Win64-MSVC2017\lib64
**●リンカーの追加の依存ファイルに以下のlibを追加**
postgres.lib
plpgsql.lib
-
VisuaStudioでのCオプションのプリコンパイル済みヘッダを変更する。
使用しないにする。
-
VisuaStudioでプロジェクトをビルドする。
以下のDLLが生成されれば成功
plpgsql_check\x64\Debug\plpgsql_check\plpgsql_check.dll -
以下の3つのファイルをPostgreSQLフォルダのサブフォルダにコピーする。
copy plpgsql_check.dll "C:\Program Files\PostgreSQL\12\lib\plpgsql_check.dll"
copy C:\plpgsql_check\plpgsql_check.control "C:\Program Files\PostgreSQL\12\share\extension"
copy C:\plpgsql_check\plpsql_check--1.9.sql "C:\Program Files\PostgreSQL\12\share\extension"
```
-
psqlでpostgresqlにログインし以下のcreate extensionコマンドを実行する。
CREATE EXTENSION plpgsql_check; -
psqlで全エラー検索するためのSQLを実行してみる。
以下のSQLでエラー関数を検索
```SQL
select
p.proname as "NAME"
, (pcf).functionid::regprocedure
, (pcf).lineno, (pcf).statement
, (pcf).sqlstate
, (pcf).message
, (pcf).detail
, (pcf).hint
, (pcf).level
, (pcf)."position"
, (pcf).query
, (pcf).context
, (pcf).message as "ERROR"
FROM pg_proc p LEFT outer JOIN
(SELECT pro.oid as pro_oid
, plpgsql_check_function_tb(pro.oid, COALESCE(tr.tgrelid, 0)) AS pcf
FROM pg_proc pro
LEFT JOIN pg_trigger tr
ON (tr.tgfoid = pro.oid)
WHERE
prolang = (SELECT lang.oid FROM pg_language lang WHERE lang.lanname = 'plpgsql') AND
pronamespace <> (SELECT nsp.oid FROM pg_namespace nsp WHERE nsp.nspname = 'pg_catalog') AND
-- ignore unused triggers
(pro.prorettype <> (SELECT typ.oid FROM pg_type typ WHERE typ.typname = 'trigger') OR
tr.tgfoid IS NOT NULL)
OFFSET 0
) ss on p.oid = ss.pro_oid
```