#============================================================ # DatabaseObject #============================================================ package DatabaseObject; use Common; @ISA = qw(Common); #公開したいサブルーチン #@EXPORT = qw(erfc tan); @EXPORT_OK = qw(); use strict; use Sys::Hostname; #========================================== # 大域変数 #========================================== my $ModuleName = "DatabaseObject"; my $ModuleExplanation = "Root class of Database"; # 利用特権 my $Privilege = 'DBManage'; my $DownloadPrivilege = 'Download'; my $ShowPasswordPrivilege = 'ShowPassword'; sub Name { return $ModuleName; } sub Explanation { return $ModuleExplanation; } sub Privileges { return "$Privilege,$DownloadPrivilege,$ShowPasswordPrivilege"; } # DB Dumpをする周期 my $MinimumPastTime = 6 * 60 * 60; my $AllowUpdateActiveAccounts = 0; #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module, $modulename, $privilege, $downloadprivilege, $minimumpasttime) = @_; my $this = {}; bless $this; # $this->SUPER::new(@_); $ModuleName = $modulename if(defined $modulename); $Privilege = $privilege if(defined $privilege); $DownloadPrivilege = $downloadprivilege if(defined $downloadprivilege); $MinimumPastTime = $minimumpasttime if(defined $minimumpasttime); return $this; } sub DESTROY { my $this = shift; $this->SUPER::DESTROY(@_); } sub GetLinkString { my ($this, $App, $pParams, $key, $pHash, $label, $target, $dir, $filename, $path, $NextAction) = @_; #$App->print("key=$key, $label\n"); my $pParams = ($App->pParams())? $App->pParams() : $pHash; #$App->print("EM: $pParams->{EMail} [$pParams]\n"); my ($Option, $target2) = $App->GetCGIParameters( { EMail => $pParams->{EMail}, Password => $pParams->{Password}, PrevAction => $pParams->{Action}, }, [qw(NextAction App EMail Password Language App ShowAll ExtendedMenu PrevAction DBConfigName Year Month Day Keyword1 SearchTarget1 Operator1 Keyword2 SearchTarget2 Order Ascend ShowAccepted ShowPending ShowReconsider ShowTSFTOEOProc ShowTOEOProc ShowReject ValidAbstractOnly ValidProgramOnly LocalOrganizingCommitteeOnly UnsendAbstractAceptanceNoticeOnly)], undef, undef, 0, { URLEncode => 1, ConvertCharCode => $pParams->{WebCharCode} } ); if($key eq 'DownloadDBDumpFile') { my $path = $filename; #$pHash->{DBDumpFilePath} if(!defined $path); my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($path); my $size = int(Utils::GetFileSize($path) / 1024); $label = "$filename ($size kB)" if(!defined $label); my $DownloadLink = "$pParams->{ScriptPath}?Action=Database::DownloadDBDumpFile&File=$filename&$Option"; return "$label"; } return "{ScriptPath}?Action=$key&sn=$pHash->{sn}&$Option\" target=\"$target\">$label"; # return "Error in ConfApp3::GetLinkString: Invalid key [$key]"; } #============================================================ # メンバー関数 #============================================================ sub OnLoad { my ($this, $App, $pParams) = @_; } sub OnInitialized { my ($this, $App, $pParams) = @_; } sub GetParameterHash { my ($this) = @_; return {}; } sub IsOpen { my ($this, $App, $pParams, $IsPrint) = @_; # return $App->HasPrivilege($Privilege, $IsPrint); return 1 if($App->HasPrivilege($Privilege, $IsPrint)); return 1 if($App->HasPrivilege('DownloadDBDump', $IsPrint)); return 0; } sub CanDownload { my ($this, $App, $pParams, $IsPrint) = @_; return $App->HasPrivilege($DownloadPrivilege, $IsPrint); } sub ShowMenu { my ($this, $App, $pParams, $ProgramPath, $BaseOption) = @_; return if(!$this->IsOpen($App, $pParams, 0)); my ($Option, $target) = $App->GetCGIParameters( { Action => "${ModuleName}::ShowPage", PrevAction => $pParams->{Action}, }, [qw(+Action +IsChildFrame +FrameMode)]); $App->PrintRawHTML("{ScriptPath}?$Option\" target=\"$target\">" . $App->mlText('en' => 'Database', 'jp' => 'DB管理') . " "); } sub ShowSubMenu { my ($this, $App, $pParams, $ShowMenu) = @_; return $this->ShowPage($App, $pParams, $ShowMenu); } sub ShowPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $ShowMenu = 1 if(!defined $ShowMenu); my $CanDBManage = $App->HasPrivilege('DBManage', 0); my $CanDownloadDBDump = $App->HasPrivilege('DownloadDBDump', 0); return if(!$CanDBManage and !$CanDownloadDBDump); if($App->{pAdminOption} and $ShowMenu) { $App->{pAdminOption}->ShowSubMenu($App, $pParams); } my ($Option, $target) = $App->GetCGIParameters( { PrevAction => $pParams->{Action}, }, [qw(+IsChildFrame +FrameMode)]); # my $Option = $App->BuildCGIOption( # { # PrevAction => $pParams->{Action}, # }, # [qw(App EMail Password Language ShowAll ExtendedMenu PrevAction DBConfigName Year Month Day)], # ); $App->H2("DB Manage"); if($CanDownloadDBDump) { $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowDBStructureDumpPage&$Option\" target=\"_self\">" . $App->mlText('en' => 'DB Structure Dump(Only for MySQL)', 'jp' => 'Dump構造バックアップの実行(MySQLのみ)') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowDBDumpPage&$Option\" target=\"_self\">" . $App->mlText('en' => 'DB Dump(Only for MySQL)', 'jp' => 'Dumpバックアップの実行(MySQLのみ)') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowBackupCSVPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'Backup(CSV)', 'jp' => 'バックアップ(CSV)') . "
"); $App->print("\n"); } if($CanDBManage) { $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowMySQLTips&$Option\" target=\"$target\">" . $App->mlText('en' => 'Show MySQL Tips', 'jp' => 'MySQLの使い方') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::DatabaseStructures&$Option\" target=\"$target\">" . $App->mlText('en' => 'Show DB Structure', 'jp' => 'DB構造の表示') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::DatabaseStructuresByDESC&$Option\" target=\"$target\">" . $App->mlText('en' => 'Show DB Structure (DESC)', 'jp' => 'DB構造の表示(DESC)') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowDBDataPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'View DB Data', 'jp' => 'DBデータ表示') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowSimpleSQLPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'Simple SQL operations', 'jp' => '簡単なSQL操作') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowSQLPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'Send SQL code', 'jp' => 'SQLコードの送信') . "
"); $App->print("\n"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowDatabaseEditForm&$Option\" target=\"$target\">" . $App->mlText('en' => 'Show DB Edit Form', 'jp' => 'DB編集フォームの表示') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowSyncDBPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'SyncDB', 'jp' => 'DBの同期') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowAddSchedulesPage&$Option\" target=\"$target\">" . $App->mlText('en' => 'Add Schedules', 'jp' => 'スケジュールの一括登録') . "
"); $AllowUpdateActiveAccounts = $pParams->{AllowUpdateActiveAccounts} if(defined $pParams->{AllowUpdateActiveAccounts}); my $opt = ($AllowUpdateActiveAccounts)? '(Active)' : '(Invalidated)'; $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowUpdateActiveAccountPage&$Option\" target=\"_self\">" . $App->mlText('en' => "Update Active Account $opt", 'jp' => "アクティブアカウントの移行 $opt") . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::CorrectCharCode&$Option\" target=\"$target\">" . $App->mlText('en' => 'Correct CharCode', 'jp' => '文字コードの修正') . "
"); $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::ShowRemoveNULLPasswordPage&$Option\" target=\"_self\">" . $App->mlText('en' => 'Remove NULL Password', 'jp' => '空白パスワードの削除') . "
"); } } sub DownloadBackupCSV { my ($this, $App, $pParams) = @_; return if(!$App->HasPrivilege('DownloadDBDump', 1)); # return if(!$this->IsOpen($App, $pParams)); $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $TableName = $pParams->{File}; my $CSVFileName = $TableName . ".csv"; my $CSVPath = Deps::MakePath($pParams->{TempDir}, $CSVFileName); Utils::DownloadFile($App->Args()->CGIForm(), $CSVPath, $CSVFileName); } sub ShowBackupCSVPage { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams) and !$App->HasPrivilege('DownloadDBDump', 0)); # return if(!$this->IsOpen($App, $pParams)); # return if(!$this->CanDownload($App, $pParams)); my $Language = $App->Language(); $this->ShowPage($App, $pParams); $App->HR(); $App->H2("Download DB files"); #$App->print("DB: $pParams->{DBName}\n"); my @Tables = $App->DB()->GetTables($pParams->{DBName}, 1); #$App->print("Tables: ", join(', ', @Tables), "\n"); foreach my $DBTable (@Tables) { #$App->print("DBTable: $DBTable\n"); my $CSVFileName = $DBTable . ".csv"; my $CSVPath = Deps::MakePath($pParams->{TempDir}, $CSVFileName); if($App->DB()->SaveToCSV($DBTable, "", "", $CSVPath, $pParams->{CSVCharCode})) { $App->PrintRawHTML("{ScriptPath}?Action=${ModuleName}::DownloadBackupCSV&File=$DBTable&" ."EMail=$pParams->{EMail}&Password=$pParams->{Password}&" ."Language=$pParams->{Language}&DBConfigName=$pParams->{DBConfigName}\">" ."$DBTable
\n"); } else { $App->H3("Error in ShowBackupPage: Can not write to [$CSVPath]"); } } } sub DownloadDBDumpFile { my ($this, $App, $pParams) = @_; return if(!$App->HasPrivilege('DownloadDBDump', 0)); # return if(!$this->CanDownload($App, $pParams)); $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $BackupDir = Utils::MakePath($pParams->{DatabasesDirectory}, "Backup", '/', 0); my $Path = Utils::MakePath($BackupDir, $pParams->{File}, '/', 0); Utils::DownloadFile($App->Args()->CGIForm(), $Path, $pParams->{File}); } sub ExecuteDBDump { my ($this, $App, $pParams, $IsPrint, $CheckPeriod) = @_; $IsPrint = 1 if(!defined $IsPrint); $IsPrint = $pParams->{IsPrint} if(defined $pParams->{IsPrint}); if($IsPrint) { $this->ShowPage($App, $pParams); $App->HR(); } if(!$App->DB()) { $App->H3("Warning in DatabaseObject::ExecuteDBDump: DB is not obtained.\n") if($IsPrint); return; } delete $pParams->{IsPrint}; my $CanExecuteDBDump = $App->HasPrivilege('ExecuteDBDump', $IsPrint); #$App->print("Can: $CanExecuteDBDump\n"); return -1 if(!$this->IsOpen($App, $pParams, $IsPrint) and !$CanExecuteDBDump); $CheckPeriod = 0 if(!defined $CheckPeriod); $CheckPeriod = $pParams->{CheckPeriod} if(defined $pParams->{CheckPeriod}); delete $pParams->{CheckPeriod}; #$IsPrint=1; #$App->print("P: $IsPrint C: $CheckPeriod\n"); if($pParams->{DatabasesDirectory} eq '') { $App->H2("Error in DatabaseObject::ExecuteDBDump: NULL DatabaseDirectory is not allowed\n"); return -2; } my $BackupDir = Utils::MakePath($pParams->{DatabasesDirectory}, "Backup", '/', 0); Deps::CreateDirecotry($BackupDir); my $DBStructureOnly = $pParams->{DBStructureOnly}; my ($year, $mon, $mday, $hour, $min, $sec, $year, $wday, $yday, $isdst) = Utils::GetDateTime(time(), 0); my $BackupPath = Utils::MakePath($BackupDir, sprintf("$pParams->{DBName}-%04d%02d%02d-%02d%02d%02d.mysql", $year, $mon, $mday, $hour, $min, $sec), '/', 0); #$IsPrint=1; if($IsPrint) { $App->H3("Dump databases for MySQL\n"); $App->print("Backup Directory: $BackupDir\n"); $App->print("Backup File: $BackupPath\n"); $App->print("DB Structure Only: $DBStructureOnly\n"); } #$App->print("CP: $CheckPeriod\n") if($IsPrint); if($CheckPeriod) { my $fmask = Utils::MakePath($BackupDir, "*.mysql", '/', 0); my @files = sort { -M $a <=> -M $b } glob($fmask); # my @files = sort { $b cmp $a } glob($fmask); if(@files > 0) { my $LastFileCreationTime = Utils::GetWriteDate($files[0]); my $now = time(); my $diff = $now - $LastFileCreationTime; #$App->print("CT: [$files[0]]$LastFileCreationTime : $now : $diff > $MinimumPastTime ?\n") if($IsPrint); return -3 if($diff < $MinimumPastTime); # foreach my $f (@files) { # my $size = Utils::GetFileSize($f); # $App->print(" $f [$size bytes]\n"); # } } } #return; my $opt = ($DBStructureOnly)? '-d' : ''; my $cmd = "mysqldump $opt -h $pParams->{DBServer} -u $pParams->{DBUser} --password=$App->{DBPassword} --database $pParams->{DBName} > $BackupPath"; #$App->print("cmd: $cmd\n"); $App->ExecuteCommand($pParams, $cmd, 0); # system($cmd); if($IsPrint) { $App->HR(); $this->ShowDBDumpPage($App, $pParams); } return 1; } sub ShowDBStructureDumpPage { my ($this, $App, $pParams) = @_; $pParams->{DBStructureOnly} = 1; $this->ShowDBDumpPage($App, $pParams); } sub ShowDBDumpPage { my ($this, $App, $pParams) = @_; # return if(!$this->IsOpen($App, $pParams) or $App->HasPrivilege('DownloadDBDump', 0)); # return if(!$this->CanDownload($App, $pParams)); return if(!$App->HasPrivilege('ManageDB', 1) and !$App->HasPrivilege('DownloadDBDump', 1)); $this->ShowPage($App, $pParams); $App->HR(); if(!$App->DB()) { $App->H3("Warning in DatabaseObject::ExecuteDBDump: DB is not obtained.\n"); return; } my $BackupDir = Utils::MakePath($pParams->{DatabasesDirectory}, "Backup", '/', 0); Deps::CreateDirecotry($BackupDir); $App->H2("Backup list\n"); my $fmask = Utils::MakePath($BackupDir, "*.mysql", '/', 0); #$App->print("f: $fmask\n"); my @files = sort { $b cmp $a } glob($fmask); foreach my $f (@files) { # my $size = Utils::GetFileSize($f); # $App->print(" $f [$size bytes]\n"); my $LinkStr = $this->GetLinkString($App, $pParams, "DownloadDBDumpFile", $pParams, undef, "_blank", $BackupDir, $f, undef) . "\n"; $App->PrintRawHTML("$LinkStr
\n"); } print <

