DBIPgSystem - Postgre SQL を使ったデータベース管理システム
Postgre SQL + CGI を使ってデータベース管理を簡単に行うためのシステム。 データの追加・修正・削除、CSVファイル/タブ区切りファイルの読み書き、 データの検索などを行う。
$dbs = DBIPgSystem->new($config_file, $group, $user, %opt);
ARGS : config_file => STRING # データ定義ファイル group => STRING # グループ名 user => STRING # ユーザ名
OPTION : debug => BOOLEAN # true ならばデバッグモード test => BOOLEAN # true ならば動作テストモード nph => BOOLEAN # true ならば NPH
コンストラクタ。
$dbs->search(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : cols => STRING # カラム名 (カンマ区切り) srcsid => STRING # セッションID(検索用) where => STRING # 解析される前の WHERE句 and => STRING # 絞り込み検索を行う v_where => STRING # 変数を埋め込める WHERE句 :* => STRING # v_where に埋め込める変数 page => NUM # 表示するページ searchnum => NUM # 1ページに表示できる件数 html => STRING # 次に表示する HTML strict => BOOLEAN # 厳密な検索 usemeta => BOOLEAN # 対象となる文字をメタ文字として扱う code_dist => STRING # 文字コードの識別のために使う文字列 order => STRING # ORDER句
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF list => ARRAYREF # 検索結果 page => NUM # ページ番号 total => NUM # 検索されたデータの総数 numpage => NUM # 総ページ数 searchnum => NUM # = $qs->{searchnum} where => STRING # 入力されたWHERE句 strict => BOOLEAN # $qs->{strict} に対応する値 join => STRING # $qs->{join} に対応する値 sql_from => STRING # SELECT文のFROM句とJOIN句 sql_where => STRING # SELECT文のWHERE句 v_qs => HASHREF # $qs->{":*"} に対応する値 html => STRING # $qs->{html} に対応する値 usemeta => BOOLEAN # $qs->{usemeta} に対応する値 srcsid => STRING # セッションID cols => STRING # $qs->{cols} に対応する値 uri_qs => STRING # URIクエリー order => STRING # $qs->{order} に対応する値
データの検索を行う。
このサブルーチンを通して検索を行う実用的な方法は、次の5通りである。
1. より柔軟なフォームから間接的に検索条件式を与える方法 $qs->{v_where} に値がある場合はこの形式だとみなす。 また必要に応じて $qs->{:*} に値がなければならない。 ('*' は適切な文字列)。 2. フォームから検索条件式を直接与える方法 1. 以外の場合で、$qs->{direct} に値がある場合は この形式だとみなす。 この場合、$qs->{where} に値がなければならない。 3. URIクエリーから検索条件式を直接与える方法 1,2. 以外の場合で、$session に値がない場合はこの形式だとみなす。 この場合、$qs->{where} に値がなければならない。 4. 絞り込み検索のために検索条件式を直接与える方法 1,2,3. 以外の場合で、$qs->{and} に値がある場合は、この形式だとみなす。 この場合、$qs->{srcsid}, $qs->{where} に値がなければならない。 5. (検索結果のページを変えるときなど)、前回と同じ検索条件を与える方法 1,2,3,4. 以外の場合は、この形式だとみなす。 $qs->{srcsid} に値がなければならない。
1 の場合のみ usemeta の値が検索時に参照される。
検索結果やフォームの値を格納するために、セッションを利用する。 検索条件が変わる場合(1,2,3 の場合)では、 検索条件式の解析に成功したら新しいセッションを作る。 4, 5 の場合では以前に作られたセッションから検索条件式を読み込む。 5 の場合のみ、検索条件式を解析しない。
$qs->{cols} には、$self->{db}{sql_cols} のキーを指定すること。 指定しなければ 'default' が代入される。 $qs->{join} には、$self->{db}{sql_join} のキーを指定すること。 指定しなければ JOIN句はないとみなす。
出力されるデータ $list は、配列へのリファレンスで、 各要素は $qs->{cols} に対応するカラムが格納された配列となる。
セッションには次の変数が保持される : $v_qs, $cols, $qs->{where}, $sql_where, $qs->{html}, $qs->{strict}, $qs->{usemeta}, $total
検索条件式に無関係な $qs->{page} や $qs->{searchnum} はセッション に保持されないので、適した値を指定する必要がある。 $qs->{searchnum} の上限は $opt{searchnum_max} で決められる (デフォルト値は 1000)。
$dbs->search_detail(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : page => NUM # ページ番号 revise => BOOLEAN # データの修正 srcsid => STRING # セッションID(検索用) did => NUM # system_did rid => NUM # system_rid actid => NUM # actid
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF list => ARRAYREF # 検索結果
データの詳細表示のための準備を行う。 または、データの修正を行うための準備を行う。 $qs->{did} または $qs->{rid} に値が格納されている必要がある。 (両方に値がある場合は、$qs->{rid} を優先する。) $qs->{did} が指定されていると、 対応する DID のデータのうち状態が active のものを出力する。 $qs->{rid} が指定されていると、対応する RID のデータを出力する。
$qs->{revise} が true のときは、データの修正とみなし、 セッションを作るなどの準備をする。
$qs->{actid} は、有効なデータに変化があったかどうかを調べるために使われる。 $qs->{actid} が指定されている場合、データの情報を取得した後、 そのデータと同じ DID で状態が有効なデータの RID (ここでは ACTID と呼ぶ) を検索する。 対応する有効なデータがない場合は ACTID は文字列 'null' とする。 ACTID が $qs->{actid} と異なる場合にはエラーを出す。 ACTID を利用すれば、詳細画面を表示し、そのデータの修正を開始するまでの間に データに変化があったことを知ることができる。
$dbs->db2file(%opt);
OPTION : filename => STRING # 出力するファイル名 param => HASHREF # パラメータ ($qs の代わり)
QUERY : srcsid => STRING # セッションID(検索用) type => STRING # 出力するファイルの形式 newline => STRING # ファイルの改行コード code => STRING # ファイルの文字コード (sjis|jis|euc)
データをファイルに書き出す。 $qs->{srcsid} に値が格納されていなければならない。
ファイルの文字コードは $qs->{code} によって決まる。 また、改行コードは $qs->{newline} が ``CR'' ならば \x0D, ``CRLF'' ならば \x0D\x0A, それ以外なら \x0A になる。
$dbs->remove_data(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : noverify => BOOLEAN # invalid にする(確認をしない) rid => NUM # invalid にするデータの system_rid srcsid => STRING # セッションID(検索用) :* => STRING # 主テーブルのカラムの値
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF total => NUM # 対象となるデータの総計 join => STRING # JOIN句 where => STRING # WHERE句 rid => NUM # $qs->{rid} と同じ srcsid => STRING # $qs->{srcsid} と同じ
データの状態を無効にする。 $qs->{noverify} が false のときは、commit コマンドを実行せず、 チェックのみを行う。
$qs->{rid} が指定されているときは、対応する system_rid のデータを無効にする。 さもなければセッションデータのSQL文が使われる。
$qs->{:*} が指定されているときは、削除時に使う WHERE句に ``カラム名 = '値''' を AND で結合し、従って削除するデータに条件を付ける。 複数の $qs->{:*} を指定することもできる。
$dbs->start_insert(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : srcsid => STRING # セッションID(検索用)
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF data => HASHREF # データの情報 ( = { } ) system => HASHREF # システム定義カラムの情報 ( = { } ) revise => BOOLEAN # true ならばデータの修正 ( = 0 ) inssid => STRING # セッションID(挿入用) error => ARRAYREF # エラーの情報 ( = [ ] ) warning => ARRAYREF # 警告の情報 ( = [ ] ) page => NUM # ページ番号 ( = 1 ) islast => BOOLEAN # 次に表示するページの処理が終わった時点で # 全ページの処理が終われば 1 srcsid => STRING # $qs->{srcsid} と同じ vpage => ARRAYREF # 各ページが処理済みかどうかを示す ( = [ ] )
新しいセッションを作り、追加用のページの1ページ目を返す。 (ブラウザの「戻る」のようなボタンを押されたときの動作を考えると、 複数ページにわたってデータの追加を行う場合は、 このメソッドが呼び出されるべきである。)
$dbs->data_check(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : code_dist => STRING # 文字コードの識別のために使う文字列 verify => BOOLEAN # true ならば挿入の確認 inssid => STRING # セッションID(挿入用) page => NUM # 呼び出し元のページのページ番号 system_state => STRING # system_state noencoded => BOOLEAN # false ならば code のデータはエンコード済み nextpage:* # 次に表示するページ、'*' はページ番号 :* => STRING # 主テーブルのカラムの値 :*:*:* => STRING # 関連テーブルのカラムの値 :*:select => STRING # ファイルのアップロード用(主テーブル) # unchange or restore or file or none :*:*:*:select => STRING # ファイルのアップロード用(関連テーブル) :*:insert:* => NUM # 関連テーブルのレコードを別の位置に挿入 :*:delete:* => BOOLEAN # 関連テーブルの特定のレコードを削除
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF data => HASHREF # データの情報 presys => HASHREF # 修正元のデータのシステム定義カラムの情報 system => HASHREF # システム定義カラムの情報 revise => BOOLEAN # データの修正ならば 1 inssid => STRING # セッションID(挿入用) error => ARRAYREF # エラーの情報 warning => ARRAYREF # 警告の情報 page => NUM # ページ番号 islast => BOOLEAN # 次に表示するページの処理が終わった時点で # 全ページの処理が終われば 1 srcsid => STRING # $qs->{srcsid} と同じ vpage => ARRAYREF # 各ページが処理済みかどうかを示す ( = [ ] ) errwarn => HASHREF # エラーと警告の情報 restore => HASHREF # アップロードされたファイルの復元用
データを修正/追加するための準備を行い、draft用のテーブルにデータを挿入する。
$system->{system_did} が空でなければデータの修正とみなす。 この場合、通常セッションに actid の値(search_detail 参照) が格納されているはずである。 actid の値があれば、修正の途中でデータに変更がないことを保証するために、 この値をチェックして一致したときのみ処理を続ける。
staff の権限がない場合は $qs->{system_state} が active であってはならない。
$dbs->data_insert(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : inssid => STRING # セッションID(挿入用) system_state => STRING # system_state srcsid => STRING # セッションID(検索用)
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF # エラーがあった場合は data_check メソッドの RET と同様。 # 以下では、エラーがなかった場合の戻り値を示す。 rid => NUM # 挿入したデータの RID revise => BOOLEAN # データの修正ならば 1 srcsid => STRING # $qs->{srcsid} と同じ
データを本テーブルに修正/追加する。またはキャンセルする。
$qs->{inssid} に値が格納されている必要がある。 セッションデータの did に値があればデータの修正とみなす。
データの修正の場合は、data_checkメソッドと同様に actid のチェックを行う。
$dbs->file_check(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり) read_unit => NUM # 改行コードを調べるときのパラメータ num_large => NUM # 途中経過を表示するために必要なデータ件数
QUERY : remove_head => BOOLEAN # 1行目をヘッダとみなして無視する revise => BOOLEAN # 1(0)ならばデータの修正(追加) system_state => NUM # system_state type => STRING # ファイルの形式('csv' or 'tab', 必須) file => FILE # ファイル(必須) code_dist => STRING # 文字コードの識別のために使う文字列
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF error => ARRAYREF # エラーの情報 warning => ARRAYREF # 警告の情報 over => ARRAYREF # ファイル中に重複のあったデータの位置 ignored => ARRAYREF # 本テーブル中のデータと重複したデータの位置 invalid => ARRAYREF # 外部から修正のあったデータの位置 permission => ARRAYREF # アクセス権がなかったデータの位置 num => HASHREF error => NUM # エラーを含むデータの件数 over => NUM # @{ $ret->{over} } と同じ ignored => NUM # @{ $ret->{ignored} } と同じ success => NUM # 上記以外の(挿入に成功した)データの件数 warning => NUM # 挿入に成功したが警告があるデータの件数 noactive => NUM # データの修正の際 active ではないデータの件数 invalid => NUM # @{ $ret->{invalid} } と同じ permission => NUM # scalar @{ $ret->{permission} } と同じ error_i => NUM # エラーの個数 warning_i => NUM # 警告の個数 total => NUM # データの総計 inssid => STRING # セッションID(挿入用) revise => BOOLEAN # データの修正ならば 1 total_large => BOOLEAN # 途中経過を表示したならば 1
ファイルを追加するための準備を行い、draft用のテーブルにデータを挿入する。
このメソッドでは、指定されたファイルの改行コードと文字コードを調べる。 その後、ファイルの行数を数える。 行数が $opt{num_large} を越えた場合は、 $self->{template}{file_head} を表示した後、途中経過を表示する。
次に SUPER::file_check を読み出して、 1行ずつエラーチェックなどを行いながら draft用のテーブルに挿入する。 最後に、新しいセッションを作り、draft用の RID などを格納する。
$qs->{code_dist} は、フォームに記入された文字列の文字コードを識別 するために使い、ファイルの文字コードの識別には使われない。
$dbs->file_insert(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : cancel => BOOLEAN # キャンセル inssid => STRING # セッションID(挿入用)
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF ins_ignored => ARRAYREF # 本テーブル中のデータと重複したデータの位置 ins_invalid => ARRAYREF # 外部から修正のあったデータの位置 ins_permission => ARRAYREF # アクセス権がなかったデータの位置 num => HASHREF ins_ignored => NUM # @{ $ret->{ins_ignored} } と同じ ins_invalid => NUM # @{ $ret->{ins_invalid} } と同じ ins_permission => NUM # @{ $ret->{ins_permission} } と同じ where_all => STRING # 挿入されたデータを検索するためのWHERE句 revise => BOOLEAN # データの修正ならば 1 total_large => BOOLEAN # 途中経過を表示したならば 1
データを本テーブルに追加/修正する。またはキャンセルする。
$qs->{inssid} に値が格納されている必要がある。 セッションから draft用のテーブルに書き込んだデータの情報を読み込み、 draft用テーブルの対応するデータを本テーブルに挿入する。
cancel が true の場合は、処理のキャンセルとみなし、 file_check メソッドで draft用のテーブルに書き込んだデータを削除する。
$dbs->start_update_passwd($authconf);
ARGS : authconf => STRING # ユーザ情報定義ファイル
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF col => HASHREF # ユーザ情報の値 passsid => STRING # セッションID(ユーザ登録用) update => BOOLEAN # ユーザ情報の更新ならば 1 ( = 1 )
ユーザ情報の更新をする準備を行う。
$dbs->registry_passwd_verify($authconf, %opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
ARGS : authconf => STRING # ユーザ情報定義ファイル
QUERY : passsid => STRING # セッションID(ユーザ登録用) update => BOOLEAN # 更新をする :* # ユーザ情報の値
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF col => HASHREF # ユーザ情報の値 passsid => STRING # $qs->{passsid} と同じ update => BOOLEAN # $qs->{update} と同じ error => ARRAYREF # エラーの情報
ユーザ登録/ユーザ情報の更新の確認を行う。 ユーザ情報の更新 ( $qs->{update} が true ) のときは、 $self->{userinfo}{uid} に値がなければならない。
$dbs->registry($authconf, %opt);
ARGS : authconf => STRING # ユーザ情報定義ファイル
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : passsid => STRING # セッションID(ユーザ登録用) cancel => BOOLEAN # キャンセル
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF col => HASHREF # ユーザ情報の値 passsid => STRING # $qs->{passsid} と同じ update => BOOLEAN # ユーザ情報の更新ならば 1 error => ARRAYREF # エラーの情報
ユーザ登録/ユーザ情報の更新を行う。
$dbs->send_passwd($authconf, %opt);
ARGS : authconf => STRING # ユーザ情報定義ファイル
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : email => STRING # E-mail
RET : ARRAY 0 => STRING # テンプレートファイル 1 => HASHREF email => STRING # $qs->{email} と同じ
指定されたメールアドレスから、対応するユーザ情報を取得し、メールを送る。 パスワードを忘れたときに利用される。
($dtlsid, $dtltotal, $dtlnum, $did) = $dbs->create_detail_session(%opt);
OPTION : param => HASHREF # パラメータ ($qs の代わり)
QUERY : $srcsid => STRING # セッションID(検索用) $rid => NUM # レコードID
RET : @array 0 => STRING # セッションID(詳細表示用) 1 => NUM # 検索されたデータの総数 2 => NUM # レコードID に対応するデータの番号 3 => NUM # データID
詳細表示用のセッションを作る。$rid はなくてもよい。
($rid, $did) = $dbs->get_dtl_session($dtlsid, $num);
ARGS : $dtlsid => STRING # セッションID(詳細表示用) $num => NUM # データの番号
RET : LIST 0 => NUM # レコードID 1 => NUM # データID
詳細表示用のセッションから、対応する番号のデータIDを返す。
$self->test_errcode();
$errcode に指定されたエラーコードが エラーメッセージ定義ファイルで定義されていることを確認する。
($where, $err) = $self->_make_cond_sentence($where_in, %opt);
ARGS : where_in => STRING # 解析前の WHERE句
OPTION : strict => BOOLEAN # subst や検索用カラムのための関数を通さない usemata => BOOLEAN # メタ文字を使用する allow_null => BOOLEAN # 右辺値が '' の単式を無視する and => BOOLEAN # 絞り込み検索 direct => BOOLEAN # v_where を使わない(直接指定する)検索 usealias => BOOLEAN # 左辺値の認識に alias などを用いる
RET : @array 0 => STRING # 解析後の WHERE句 1 => STRING # エラーコード
$where_in を解析し、SQL の WHERE句として適切な文字列を返す。
まず最初に前処理を行い、次に条件式を単式に分解する。 それから各単式について解析を行い、最後に WHERE句を生成する。 解析の途中でエラーが見つかれば、$err にエラーコードを出力する。
各単式の解析は、オプションの値などに応じて臨機応変に行われる。
各単式について、左辺値にはユーザ定義カラム、検索用カラム、 システム定義カラムが指定できる。 ただし、nosearch と設定されているユーザ定義カラムや、 利用を禁止されているシステム定義カラムを指定することはできない。
strict オプションは、subst や検索用カラムのための関数を通すかどうかを 決めるために使われる。 strict オプションが false の場合、左辺値がユーザ定義カラムで、 さらにいくつかの条件を満たす単式について、 右辺値を subst のフィルタに通す。 また対応する検索用カラムがあれば、左辺値を検索用カラムに置き換え、 右辺値を search のフィルタに通す。 勝手に検索用カラムに置き換えられたくない単式には、 左辺値の末尾に文字列 '#s' を付ければよい。
$list = $self->_conv_rpn($in, $op_precedence, $regex_op);
ARGS : in => STRING # 解析前の文字列 op_precedence => HASHREF # 演算子の優先順位が格納されたハッシュ regex_op => REGEX # 演算子の正規表現
文字列を括弧 '(', ')'、演算子 $regex_op、 識別子(それ以外の文字列)に分解し、 後で解析しやすいよう後置記法に変換する。 演算子の前後は空白でなければならない。 でなければ識別子とみなされる。 演算子に大文字・小文字の区別はなく、 $op_precedence の値が小さいほど優先順位が高い。 括弧によって優先順位を変えることができ、括弧のネストにも対応している。 このメソッドでは、識別子に /( $regex_op |[()])/ が含まれていないときに正しい動作をする (これらが含まれないよう適切に前処理されているものとする)。
文法に誤りがなければ、配列へのリファレンスを返す。 さもなければ、エラーコードを返す。
$order = $self->_get_order($in);
ARGS : in => STRING # ORDER句 を表す文字列
RET : STRING # ORDER句
引数を解析して ORDER句を作る。ORDER句は全て小文字で出力される。 解析に失敗したときは undef を返す。 nosearch が true のカラムは ORDER句に含められない。
$session = $self->_session_connect($kind); $session = $self->_session_connect($kind, $sid);
ARGS : kind => STRING # セッションの種類 sid => STRING # セッションID
$sid が指定された場合、セッションを元に戻す。 さもなければ、新しいセッションを作る。
セッションを元に戻すときは、ADDR、グループ、UID、$kind が セッションが作られたときの値と同じでなければならない。
$self->_getparam($query, $param, @lists);
ARGS : query => CGI # CGIモジュールのオブジェクト param => HASHREF # パラメータ lists => ARRAY # 読み込みたいパラメータ
@lists に対応するCGIの パラメータを読み込み、$qs にハッシュの形で格納する。 @lists の各要素は、次のいずれかの形で記述する(Getopt::Long に似ている)。 ただし、'name' は、パラメータの名前に置き換えること。
'name!' # 0 or 1 のいずれかとして評価する 'name=i' # 0以上の整数値として評価する 'name=s' # 文字列として評価する
$self->_pgsqlpack($ref) or die $ERROR;
PostgreSQL の文字列定数中の逆スラッシュ('\')を解釈する。
具体的には '\n', '\035', ``'''' を、それぞれ \x0A, \x1D, ``''' に変換する。 また、上記以外で特殊な意味を持つ文字列('\b', '\f', '\r', '\t', '\xxx') があれば、変換に失敗する。 末尾に単独の逆スラッシュがある場合や、``''' の直後に ``''' が続かない場合にも、 変換に失敗する。 '\n', '\035' 以外の逆スラッシュに続く文字があれば、 始めの逆スラッシュが除かれる。
変換に成功すれば 1 を返す。さもなくば失敗の原因となる文字列を $ERROR に代入し、0 を返す。
Jcode, DBIPgSystem::DB, DBSession, DBIPgSystem::Passwd
Copyright (C) 2002 The Nagoya University Consumers' Co-operative Association
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the following URL for more details: http://www.gnu.org/licenses/gpl.txt
Written by Kenji Nakahira <nakahira@coop.nagoya-u.ac.jp>