16. シェルスクリプト内に Slonik の埋め込み

前に説明したように、シェルスクリプト内で Slonik の生成を埋め込んだ数多くの Slony-I テストスクリプトが src/ducttape にあります。

それらの殆どは、恐ろしいほど洗練された方法でこれを行いません。典型的には、以下のような構造を使用します。

DB1=slony_test1
DB2=slony_test2
slonik <<_EOF_
	cluster name = T1;
	node 1 admin conninfo = 'dbname=$DB1';
	node 2 admin conninfo = 'dbname=$DB2';

	try {
		table add key (node id = 1, fully qualified name = 'public.history');
	}
	on error {
		exit 1;
	}

	try {
		create set (id = 1, origin = 1, comment = 'Set 1 - pgbench tables');
		set add table (set id = 1, origin = 1,
			id = 1, fully qualified name = 'public.accounts',
			comment = 'Table accounts');
		set add table (set id = 1, origin = 1,
			id = 2, fully qualified name = 'public.branches',
			comment = 'Table branches');
		set add table (set id = 1, origin = 1,
			id = 3, fully qualified name = 'public.tellers',
			comment = 'Table tellers');
		set add table (set id = 1, origin = 1,
			id = 4, fully qualified name = 'public.history',
			key = serial, comment = 'Table accounts');
	}
	on error {
		exit 1;
	}
_EOF_

より洗練された手引は何らかの共通要素を定義する事で、特に、全ての Slonik スクリプトに共通な CLUSTER NAME ADMIN CONNINFO コマンドからなる "preamble" です。そうするとこうなります。

CLUSTER=T1
DB1=slony_test1
DB2=slony_test2
PREAMBLE="cluster name = $CLUSTER
node 1 admin conninfo = 'dbname=$DB1';
node 2 admin conninfo = 'dbname=$DB2';
"

そうすると PREAMBLE の値は、シェルスクリプトが複数回 slonik を呼び出せば、その度に何回も再利用されます。同時に、INCLUDE の使用も考慮して、組み込まれたファイルに preamble を配置します。

シェル変数はセットとノードに名前を割り振る簡単な方法を提供します。

origin=1
subscriber=2
mainset=1
slonik <<_EOF_
$PREAMBLE
try {
    table add key (node id = $origin, fully qualified name = 'public.history');
} on error {
    exit 1;
}
try {
	create set (id = $mainset, origin = $origin, comment = 'Set $mainset - pgbench tables');
	set add table (set id = $mainset, origin = $origin,
		id = 1, fully qualified name = 'public.accounts',
		comment = 'Table accounts');
	set add table (set id = $mainset, origin = $origin,
		id = 2, fully qualified name = 'public.branches',
		comment = 'Table branches');
	set add table (set id = $mainset, origin = $origin,
		id = 3, fully qualified name = 'public.tellers',
		comment = 'Table tellers');
	set add table (set id = $mainset, origin = $origin,
		id = 4, fully qualified name = 'public.history',
		key = serial, comment = 'Table accounts');
} on error {
	exit 1;
}
_EOF_

以下のように、テーブルのリストを始めから終りまでループするようにスクリプトを更に機能強化することも可能です。

# Basic configuration
origin=1
subscriber=2
mainset=1
# List of tables to replicate
TABLES="accounts branches tellers history"
ADDTABLES=""
tnum=1
for table in `echo $TABLES`; do
  ADDTABLES="$ADDTABLES
   set add table ($set id = $mainset, origin = $origin,
   id = $tnum, fully qualified name = 'public.$table',
   comment = 'Table $tname');
"
  let "tnum=tnum+1"
done
slonik <<_EOF_
$PREAMBLE
try {
    table add key (node id = $origin, fully qualified name = 'public.history');
} on error {
    exit 1;
}
try {
	create set (id = $mainset, origin = $origin, comment = 'Set $mainset - pgbench tables');
$ADDTABLES
} on error {
	exit 1;
}
_EOF_

たった 4 つのテーブルしか持っていなければこれはなんとなく曖昧な値ですが、手作業による大規模のリストの構成を列挙することに由来するエラーを回避することは、"実生活"で偶然出逢うより大規模な実例には極めて有効です。

もし使用のスクリプト言語に以下が提供されていれば、より洗練されたことが可能です。

もし、 Bash, zsh, もしくは Korn シェル が有効なことに依存するのであれば、 これらの拡張付きシェルは、かなり洗練されたデータ構造とモジュールシステムを提供します。Linux では Bash、商用の UNIX™ では Korn シェルが概ね至る所で有効ですが、BSDでは"洗練された"シェルはデフォルトではなくオプションです。

その時点になって、他のスクリプト言語の調査は意味のあることで、中でも Perl は最も広まっており、Linux、UNIX™、および BSD 上で広範囲に使用されます。