Dump database $pParams->{DBName} (for MySQL)

Backup Directory: $BackupDir
DB Structre Only
EOT } sub ShowUpdateActiveAccountPage { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); $this->ShowPage($App, $pParams); $App->HR(); #$App->H2("A[$pParams->{AllowUpdateActiveAccounts}]\n"); $AllowUpdateActiveAccounts = $pParams->{AllowUpdateActiveAccounts} if(defined $pParams->{AllowUpdateActiveAccounts}); $App->H2("Update Active Account\n"); my $db = $App->DuplicateDB(); my @TableDef = ( ["sn" => "==>{sn}"], ["EMail" => "{EMail}"], ["Name" => "{Name}"], ["Category" => "{Category}"], ["Privilege" => "{Privilege}"], ["Status" => "{FiscalYear}
{Status}"], # ["Password" => "{Password}"], ); my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time()); $year += 1900; my $SourceYear = $year - 1; if($pParams->{UpdateActiveAccounts}) { $App->H3("Update Active Users for Year [$pParams->{NewFiscalYear}]\n"); } else { $App->H3("Active Users\n"); print <
Source Fiscal Year: $SourceYear
New Fiscal Year:
EOT } # $App->SearchUsers("order by sn", ""); # $App->SearchUsers("Status='Active' order by sn", ""); $App->SearchUsers("FiscalYear=$SourceYear and Status='Active' order by sn", ""); # $App->SearchUsers("FiscalYear=$SourceYear and Status='Active' and (Privilege like '%LogonLevel1%' or Privilege like '%LogonLevel2%') order by Privilege,EMail,sn", ""); my $nHit = $App->nHit(); if(!$AllowUpdateActiveAccounts) { $App->H2("Warning: UpdateActiveAccounts is not allowed.\n"); } $App->print("$nHit found.\n"); $App->BeginTable(1); $App->TableRowByDefinition(\@TableDef, 0); for(my $i = 0 ; $i < $nHit ; $i++) { my %Hit = $App->GetNextHit(); # next if($Hit{Status} ne 'Active'); # $Hit{Password} = int(rand() * 10000000000); # $db->Search($pParams->{UsersTableName}, "FiscalYear=2008 and EMail='$Hit{EMail}' order by sn", ""); # my %Hit2 = $db->GetNextHit(); # $Hit{Password} = $Hit2{Password}; # $Hit{Status} = 'Active'; # $db->UpdateData($pParams->{UsersTableName}, "sn=$Hit{sn}", Status => 'Active', Password => $Hit2{Password}); $App->TableRowByDefinition(\@TableDef, 1, \%Hit); if($AllowUpdateActiveAccounts and $pParams->{UpdateActiveAccounts}) { #$App->print("Change sn=$Hit{sn} to null Status\n"); $db->UpdateData($pParams->{UsersTableName}, "sn=$Hit{sn}", Status => ''); $Hit{FiscalYear} = $pParams->{NewFiscalYear}; delete $Hit{sn}; #$App->print("Insert data\n"); $db->InsertData($pParams->{UsersTableName}, %Hit); } elsif(!$AllowUpdateActiveAccounts) { # $App->H3("UpdateActiveAccounts is not allowed.\n"); } } $App->EndTable(); } sub RemoveNULLPassword { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); my $db = $App->DuplicateDB(); my @TableDef = ( ["sn" => "==>{sn}"], ["EMail" => "{EMail}"], ["Name" => "{Name}"], ["Category" => "{Category}"], ["Priivlege" => "{Privilege}"], ["Password" => "{Password}"], ); $App->H3("Remove NULL Password\n"); $App->SearchUsers("(Password is null or Password='') and (Privilege is not null and Privilege!='') order by sn", ""); my $nHit = $App->nHit(); $App->print("$nHit found.\n"); # $App->BeginItem(1); $App->BeginTable(1); $App->TableRowByDefinition(\@TableDef, 0); for(my $i = 0 ; $i < $nHit ; $i++) { my %Hit = $App->GetNextHit(); $Hit{Password} = int(rand() * 10000000000); # $App->PrintItem("$Hit{sn}: $Hit{Name} ($Hit{EMail}) [$Hit{Category}] [$Hit{Privilege}]: Password='$Hit{Password}'"); $App->TableRowByDefinition(\@TableDef, 1, \%Hit); $db->UpdateData($pParams->{UsersTableName}, "sn=$Hit{sn}", Password => $Hit{Password}); } # $App->EndItem(1); $App->EndTable(); $App->H3("Random passwords have been added to the above users.\n"); } sub ShowRemoveNULLPasswordPage { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); $this->ShowPage($App, $pParams); $App->HR(); my @TableDef = ( ["sn" => "==>{sn}"], ["EMail" => "{EMail}"], ["Name" => "{Name}"], ["Category" => "{Category}"], ["Priivlege" => "{Privilege}"], ); $App->H2("Remove NULL Password\n"); $App->H3("List of NULL Password Users\n"); $App->SearchUsers("(Password is null or Password='') and (Privilege is not null and Privilege!='') order by sn", ""); my $nHit = $App->nHit(); $App->print("$nHit found.\n"); $App->BeginForm(undef, undef, undef, 0); # $App->BeginItem(1); $App->BeginTable(1); $App->TableRowByDefinition(\@TableDef, 0); for(my $i = 0 ; $i < $nHit ; $i++) { my %Hit = $App->GetNextHit(); # $App->PrintItem("$Hit{sn}: $Hit{Name} ($Hit{EMail}) [$Hit{Category}] [$Hit{Privilege}]"); $App->TableRowByDefinition(\@TableDef, 1, \%Hit); } # $App->EndItem(1); $App->EndTable(); $App->EndForm({Action => "${ModuleName}::RemoveNULLPassword"}, undef); } sub ExecuteSQL { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $ShowPassword = $App->HasPrivilege($ShowPasswordPrivilege); $this->ShowSQLPage($App, $pParams, $ShowMenu); $App->HR(); $App->PrintRawHTML("SQLCode: $pParams->{SQLCode}
\n"); my $DB = $App->DB(); my ($sth, $ret) = $DB->Execute($pParams->{SQLCode}, undef, 1); $App->print("ret: $ret\n"); return if(!defined $ret); my $nHit = $DB->nHit(); my $nrow = $DB->rows(); $App->print("$nHit [$nrow] found.\n"); my $c = 1; for(my $i = 0 ; $i < $nHit or $i < $nrow ; $i++) { if($pParams->{SQLCode} =~ /select/i) { my %Hit = $DB->GetNextHit(); #$App->print("P: [$Hit{Password}][ShowPassword=$ShowPassword]\n"); # last if(!defined $Hit{sn}); $App->HR(); $App->PrintRawHTML("Hit#$c
\n"); foreach my $key (sort keys %Hit) { next if($key eq 'Password' and !$ShowPassword); $App->PrintRawHTML("$key: $Hit{$key}
\n"); } } else { my @a = $DB->fetchrow_array(); last if(@a == 0); $App->HR(); $App->PrintRawHTML("Hit#$c
\n"); for(my $i = 0 ; $i < @a ; $i++) { $App->print("$a[$i]\n"); } } $App->print("\n"); $c++; } } sub AddSchedules { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $lines = $pParams->{Schedules}; my @a = Utils::Split("[\\r\\n\\s]*[\\r\\n][\\r\\n\\s]*", $lines); for(my $i = 0 ; $i < @a ; $i++) { #$App->print("$a[$i]\n"); $a[$i] =~ s/\s*\d+\s*$//; my ($date, $starttime, $endtime, $description) = ($a[$i] =~ /^\s*([\d\/]+)\s+([\d:\*\?]+)\-([\d:\*\?]+)\s+(.*?)\s*$/); if(!defined $date) { ($date, $description) = ($a[$i] =~ /^\s*([\d\/]+)\s+(.*?)\s*$/); ($starttime, $endtime) = ('*', '*'); } next if(!defined $date); $App->print("$description: "); my ($Year, $Month, $Day); if($date =~ /^(\d+)\/(\d+)\/(\d+)$/) { ($Year, $Month, $Day) = Utils::Split("\\/", $date); } elsif($date =~ /^(\d+)\/(\d+)$/) { ($Month, $Day) = Utils::Split("\\/", $date); my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time()); $Year = $year + 1900; } elsif($date =~ /^(\d+)$/) { $Day = $date; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time()); $Year = $year + 1900; $Month = $mon+1; } else { $App->print(" Error: Invalid date [$date]\n"); } $starttime = $App->TimeStrToIntForSchedule($starttime); $endtime = $App->TimeStrToIntForSchedule($endtime); $App->print("$Year/$Month/$Day: [$starttime - $endtime]\n"); $App->DB()->InsertData($pParams->{ScheduleTableName}, "EMail", $pParams->{EMail}, "Apparatus", $pParams->{Apparatus}, "Year", $Year, "Month", $Month, "Day", $Day, "Starttime", $starttime, "Endtime", $endtime, "Comment", $description, "Secret", '', "UpdateDate", time(), "IPAddress", $pParams->{IPAddress}, ); } $App->HR(); $this->ShowAddSchedulesPage($App, $pParams); } sub ShowAddSchedulesPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); #$App->print("Add Schedule\n"); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); if(!$App->can('GetApparatusSelectionFormString')) { $App->H3("Error: This system does not have App::GetApparatusSelectionFormString.\n"); return; } # $pParams->{Apparatus1} = $pParams->{Apparatus} if($pParams->{Apparatus1} eq ''); # my $ApparatusSelectStr = $App->GetApparatusSelectionFormString($pParams, 'Apparatus1', $pParams->{Apparatus1}); my $ApparatusSelectStr = $App->GetApparatusSelectionFormString($pParams, 'Apparatus', $pParams->{Apparatus}); print <

