ログデータベース
- CAFEMILK SHOPIING CART V5 ではカンマ区切りCSV形式のデータベースを用います。
- 文字コードは UTF-8N となります。
- エクセルの書式に対応しています。
- データベース運用の方法は用途に合わせて基本データベースとログデータベースの二種類があります。
- データベース関連の処理はフレームワークとなっていますので、カスタマイズ時の実装作業が楽です。
- レコードの各項目は SQL のようにカラム名をつけて操作することができ、効率的です。
- 独自仕様であるため、SQL に常態化しているようなデータベースインジェクション脆弱性の危険がありません。
ログデータベースの概要
- ログデータベースは、レコードを収めた10のファイルとそのカラム名を収めたファイルの11ファイルからなるデータベースを運用する形態となります。
- レコードは古くなると消えます。(ログローテンションします。)
- Flock を用いてロックすることはしません。
- ログデータベースでは書き込みは追記しかできません。
- ログデータベースを扱うモジュールのファイル名は以下の通りです。
cafemilk_database_log.pl
- cafemilk_database_log.pl のあるディレクトリは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [pl]
- ログデータベースの扱うデータベースのファイルは例えば以下の通りです。
item_news.0.log.csv.cgi : 新着商品のレコード0
item_news.1.log.csv.cgi : 新着商品のレコード1
item_news.2.log.csv.cgi : 新着商品のレコード2
item_news.3.log.csv.cgi : 新着商品のレコード3
item_news.4.log.csv.cgi : 新着商品のレコード4
item_news.5.log.csv.cgi : 新着商品のレコード5
item_news.6.log.csv.cgi : 新着商品のレコード6
item_news.7.log.csv.cgi : 新着商品のレコード7
item_news.8.log.csv.cgi : 新着商品のレコード8
item_news.9.log.csv.cgi : 新着商品のレコード9
item_column_list.csv... : 新着商品のカラム名
- データベースは標準にてセーフモードで運用されます。
- パーミッションファイルのないディレクトにあるデータベースの読み書きはできません。
- 標準のセーフモードは以下のように指定されています。
$config->{database}{safety} = '1';
- $config->{database}{safety} を設定しているファイルは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [config]
└ [admin]
└ config_basic.pl
- セーフモードにて要求されるパーミッションファイルは以下の通りです。
[permit_database_connect.txt]
ログデータベースの操作のサンプル
まずはデータベース接続
my $log_database = Cafemilk_database_log->connect
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
column_filename => 'log/access_log_column_list.csv',
column_separator => ',',
database_filename => 'log/access_log',
database_separator => ',',
record_stack => $config->{database}{log_stack}{common},
});
ログとして書き込む内容の作成
my $error = "@{$log_error}";
my $alert = "@{$log_alert}";
$error =~ s/\x0D\x0A|\x0D|\x0A//g;
$alert =~ s/\x0D\x0A|\x0D|\x0A//g;
my %records =
(
id => $userdata->{'time'},
time => $userdata->{'time'},
admin_name => $userdata->{admin_registry_values}{admin_name},
user_name => $userdata->{user_registry_values}{user_name},
execute => $userdata->{request_values}{execute}[0],
ip_address => $ENV{'REMOTE_ADDR'},
referer => $ENV{'HTTP_REFERER'},
# post => $ENV{'CONTENT_LENGTH'},
# get => $ENV{'QUERY_STRING'},
# cookie => $ENV{'HTTP_COOKIE'},
# error => $error,
# alert => $alert,
);
追記
$log_database->postscript(\%records);
終了処理
undef $log_database;
- 以下は、最後のレコードを取得する場合のサンプルとなります。
my $database = Cafemilk_database_log->connect
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
column_filename => 'database/forum_thread_column_list.csv',
column_separator => ',',
database_filename => 'database/admin_forum_thread',
database_separator => ',',
record_stack => $config->{database}{session_stack}{admin_forum}{thread},
});
条件に合う最後のレコードを取得
my $extract_database = $database->extract_last_record
({
extract_column_name => 'thread_id',
extract_column_value => $message_values{thread_id},
});
%thread_values にレコードのカラム名と値を格納
%thread_values = $database->get_values_argument
({
database_values => $extract_database,
});
undef $database;
- 以下は、最後のレコードを取得して内容を修正し、追記する場合のサンプルとなります。
my $database = Cafemilk_database_log->connect
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
column_filename => 'log/sale_count_column_list.csv',
column_separator => ',',
database_filename => 'log/sale_count',
database_separator => ',',
record_stack => 10,
});
my $extract_database = $database->extract_last_record
({
extract_column_name => 'dummy',
extract_column_value => 'count',
});
%count_values にレコードのカラム名と値を格納
my %count_values = $database->get_values_argument
({
database_values => $extract_database,
});
%count_values の変更
$count_values{count} ++;
$status->{sale_count} = $count_values{count};
$count_values{id} = $userdata->{'time'};
$count_values{time} = $userdata->{'time'};
$count_values{dummy} = 'count';
追記
$database->postscript(\%count_values);
undef $database;
- 以下は、データベスーから特定の条件に合うレコード(複数)を抽出して、抽出された各レコードを順次処理していく場合のサンプルとなります。
まずはデータベース接続
my $database = Cafemilk_database_log->connect
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
column_filename => 'database/item_column_list.csv',
column_separator => ',',
database_filename => 'database/item_news',
database_separator => ',',
record_stack => $config->{database}{session_stack}{item}{news},
});
全レコードの読み込み
$database->get_record_all();
追記により重複しているレコードを最新のものを除いて削除
$database->merge_database
({
column_name => 'item_id',
});
完全一致カラム抽出処理
my $target = 'multiprice';
$database->match_database
({
column_name => 'item_type',
match_word => $target,
});
検索文字列の用意
文字列はスペース区切りで AND 検索となる
my $words = $input_values{'search'};
$words = Cafemilk_basic::decode_escape
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
text => $words,
});
検索の対象となるカラムの指定
my @columns =
(
"item_id",
"name_$userdata->{language_type}",
"text_1_$userdata->{language_type}",
"text_2_$userdata->{language_type}",
"manufacturer_$userdata->{language_type}",
"table_value_1_$userdata->{language_type}",
"table_value_2_$userdata->{language_type}",
"table_value_3_$userdata->{language_type}",
"table_value_4_$userdata->{language_type}",
"option_name_1_$userdata->{language_type}",
"option_name_2_$userdata->{language_type}",
"option_name_3_$userdata->{language_type}",
);
検索実行
$database->search_database
({
search_column => \@columns,
search_words => $words,
英字の大文字と小文字の区別
1 でしない
character_mode => '1',
});
並び替え処理
$database->sort_database
({
column_name => "price_main_$userdata->{currency_type}",
逆順処理
1 で逆順
reverse_mode => '0',
並び替えモード
number_quick で数値モード
character_quick で文字モード
sort_mode => 'number_quick',
});
抽出・検索・並び替えされたレコードを取得
my @lines = $database->get_extract_database();
レコード処理
foreach (@lines)
{
my $line = $_;
レコードの分割とカラム名との関連づけ
my %target_values = $database->get_values_argument
({
database_values => $line,
});
ここで例えばレコードの内容の表示処理を行う
print $target_values{item_id};
}
終了処理
undef $database;