4.PostgreSQL編
PostgreSQL用データプロバイダ「Npgsql(Npgsql2.0RTM)」を使用したDBアクセスについて解説を行います。PostgreSQLについてはWikipediaなどを参照してください。
「Npgsql」はC#コードだけで実装されたPostgreSQL用データプロバイダで、他のネイティブライブラリを必要としません。PostgreSQL 7.x以上に対応しています。
セットアップ
ゲストOS側で動作確認用PostgreSQL DBを作成し、「Npgsql」の準備を行います。
PostgreSQL自体はopenSUSEのソフトウェア管理(YaST2)から導入可能で、導入したパッケージは以下になります(2008.11.6現在)。
| パッケージ | バージョン | 概要 |
| postgresql | 8.2.6 | Basic Clients and Utilities for PostgreSQL |
| postgresql-libs | 8.2.6 | Shared Libraries Required for PostgreSQL Clients |
| postgresql-server | 8.2.6 | The Programs Needed to Create and Run a PostgreSQL Server |
「Npgsql」は、NpgsqlのWebページの「Downloads」から「Npgsql2.0rtm-bin-mono2.0.tar.bz2」をダウンロードして下さい。
PostgreSQL DB
動作確認用DB(TestData)を作成します。PostgreSQL管理用のユーザアカウントとして、「postgres」がパッケージ導入時に登録されるので、「postgres」でログオンし、以下の操作を行います(導入時に設定されるパスワードは不明なので、事前にパスワードの再設定を行いました。また、「postgres」のホームディレクトリは「/var/lib/pgsql」になります)。
テーブル作成用SQLファイルの準備
「/var/lib/pgsql/sql」に以下のテーブル作成用SQLファイルを用意します。
-- psql Testdata -f sql/Products.sql -- -- Products テーブル削除 drop table if exists Products; -- Products テーブル作成 create table Products( ProductID integer not null primary key, ProductName text not null, Price numeric null, ProductDescription text null); -- INSERT 実行 insert into Products (ProductID, ProductName, Price, ProductDescription) values (0, 'PostgreSQL', null, 'PostgreSQL 8.2.6'); -- INSERT 実行 insert into Products (ProductID, ProductName, Price, ProductDescription) values (1, 'Clamp', 12.48, 'Workbench clamp'); -- INSERT 実行 カラムの順番を変えたパターン insert into Products (ProductName, ProductID, Price, ProductDescription) values ('Screwdriver', 50, 3.17, 'Flat head'); -- INSERT 実行 カラムリスト指定なし、入力値リストはカラム順パターン insert into Products values (75, 'Tire Bar', NULL, 'Tool for changing tires.'); -- INSERT 実行 ProductDescription カラムの指定なしパターン insert into Products (ProductID, ProductName, Price) values (3000, '3mm Bracket', .52); -- UPDATE 実行 update Products set ProductName = 'Flat Head Screwdriver' where ProductID = 50; -- SELECT 実行 確認用 select * from Products;
データベースクラスタの作成
> su - postgres > initdb --encoding=UTF8
データベースサーバの起動
> pg_ctl -l logfile start
停止は
> pg_ctl -l logfile stop
データベースの作成
> createdb TestData
テーブルの作成
> psql TestData -f sql/Products.sql
データプロバイダ
Mono 1.9.1から提供されている「mono-data-postgresql」パッケージに含まれる「Npgsql」は「Npgsql 0.7beta3(2004-11-21)」相当のものらしく、プロバイダファクトリ対応クラスが含まれていません。そこでNpgsql本家サイトから、現時点での最新版「Npgsql(Npgsql2)」を入手して使用することにしました。ソースを確認しましたが、プロバイダファクトリ対応クラスNpgsqlFactoryが存在しています。
> cd ~/tmp > tar xjvf Npgsql2.0rtm-bin-mono2.0.tar.bz2 > cd Mono2.0/bin > ls Npgsql.dll Npgsql.dll.mdb Npgsql.xml de es fi fr ja zh-CN
既に導入されていた「mono-data-postgresql」パッケージの削除を試みましたが、「monodevelop-database」パッケージの削除も要求されたので、これをやめ、
- GACへの変更
- MONO_PATHの設定
の2つの方法による対応を試しました。
GACへの変更
「GAC(Global Assembly Cache、グローバル アセンブリ キャッシュ)」は、そのコンピュータ上で複数のアプリケーションからグローバルに参照可能なアセンブリの配置場所になります。今回の動作環境でGACは「/usr/lib/mono/gac」以下になります。GACへの操作は「gacutil」コマンドが使用可能です。「gacutil」コマンドで「Npgsql」を確認してみると、
> gacutil -l Npgsql The following assemblies are installed into the GAC: Npgsql, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Npgsql, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Number of items = 2
実際の配置は
/usr/lib/mono/1.0/Npgsql.dll ← /usr/lib/mono/gac/Npgsql/1.0.5000.0__5d8b90d52f46fda7/Npgsql.dllへのシンボリックリンク /usr/lib/mono/2.0/Npgsql.dll ← /usr/lib/mono/gac/Npgsql/2.0.0.0__5d8b90d52f46fda7/Npgsql.dllへのシンボリックリンク /usr/lib/mono/gac/Npgsql/1.0.5000.0__5d8b90d52f46fda7/Npgsql.dll /usr/lib/mono/gac/Npgsql/2.0.0.0__5d8b90d52f46fda7/Npgsql.dll
となり、C#コンパイラのアセンブリ検索パス自体は「/usr/lib/mono/1.0」(mcs)や「/usr/lib/mono/2.0」(gmcs)になるようです。
いったん「/usr/lib/mono/gac/Npgsql」のバックアップをとってから、「gacutil」コマンドを使用して変更を行うことにしました。
> cd ~/tmp/Mono2.0/bin > su # gacutil -u Npgsql Assembly: Npgsql, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Uninstalled: Npgsql, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Assembly: Npgsql, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Uninstalled: Npgsql, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7 Cleaning assembly dir, it is empty Assemblies uninstalled = 2 Failures = 0 # gacutil -i Npgsql.dll -package 2.0 Package exported to: /usr/lib/mono/2.0/Npgsql.dll -> ../gac/Npgsql/2.0.0.0__5d8b90d52f46fda7/Npgsql.dll Installed Npgsql.dll into the gac (/usr/lib/mono/gac)
「-package」オプションを使用することで、GACに「Npgsql.dll」を登録すると共に、登録した「Npgsql.dll」へのシンボリックリンクを「/usr/lib/mono/2.0」に作成します。「gacutil」コマンドの詳細は「man gacutil」で確認して下さい。
MONO_PATHの設定
Monoでは環境変数MONO_PATHに任意のパスを設定することで、アセンブリ検索パスへ追加することができます。
例えば「mono program.exe」を実行した場合、アセンブリ検索パスは
program.exeと同じディレクトリ -> MONO_PATH -> GAC
になるようです。
MONO_PATHに「~/lib/mono」を設定する場合、アセンブリの配置は
> cd ~/tmp/Mono2.0/bin > cp Npgsql.dll ~/lib/mono/
また、以下の設定を「~/.profile」等に追加することで完了します。
#ADD for Mono
if test -z "$MONO_PATH" ; then
export MONO_PATH="$HOME/lib/mono"
else
export MONO_PATH="$HOME/lib/mono:$MONO_PATH"
fi
ということで、上記2つの方法をそれぞれ行い、次節「DBアクセスー接続確認」を試してみましたが、特に問題はありませんでした。