Schedules:
format should be same as those copied from "Schedule" menu like:
Date Time Description sn
2009/1/12 *-* 成人の日 2264
2009/2/11 9:15-10:30 建国記念の日 2265
Date Time Description
1/12 9-12 成人の日
2/11 *-* 建国記念の日
2/11 9 建国記念の日
2/11 -9 建国記念の日
Date Description
1/12 成人の日
2/11 建国記念の日
$ApparatusSelectStr

EOT } sub OpenDB { my ($this, $App, $pParams, $DBMName, $DBServer, $DBUser, $DBPassword, $DBName, $IsPrint) = @_; my $DB = new SQLDB($DBMName); $DB->SetApplication($App); $DB->SetDBCharCode($App->SQLCharCode()); $DB->SetSourceCharCode($App->WebCharCode()); $DB->SetDebug($App->Debug()); $DB->Open($DBServer, $DBUser, $DBPassword, $DBName, undef, 0, 0); if(!defined $DB or !$DB->dbh()) { $App->H3("Error: Can not open [$DBServer/$DBName/$DBUser/*****][DB=$DB].\n") if($IsPrint); #$App->H3("Error: Can not open [$DBServer/$DBName/$DBUser/$DBPassword][DB=$DB].\n"); return undef; } return $DB; } sub ExecuteSimpleSQLPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $ShowPassword = $App->HasPrivilege($ShowPasswordPrivilege); #0; my $DB = $this->OpenDB($App, $pParams, $pParams->{TargetDBMName}, $pParams->{TargetDBServer}, $pParams->{TargetDBUser}, $pParams->{TargetDBPassword}, $pParams->{TargetDBName}, 1); return if(!$DB); $App->print("\n"); my $sql = ''; if($pParams->{ChangeTable}) { my @FieldName = sort {lcfirst $a cmp lcfirst $b} $DB->GetFields($pParams->{UserDBTableName}, $pParams->{UserDBTableName}, 0); $pParams->{TargetDBName2} = $pParams->{TargetDBName}; $pParams->{TargetTableName} = $pParams->{UserDBTableName}; $pParams->{TargetBaseFieldName} = $FieldName[@FieldName-1]; } elsif($pParams->{CreateUser}) { $sql = "grant all on $pParams->{TargetDBName2}.* to $pParams->{TargetDBUser}\@'%' identified by '$pParams->{TargetDBPassword}' with grant option;\n" ."flush privileges;\n"; } elsif($pParams->{AddTableField}) { $sql = "alter table $pParams->{TargetTableName} add $pParams->{TargetFieldName} $pParams->{TargetFieldAttribute} after $pParams->{TargetBaseFieldName};\n"; } elsif($pParams->{ChangeTableField}) { $sql = "alter table $pParams->{ChangeTargetTableName} change $pParams->{ChangeTargetFieldName} $pParams->{ChangeNewFieldName} $pParams->{ChangeNewFieldAttribute};\n"; } elsif($pParams->{DeleteTableField}) { $sql = "alter table $pParams->{DeleteTargetTableName} drop $pParams->{DeleteTargetFieldName};\n"; } elsif($pParams->{Search}) { $sql = "select * from $pParams->{SearchTableName} where $pParams->{SearchCondition};\n"; } if($sql) { $App->print("Execute [$sql]\n"); my ($sth, $ret) = $DB->Execute($sql, undef, 1); $App->print("ret: $ret\n"); return if(!defined $ret); my $nHit = $DB->nHit(); my $nrow = $DB->rows(); $App->print("$nHit [$nrow] found.\n"); my $c = 1; for(my $i = 0 ; $i < $nHit or $i < $nrow ; $i++) { if($sql =~ /select/i) { my %Hit = $DB->GetNextHit(); # last if(!defined $Hit{sn}); $App->HR(); $App->PrintRawHTML("Hit#$c
\n"); foreach my $key (sort keys %Hit) { next if($key eq 'Password' and !$ShowPassword); $App->PrintRawHTML("$key: $Hit{$key}
\n"); } } else { my @a = $DB->fetchrow_array(); last if(@a == 0); $App->HR(); $App->PrintRawHTML("Hit#$c
\n"); for(my $i = 0 ; $i < @a ; $i++) { $App->print("$a[$i]\n"); } } $App->print("\n"); $c++; } } $App->HR(); $this->ShowSimpleSQLPage($App, $pParams); } sub ShowSimpleSQLPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my $TextboxWidth = 30; my $TextboxWidth2 = 10; my $TextboxWidth3 = 60; my ($Option, $target) = $App->GetCGIParameters( { PrevAction => $pParams->{Action}, }, undef); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2('Simple SQL Manage'); $pParams->{TargetDBServer} = $pParams->{DBServer} if(!$pParams->{TargetDBServer}); $pParams->{TargetDBMName} = $pParams->{DBMName} if(!$pParams->{TargetDBMName}); $pParams->{TargetDBName} = $pParams->{DBName} if(!$pParams->{TargetDBName}); $pParams->{TargetDBUser} = $pParams->{DBUser} if(!$pParams->{TargetDBUser}); $pParams->{TargetDBPassword} = $App->{DBPassword} if(!$pParams->{TargetDBPassword}); $App->print("\n"); my $DB = $this->OpenDB($App, $pParams, $pParams->{TargetDBMName}, $pParams->{TargetDBServer}, $pParams->{TargetDBUser}, $pParams->{TargetDBPassword}, $pParams->{TargetDBName}, 1); if(!$DB) { # $App->H3("Error: Can not open [$DBServer/$DBName/$DBUser/*****][DB=$DB].\n") if($IsPrint); return; } my @TableName = sort {lcfirst $a cmp lcfirst $b} $DB->GetTables($App->{pParams}->{DBName}, 0); $pParams->{UserDBTableName} = $TableName[0] if(!defined $pParams->{UserDBTableName}); my $DBTableNameFormString = $pParams->{SearchTarget1String} = $App->BuildFormSelectString2("UserDBTableName", $pParams->{UserDBTableName}, "", "", \@TableName, \@TableName, $pParams->{WebCharCode}); my @FieldName = sort {lcfirst $a cmp lcfirst $b} $DB->GetFields($pParams->{UserDBTableName}, $pParams->{UserDBTableName}, 0); my $DBFieldNameFormString = $pParams->{SearchTarget1String} = $App->BuildFormSelectString2("UserFieldName", $pParams->{UserFieldName}, "", "", \@FieldName, \@FieldName, $pParams->{WebCharCode}); $pParams->{UserDBTableName} = $TableName[@TableName-1] if(!$pParams->{UserDBTableName}); $pParams->{TargetTableName} = $pParams->{UserDBTableName} if(!$pParams->{TargetTableName}); $pParams->{TargetFieldName} = '' if(!$pParams->{TargetFieldName}); $pParams->{TargetFieldAttribute} = 'varchar(255)' if(!$pParams->{TargetFieldAttribute}); $pParams->{TargetBaseFieldName} = $FieldName[@FieldName-1] if(!$pParams->{TargetBaseFieldName}); my ($Option, $target) = $App->GetCGIParameters( { Action => "${ModuleName}::ExecuteSimpleSQLPage", PrevAction => $pParams->{Action}, }, [qw(App Action EMail Password Code Language PrevAction DBConfigName ExtendedMenu ShowAll IsChildFrame Year Month Day)], undef, undef, 1, ); $App->BeginForm($pParams, $pParams->{ScriptPath}, "POST", $target, 0); $App->BeginTable(1); $App->TableRowByArray(['DB Manager', $App->Textbox("TargetDBMName", $TextboxWidth, $pParams->{TargetDBMName}, '', undef, IsPrint => 0), 'DB Server', $App->Textbox("TargetDBServer", $TextboxWidth, $pParams->{TargetDBServer}, '', undef, IsPrint => 0), 'DB Name', $App->Textbox("TargetDBName", $TextboxWidth, $pParams->{TargetDBName}, '', undef, IsPrint => 0)], undef, '{', '}', undef, 1); $App->TableRowByArray(['DB User', $App->Textbox("TargetDBUser", $TextboxWidth, $pParams->{TargetDBUser}, '', undef, IsPrint => 0), 'DB Password', $App->PasswordTextbox("TargetDBPassword", $TextboxWidth, $pParams->{TargetDBPassword}, '', undef, IsPrint => 0)], undef, '{', '}', undef, 1); $App->EndTable(); $App->PrintFormButton("ChangeTable", "Change Table"); $App->print(" "); $App->PrintRawHTML("Table: $DBTableNameFormString\n"); $App->print(" "); $App->PrintRawHTML("Fields: $DBFieldNameFormString
\n"); $App->PrintFormButton("CreateUser", "Create User"); $App->print("grant all on "); $App->Textbox("TargetDBName2", $TextboxWidth2, $pParams->{TargetDBName2}, '', undef, IsPrint => 1); $App->print(".* to "); $App->Textbox("TargetDBUser", $TextboxWidth2, $pParams->{TargetDBUser}, '', undef, IsPrint => 1); $App->print("@'%' identified by '"); $App->Textbox("TargetDBPassword", $TextboxWidth2, $pParams->{TargetDBPassword}, '', undef, IsPrint => 1); $App->print("' with grant option;\n"); $App->print(" flush privileges;\n"); $App->PrintFormButton("AddTableField", "Add Table Field"); $App->print("alter table "); $App->Textbox("TargetTableName", $TextboxWidth2, $pParams->{TargetTableName}, '', undef, IsPrint => 1); $App->print(" add "); $App->Textbox("TargetFieldName", $TextboxWidth2, $pParams->{TargetFieldName}, '', undef, IsPrint => 1); $App->print(" "); $App->Textbox("TargetFieldAttribute", $TextboxWidth2, $pParams->{TargetFieldAttribute}, '', undef, IsPrint => 1); $App->print(" after "); $App->Textbox("TargetBaseFieldName", $TextboxWidth2, $pParams->{TargetBaseFieldName}, '', undef, IsPrint => 1); $App->print(";\n"); $pParams->{ChangeTargetTableName} = $pParams->{UserDBTableName} if(!$pParams->{ChangeTargetTableName}); $pParams->{ChangeTargetFieldName} = $FieldName[@FieldName-1] if(!$pParams->{ChangeTargetFieldName}); $pParams->{ChangeNewFieldName} = $FieldName[@FieldName-1] if(!$pParams->{ChangeNewFieldName}); $pParams->{ChangeNewFieldAttribute} = 'varchar(255)' if(!$pParams->{ChangeNewFieldAttribute}); $App->PrintFormButton("ChangeTableField", "Change Table Field"); $App->print("alter table "); $App->Textbox("ChangeTargetTableName", $TextboxWidth2, $pParams->{ChangeTargetTableName}, '', undef, IsPrint => 1); $App->print(" change "); $App->Textbox("ChangeTargetFieldName", $TextboxWidth2, $pParams->{ChangeTargetFieldName}, '', undef, IsPrint => 1); $App->print(" "); $App->Textbox("ChangeNewFieldName", $TextboxWidth2, $pParams->{ChangeNewFieldName}, '', undef, IsPrint => 1); $App->print(" "); $App->Textbox("ChangeNewFieldAttribute", $TextboxWidth, $pParams->{ChangeNewFieldAttribute}, '', undef, IsPrint => 1); $App->print(";\n"); $pParams->{DeleteTargetTableName} = $pParams->{UserDBTableName} if(!$pParams->{DeleteTargetTableName}); $pParams->{DeleteTargetFieldName} = $FieldName[@FieldName-1] if(!$pParams->{DeleteTargetFieldName}); $App->PrintFormButton("DeleteTableField", "Delete Table Field"); $App->print("alter table "); $App->Textbox("DeleteTargetTableName", $TextboxWidth2, $pParams->{DeleteTargetTableName}, '', undef, IsPrint => 1); $App->print(" drop "); $App->Textbox("DeleteTargetFieldName", $TextboxWidth, $pParams->{DeleteTargetFieldName}, '', undef, IsPrint => 1); $App->print(";\n"); $pParams->{SearchTableName} = $pParams->{UserDBTableName} if(!$pParams->{SearchTableName}); $pParams->{SearchCondition} = "$FieldName[0] like '%'" if(!$pParams->{SearchCondition}); $App->PrintFormButton("Search", "Search"); $App->print("select * from "); $App->Textbox("SearchTableName", $TextboxWidth2, $pParams->{SearchTableName}, '', undef, IsPrint => 1); $App->print(" where "); $App->Textbox("SearchCondition", $TextboxWidth3, $pParams->{SearchCondition}, '', undef, IsPrint => 1); $App->print(";\n"); $App->PrintRawHTML(" $Option\n"); $App->EndForm(); } sub ShowDatabaseInfPage { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); $App->H2("Database structures"); my ($Option, $target) = $App->GetCGIParameters( { Action => $pParams->{Action}, PrevAction => $pParams->{Action}, ValidAbstractOnly => 'ON', }, [qw(App Action EMail Password Code Language PrevAction DBConfigName ExtendedMenu ShowAll IsChildFrame)], undef, undef, 1, ); $pParams->{Options} = $Option; my @TableName = sort {lcfirst $a cmp lcfirst $b} $App->{DB}->GetTables($App->{pParams}->{DBName}, 0); $pParams->{UserDBTableName} = $TableName[0] if(!defined $pParams->{UserDBTableName}); my $DBTableNameFormString = $pParams->{SearchTarget1String} = $App->BuildFormSelectString2( "UserDBTableName", $pParams->{UserDBTableName}, "", "", \@TableName, \@TableName, $pParams->{WebCharCode}); my @FieldName = sort {lcfirst $a cmp lcfirst $b} $App->{DB}->GetFields($pParams->{UserDBTableName}, $pParams->{UserDBTableName}, 0); my $DBFieldNameFormString = $pParams->{SearchTarget1String} = $App->BuildFormSelectString2( "UserFieldName", $pParams->{UserFieldName}, "", "", \@FieldName, \@FieldName, $pParams->{WebCharCode}); $App->BeginForm($pParams, $pParams->{ScriptPath}, "POST", $target, 0); $App->PrintFormButton("submit", "Show fields"); $App->print("\n"); $App->PrintRawHTML("Table: "); $App->PrintRawHTML($DBTableNameFormString . "
\n"); $App->PrintRawHTML("Fields: "); $App->PrintRawHTML($DBFieldNameFormString . "
\n"); $App->PrintRawHTML(" $Option\n"); $App->EndForm(); } sub ShowSQLPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $App->SendNotificationForPrivilegedAccessMail($App, $pParams); my ($Option, $target) = $App->GetCGIParameters( { PrevAction => $pParams->{Action}, }, undef); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Send SQL\n"); $this->ShowDatabaseInfPage($App, $pParams); my ($Option, $target) = $App->GetCGIParameters( { Action => "${ModuleName}::ExecuteSQL", PrevAction => $pParams->{Action}, }, [qw(App Action EMail Password Code Language PrevAction DBConfigName ExtendedMenu ShowAll IsChildFrame Year Month Day)], undef, undef, 1, ); $App->BeginForm($pParams, $pParams->{ScriptPath}, "POST", $target, 0); $App->PrintRawHTML("SQL: "); $App->PrintFormButton("submit", "send"); $App->print("\n"); $App->TextArea($pParams, 'SQLCode', $pParams->{SQLCode}, 5, 80); $App->PrintRawHTML(" $Option\n"); $App->EndForm(); } sub ShowMySQLTips { my ($this, $App, $pParams, $ShowMenu) = @_; $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); my $s = "

MySQLの使い方


★起動: mysql -h host_name -u user_name -p
★終了: mysql> exit
★rootへのパスワード設定: set password for root=PASSWORD('パスワード');
注意: flush privileges; が必要
★匿名ユーザーの削除:
mysql> use mysql;
mysql> delete from user where user='';
mysql> flush privileges;
★一般ユーザーの作成:
mysql> grant all on *.* to ユーザー名 identified by 'パスワード';
mysql> flush privileges;

★パスワードの設定:
mysql> set password for ユーザー名=PASSWORD('パスワード');
mysql> flush privileges;
注: ネットワーク越しのユーザー名は、'khlab'@'usrv615.khlab.lan'などと指定する
ワイルドカードを使う場合は、''でくくって % を使う: 例 khlab@'%.khlab.lan'
★権限設定
mysql> grant all on woe11_db.* to woe11_web identified by 'PASSWORD' with grant option;
★パスワード変更
mysql> set password = PASSWORD('パスワード');
mysql> set password for ユーザー名 = PASSWORD('パスワード');
注:ネットワーク越しのユーザー名は、'khlab'\@'usrv615.khlab.lan'などと指定する
★データベース作製
mysql> create database woe11_db;
   (ユーザ名にwoe11-webが使えなかった)
mysql> flush privileges;
★データベースを使う宣言
mysql> use データベース名;
★データの取得
mysql> select * from データベース名.テーブル名;
mysql> select * from データベース名.テーブル名 where EMail='tkamiya' order by sn DESC;
mysql> select * from データベース名.テーブル名 where EMail like '%tkamiya%' order by sn DESC;
★データの作製
mysql> insert テーブル名(フィールド名,フィールド名,,,) values(値,値,,,);
★データの更新
mysql> update テーブル名 set フィールド名=\"値\",フィールド名=\"値\" where ...;
★データの削除
mysql> delete from テーブル名 where ..;
★テーブルの作製
mysql> create table テーブル名(
       フィールド名 型 オプション,
       );
★フィールドの型
 CHAR(バイト数)
 VARCHAR(バイト数)
 TEXT (65,535bytes)
 MEDIUMTEXT (16,777,215bytes)
 LONGTXT (4,24,967,295bytes)
 INT
 DOUBLE
 TIME
 DATE
 DATETIME
例:create table a_tbl(
id int not null auto_increment,
name varchar(20) not null,
primary key(id)
);

★テーブル名変更
mysql> alter table テーブル名 rename 新テーブル名;
★テーブルのフィールド追加
mysql> alter table テーブル名 add フィールド名 フィールド定義 「FIRST|AFTER フィールド名];
mysql> alter table テーブル名 add BIKO VARCHAR(255);

★テーブルのフィールド削除
mysql> alter table テーブル名 drop フィールド名
★テーブルのフィールド定義の変更
mysql> alter table テーブル名 change 現フィールド名 新フィールド名 定義;
mysql> alter table テーブル名 change name name text not null;
★テーブルの削除
mysql> drop table テーブル名;
★バックアップ
mysqldump --opt データベース名 テーブル名 -u ユーザー名 -p > ダンプファイル名
mysqldump --opt --databases データベース名 -u ユーザー名 -p > ダンプファイル名
mysqldump --opt --all-databases -u ユーザー名 -p > ダンプファイル名
★リストア
mysql -u ユーザー名 -p データベース名 < ダンプファイル名
★情報の表示
★データベースの表示
mysql> show databases;
★テーブルの表示
mysql> show tables;
★サーバーステータス情報
mysql> show status;
★サーバー変数情報
mysql> show variables;
★プロセスの表示
mysql> show processlist;
★プロセスの強制終了
mysql> kill プロセス番号;

バージョンアップについて注意

Ver4.0=>4.1で、多言語の扱いとパスワードの長さが変わっているので、要注意
パスワードについて:
Ver4.1以降でも、my.cnfに"old-passwords"を指定することで、Ver4.0以前と同じ扱いができる
文字コードについて:
Ver4.1以降では、文字コードを自動変換してしまう。
それを避けるため、必ずmy.cnfでdefault-character-set=sjisを指定する。
"; Jcode::convert(\$s, $pParams->{WebCharCode}, $pParams->{PerlCharCode}); $App->PrintRawHTML($s); } sub ShowDBDataPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Database Data"); my $DB = $App->DB(); my @TableName = $App->{DB}->GetTables($App->{pParams}->{DBName}, 0); for(my $i = 0 ; $i < @TableName ; $i++) { $App->H3("$TableName[$i]\n"); $DB->Search($TableName[$i], "order by sn", ""); $App->PrintRawHTML("\n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); my $nHit = $DB->nHit(); for(my $i = 0 ; $i < $nHit ; $i++) { my %Hit = $DB->GetNextHit(); my $c = 0; foreach my $key (sort keys %Hit) { next if($key eq 'sn'); my $sn = ''; if($c == 0) { $sn = $Hit{sn}; $c++; } $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); } } $App->PrintRawHTML("
snKeyVal
$sn$key$Hit{$key}
\n"); $App->PrintRawHTML("\n"); $App->PrintRawHTML("\n"); $App->PrintRawHTML("{EMail}\">\n"); $App->PrintRawHTML("{Password}\">\n"); $App->PrintRawHTML("{Language}\">\n"); $App->PrintRawHTML("{DBConfigName}\">\n"); $App->PrintRawHTML("{ExtendedMenu}\">\n"); $App->PrintRawHTML("{ShowAll}\">\n"); $App->PrintRawHTML("{sn}\">\n"); $App->PrintRawHTML("\n"); } } sub ShowDatabaseEditForm { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Database Edit Forms"); my @TableName = $App->{DB}->GetTables($App->{pParams}->{DBName}, 0); for(my $i = 0 ; $i < @TableName ; $i++) { $App->PrintRawHTML("
{ScriptPath}\" target=\"$pParams->{WebTarget}\">\n"); $App->PrintRawHTML("\n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); my @FieldName = $App->{DB}->GetFields($TableName[$i], $TableName[$i], 0); my @FieldType = $App->{DB}->GetFieldTypes($TableName[$i], $TableName[$i], undef, 0); for(my $j = 0 ; $j < @FieldName ; $j++) { $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); if($FieldName[$j] =~ /^Password/i) { $App->PrintRawHTML(" \n"); } elsif($FieldType[$j] =~ /text/i) { $App->PrintRawHTML(" \n"); } else { $App->PrintRawHTML(" \n"); } $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); } $App->PrintRawHTML("
$TableName[$i]
$FieldName[$j]$FieldType[$j]
\n"); $App->PrintRawHTML("\n"); $App->PrintRawHTML("\n"); $App->PrintRawHTML("{EMail}\">\n"); $App->PrintRawHTML("{Password}\">\n"); $App->PrintRawHTML("{Language}\">\n"); $App->PrintRawHTML("{DBConfigName}\">\n"); $App->PrintRawHTML("{ExtendedMenu}\">\n"); $App->PrintRawHTML("{ShowAll}\">\n"); $App->PrintRawHTML("{sn}\">\n"); $App->PrintRawHTML("
\n"); } } sub DatabaseStructures { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Database structures"); my $DB = $App->DB(); my $pParams = $App->pParams(); my @TableName = $DB->GetTables($pParams->{DBName}, 0); for(my $i = 0 ; $i < @TableName ; $i++) { $App->PrintRawHTML("\n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); my @FieldName = $DB->GetFields($TableName[$i], $TableName[$i], 0); my @FieldType = $DB->GetFieldTypes($TableName[$i], $TableName[$i], undef, 0); for(my $j = 0 ; $j < @FieldName ; $j++) { # $this->print(" $FieldName[$j] $FieldType[$j]\n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); $App->PrintRawHTML(" \n"); } $App->PrintRawHTML("
$TableName[$i]
$FieldName[$j]$FieldType[$j]
\n"); } } sub DatabaseStructuresByDESC { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); # $App->SendNotificationForPrivilegedAccessMail($App, $pParams); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Database structures by Description command"); my $DB = $App->DB(); my $pParams = $App->pParams(); my @TableName = $DB->GetTables($pParams->{DBName}, 0); for(my $i = 0 ; $i < @TableName ; $i++) { $App->H3("$TableName[$i]\n"); my ($nHit, $pKeys, @lines) = $DB->DescribeTable($TableName[$i]); $App->BeginTable(1); $App->BeginTableHeader(); $App->BeginTableRow(); for(my $j = 0 ; $j < @$pKeys ; $j++) { $App->TableCell("$pKeys->[$j]"); } $App->EndTableRow(); $App->EndTableHeader(); $App->BeginTableBody(); for(my $k = 0 ; $k < @lines ; $k++) { $App->BeginTableRow(); my $pHit = $lines[$k]; for(my $j = 0 ; $j < @$pKeys ; $j++) { $App->TableCell($pHit->{$pKeys->[$j]}); } $App->EndTableRow(); } $App->EndTableBody(); $App->EndTable(); } } sub ShowSyncDBPage { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Operating DB Server"); $App->PrintRawHTML("   DBConfigName: $pParams->{DBConfigName}
\n"); $App->PrintRawHTML("   DBMName: $pParams->{DBMName}
\n"); my $HostName = hostname(); $pParams->{DBServer} = "$HostName (localhost)" if($pParams->{DBServer} =~ /^localhost$/i); $App->PrintRawHTML("   Server: $pParams->{DBServer}
\n"); $App->PrintRawHTML("   Database: $pParams->{DBName}
\n"); $App->PrintRawHTML("   Users Table $pParams->{UsersTableName}
\n"); $App->PrintRawHTML("   Schedule Table: $pParams->{ScheduleTableName}
\n"); $App->PrintRawHTML("   Message Table: $pParams->{MessageTableName}
\n"); if(!$pParams->{AllowLocalSync} and $pParams->{DBConfigName} =~ /-localhost$/i) { $App->H2("Sync does not work for the DB server working on the PC launching Schedule.pl."); return; } my ($lDBConfigName, $lDBMName, $lDBServer, $lDBUser, $lDBPassword, $lDBName, $lUsersTableName, $lScheduleTableName, $lMessageTableName); for(my $i = 0 ; ; $i++) { ($lDBConfigName, $lDBMName, $lDBServer, $lDBUser, $lDBPassword, $lDBName, $lUsersTableName, $lScheduleTableName, $lMessageTableName) = $App->GetDBConfig($i); last if(!$lDBConfigName); last if($lDBConfigName ne $pParams->{DBConfigName} and $lDBConfigName =~ /-localhost/i); } $App->H3("Local DB to be synchronized."); my $CSVDBDir = $App->CSVDBDir(); $App->PrintRawHTML("   DBConfigName: $lDBConfigName
\n"); $App->PrintRawHTML("   DBMName: $lDBMName
\n"); $App->PrintRawHTML("   Server: $lDBServer
\n"); $App->PrintRawHTML("   Database: $lDBName
\n"); $App->PrintRawHTML("   Users Table $lUsersTableName
\n"); $App->PrintRawHTML("   Schedule Table: $lScheduleTableName
\n"); $App->PrintRawHTML("   Message Table: $lMessageTableName
\n"); if($lDBMName =~ /^csv$/i) { $App->PrintRawHTML("   Local CSV Dir: $CSVDBDir
\n"); } print < EOT } sub Sync { my ($this, $App, $pParams) = @_; return if(!$this->IsOpen($App, $pParams)); my $DB = $App->DB(); my $lconf = $pParams->{LocalDBConfigName}; my ($lDBConfigName, $lDBMName, $lDBServer, $lDBUser, $lDBPassword, $lDBName, $lUsersTableName, $lScheduleTableName, $lMessageTableName) = $App->FindDBConfig($lconf); #$App->print("Make outDB\n"); #DBの作成 my $outDB = new SQLDB($lDBMName); my $ret = $outDB->IsExistDatabase($lDBName); if($ret < 0) { $App->print("Query for [$lDBMName:$lDBName] failed."); return; } elsif(!$ret) { if($outDB->CreateDatabase($lDBName)) { $App->print("[$lDBName] is created.\n"); } else { $App->print("DB dir [$lDBName] could not be created."); return; } } #$App->print("Make Table\n"); #Tableの作成 $outDB->Open($lDBServer, $lDBUser, $lDBPassword, $lDBName, "sjis", 0, 1); if(!$outDB->dbh()) { $App->H2("Error:OutDB: Can not open [$lDBName].\n"); exit; } #$App->print("[$lDBName] is opened.\n"); foreach my $tbl ($lUsersTableName, $lScheduleTableName, $lMessageTableName) { $App->print("Local Table: $lDBName.$tbl\n"); next if($outDB->IsExistTable($lDBName, $tbl)); $App->print(" Table: $tbl not exist\n"); my $RemoteTable = $tbl; $RemoteTable =~ s/\.csv//; $App->H3("Create [$lDBName/$tbl]"); my @pDefs = $DB->GetTableDefinition($pParams->{DBName}, $RemoteTable); my ($sth, $ret) = $outDB->CreateTable($tbl, \@pDefs); if($sth) { $App->print("Local table [$lDBName/$tbl] is created from [$pParams->{DBName}:$RemoteTable].\n"); } else { $App->H2("Can not create table [$lDBName/$tbl] from [$pParams->{DBName}:$RemoteTable]."); next; } } $outDB->Close(); $App->print("Sync\n"); #同期 my $outDB = new SQLDB($lDBMName); $outDB->Open($lDBServer, $lDBUser, $lDBPassword, $lDBName, "sjis", 0, 1); if(!$outDB->dbh()) { $App->H2("Error:OutDB: Can not open [$lDBName].\n"); exit; } #$App->print("SynchronizeDBs($DB, $outDB, $pParams->{UsersTableName}, $pParams->{ScheduleTableName}," # ."$pParams->{MessageTableName}, $App->{LogonUserPrivilege}\n"); #$App->print("SynchronizeDBs($outDB, $DB, $pParams->{UsersTableName}, $pParams->{ScheduleTableName}," # ."$pParams->{MessageTableName}\n"); $this->SynchronizeDBs($App, $pParams, $DB, $outDB, $pParams->{UsersTableName}, $pParams->{ScheduleTableName}, $pParams->{MessageTableName}, $App->{LogonUserPrivilege}); $this->SynchronizeDBs($App, $pParams, $outDB, $DB, $pParams->{UsersTableName}, $pParams->{ScheduleTableName}, $pParams->{MessageTableName}); $outDB->Close(); } sub SynchronizeDBs { my ($this, $App, $pParams, $SourceDB, $TargetDB, $UsersTableName, $ScheduleTableName, $MessageTableName) = @_; my $priv = $pParams->{LogonUserPrivilege}; $priv = ",$priv,"; my $SourceDBMName = $SourceDB->DBMName(); my $SourceDBName = $SourceDB->DBName(); my $TargetDBMName = $TargetDB->DBMName(); my $TargetDBName = $TargetDB->DBName(); $App->H2("Synchronize from [$SourceDBMName:$SourceDBName] to [$TargetDBMName:$TargetDBName].\n"); foreach my $tbl ($UsersTableName, $ScheduleTableName, $MessageTableName) { my $SourceTable = $tbl; my $TargetTable = $tbl; if($SourceDBMName =~ /csv/i) { $SourceTable = "${SourceTable}.csv"; } if($TargetDBMName =~ /csv/i) { $TargetTable = "${TargetTable}.csv"; } $App->H3("From [$SourceDBName/$SourceTable] to [$TargetDBName/$TargetTable]"); my $ret; if($tbl !~ /users/i and $priv =~ /,SyncAll,/i) { $ret = $SourceDB->Search($SourceTable, "order by sn", ""); } else { $ret = $SourceDB->Search($SourceTable, "(EMail='$pParams->{EMail}') order by sn", ""); } my $n = $SourceDB->nHit(); for(my $i = 0 ; $i < $n ; $i++) { my %SourceHit = $SourceDB->GetNextHit(); $App->print("i=$i: $SourceHit{sn} $SourceHit{EMail}
\n") if($i % 100 == 0); my $ret = $TargetDB->Search($TargetTable, "sn='$SourceHit{sn}'", ""); my %TargetHit = $TargetDB->GetNextHit(); if(!$TargetHit{UpdateDate} or $TargetHit{UpdateDate} < $SourceHit{UpdateDate}) { if($TargetHit{sn}) { $ret = $TargetDB->UpdateData($TargetTable, "sn='$SourceHit{sn}'", %SourceHit); } else { $ret = $TargetDB->InsertData($TargetTable, %SourceHit); } if($ret) { } else { $App->print("Data [sn:$SourceHit{sn}] could not been added.\n"); } } } } $App->H2("Synchronization finished."); } sub CorrectCharCode { my ($this, $App, $pParams, $ShowMenu) = @_; return if(!$this->IsOpen($App, $pParams)); $this->ShowPage($App, $pParams, $ShowMenu); $App->HR(); $App->H2("Correct char code\n"); $App->print("Normalize DB character code to [$pParams->{SQLCharCode}]\n"); my ($DB2) = $App->OpenDB($pParams->{DBConfigName}); my $DB = $App->DB(); foreach my $TableName ($pParams->{ScheduleTableName}, $pParams->{MessageTableName}) { $App->H3("For $TableName"); $DB->Search($TableName, "order by sn", ""); for(my $i = 0 ; ; $i++) { my %Hit = $DB->GetNextHit(); last if(!defined $Hit{sn}); my $code1 = Jcode::getcode($Hit{Comment}); my $code2 = Jcode::getcode($Hit{Secret}); if($code1 ne $pParams->{SQLCharCode} or $code2 ne $pParams->{SQLCharCode}) { my $s1 = $Hit{Comment}; Jcode::convert(\$s1, $pParams->{SQLCharCode}); Utils::DelSpace($s1); my $s2 = $Hit{Secret}; Jcode::convert(\$s2, $pParams->{SQLCharCode}); Utils::DelSpace($s2); if($s1 ne $Hit{Comment} or $s2 ne $Hit{Secret}) { $App->print("$i: $code1 [$s1] $code2 [$s2]\n"); $DB2->UpdateData($TableName, "sn='$Hit{sn}'", "Comment", $s1, "Secret", $s2, ); } } } } } 1;