Changeset 21426


Ignore:
Timestamp:
2012/01/31 09:45:59 (12 years ago)
Author:
Seasoft
Message:

#1621 (バックアップの大規模店舗対応)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_12-dev/data/class/pages/admin/system/LC_Page_Admin_System_Bkup.php

    r21420 r21426  
    100100 
    101101                // バックアップファイル作成 
    102                 $arrErrTmp[3] = $this->lfCreateBkupData($arrData['bkup_name'], $this->bkup_dir); 
     102                $work_dir = $this->bkup_dir . $arrData['bkup_name'] . "/"; 
     103                $res = $this->lfCreateBkupData($arrData['bkup_name'], $work_dir); 
     104                // バックアップデータの削除 
     105//                SC_Utils_Ex::sfDelFile($work_dir); 
     106 
     107                $arrErrTmp[3] = array(); 
     108                if ($res !== true) { 
     109                    $arrErrTmp[3]['bkup_name'] = 'バックアップに失敗しました。(' . $res . ')'; 
     110                } 
    103111 
    104112                // DBにデータ更新 
     
    255263     * バックアップファイル作成. 
    256264     * 
    257      * TODO $csv_data はデータを大きく保持しすぎに感じる。分割して書き込みたい。 
    258265     * @param string $bkup_name 
    259      * @return array $arrErr 
    260      */ 
    261     function lfCreateBkupData($bkup_name, $bkup_dir){ 
     266     * @return boolean|int 結果。true:成功 int:失敗 FIXME 本来は int ではなく、エラーメッセージを戻すべき 
     267     */ 
     268    function lfCreateBkupData($bkup_name, $work_dir){ 
    262269        // 実行時間を制限しない 
    263270        set_time_limit(0); 
    264271 
    265272        $objQuery =& SC_Query_Ex::getSingletonInstance(); 
    266         $csv_data = ''; 
    267273        $csv_autoinc = ""; 
    268274        $arrData = array(); 
    269         $success = true; 
    270  
    271         if (!is_dir(dirname($bkup_dir))) $success = mkdir(dirname($bkup_dir)); 
    272         $bkup_dir = $bkup_dir . $bkup_name . "/"; 
     275 
     276        $success = mkdir($work_dir, 0777, true); 
     277        if (!$success) { 
     278            return __LINE__; 
     279        } 
    273280 
    274281        // 全テーブル取得 
     
    278285        foreach ($arrTableList as $table) { 
    279286 
    280             if (!($table == "dtb_bkup" || $table == "mtb_zip")) { 
    281  
    282                 // 全データを取得 
    283                 if ($table == "dtb_pagelayout"){ 
    284                     $arrData = $objQuery->getAll("SELECT * FROM $table ORDER BY page_id"); 
    285                 }else{ 
    286                     $arrData = $objQuery->getAll("SELECT * FROM $table"); 
    287                 } 
    288  
    289                 // CSVデータ生成 
    290                 if (count($arrData) > 0) { 
    291  
    292                     // テーブル名 
    293                     $csv_data .= $table . "\r\n"; 
    294  
    295                     // カラム名 
    296                     $csv_data .= SC_Helper_CSV_Ex::sfArrayToCsv(array_keys($arrData[0])) . "\r\n"; 
    297  
    298                     // データ 
    299                     foreach ($arrData as $data_val) { 
    300                         $csv_data .= SC_Helper_CSV_Ex::sfArrayToCsv($data_val) . "\r\n"; 
    301                     } 
    302  
    303                     // テーブル終端 
    304                     $csv_data .= "\r\n"; 
    305                 } 
    306  
    307                 // タイムアウトを防ぐ 
    308                 SC_Utils_Ex::sfFlush(); 
    309             } 
     287            if ($table == 'dtb_bkup' || $table == 'mtb_zip') { 
     288                continue; 
     289            } 
     290 
     291            // dataをCSV出力 
     292            $csv_file = $work_dir . $table . '.csv'; 
     293            $fp = fopen($csv_file, 'w'); 
     294            if (!$fp) { 
     295                return __LINE__; 
     296            } 
     297 
     298            // 全データを取得 
     299            $sql = "SELECT * FROM $table"; 
     300 
     301            $this->fpOutput =& $fp; 
     302            $this->first_line = true; 
     303            $success = $objQuery->doCallbackAll(array(&$this, 'cbOutputCSV'), $sql); 
     304            unset($this->fpOutput); 
     305 
     306            if ($success === false) { 
     307                return __LINE__; 
     308            } 
     309 
     310            fclose($fp); 
     311 
     312            // タイムアウトを防ぐ 
     313            SC_Utils_Ex::sfFlush(); 
    310314        } 
    311315 
     
    313317        $csv_autoinc = $this->lfGetAutoIncrement(); 
    314318 
    315         $csv_file = $bkup_dir . "bkup_data.csv"; 
    316         $csv_autoinc_file = $bkup_dir . "autoinc_data.csv"; 
    317         mb_internal_encoding(CHAR_CODE); 
     319        $csv_autoinc_file = $work_dir . "autoinc_data.csv"; 
     320 
    318321        // CSV出力 
    319         // ディレクトリが存在していなければ作成する 
    320         if (!is_dir(dirname($csv_file))) { 
    321             $success = mkdir(dirname($csv_file)); 
    322         } 
    323         if ($success) { 
    324             // dataをCSV出力 
    325             $fp = fopen($csv_file,'w'); 
    326             if($fp) { 
    327                 if($csv_data != ""){ 
    328                     $success = fwrite($fp, $csv_data); 
     322 
     323        // 自動採番をCSV出力 
     324        $fp = fopen($csv_autoinc_file,'w'); 
     325        if($fp) { 
     326            if($csv_autoinc != ""){ 
     327                $success = fwrite($fp, $csv_autoinc); 
     328                if (!$success) { 
     329                    return __LINE__; 
    329330                } 
    330                 fclose($fp); 
    331             } 
    332  
    333             // 自動採番をCSV出力 
    334             $fp = fopen($csv_autoinc_file,'w'); 
    335             if($fp) { 
    336                 if($csv_autoinc != ""){ 
    337                     $success = fwrite($fp, $csv_autoinc); 
    338                 } 
    339                 fclose($fp); 
    340             } 
    341         } 
    342  
    343         if ($success) { 
    344             //圧縮フラグTRUEはgzip圧縮をおこなう 
    345             $tar = new Archive_Tar($this->bkup_dir . $bkup_name . $this->bkup_ext, TRUE); 
    346  
    347             //bkupフォルダに移動する 
    348             chdir($this->bkup_dir); 
    349  
    350             //圧縮をおこなう 
    351             $zip = $tar->create("./" . $bkup_name . "/"); 
    352  
    353             // バックアップデータの削除 
    354             if ($zip) SC_Utils_Ex::sfDelFile($bkup_dir); 
    355         } 
    356  
    357         if (!$success) { 
    358             $arrErr['bkup_name'] = "バックアップに失敗しました。"; 
    359             // バックアップデータの削除 
    360             SC_Utils_Ex::sfDelFile($bkup_dir); 
    361         } 
    362  
    363         return isset($arrErr) ? $arrErr : array(); 
     331            } 
     332            fclose($fp); 
     333        } 
     334 
     335        //圧縮フラグTRUEはgzip圧縮をおこなう 
     336        $tar = new Archive_Tar($this->bkup_dir . $bkup_name . $this->bkup_ext, TRUE); 
     337 
     338        //bkupフォルダに移動する 
     339        chdir($work_dir); 
     340 
     341        //圧縮をおこなう 
     342        $zip = $tar->create('./'); 
     343 
     344        return true; 
     345    } 
     346 
     347    /** 
     348     * CSV作成 テンポラリファイル出力 コールバック関数 
     349     * 
     350     * @param mixed $data 出力データ 
     351     * @return boolean true (true:固定 false:中断) 
     352     */ 
     353    function cbOutputCSV($data) { 
     354        $line = ''; 
     355        if ($this->first_line) { 
     356            // カラム名 
     357            $line .= SC_Helper_CSV_Ex::sfArrayToCsv(array_keys($data)) . "\n"; 
     358            $this->first_line = false; 
     359        } 
     360        $line .= SC_Helper_CSV_Ex::sfArrayToCsv($data); 
     361        $line .= "\n"; 
     362        return fwrite($this->fpOutput, $line); 
    364363    } 
    365364 
     
    427426        $success = true; 
    428427 
     428        $work_dir = $bkup_dir . $bkup_name . '/'; 
     429 
    429430        //圧縮フラグTRUEはgzip解凍をおこなう 
    430         $tar = new Archive_Tar($bkup_dir . $bkup_name . $bkup_ext, TRUE); 
     431//        $tar = new Archive_Tar($work_dir . $bkup_name . $bkup_ext, TRUE); 
    431432 
    432433        //指定されたフォルダ内に解凍する 
    433         $success = $tar->extract($bkup_dir); 
     434//        $success = $tar->extract($work_dir . $bkup_name); 
    434435 
    435436        // 無事解凍できれば、リストアを行う 
     
    443444 
    444445            // INSERT実行 
    445             if ($success) $success = $this->lfExeInsertSQL($objQuery, $bkup_dir . $bkup_name . "/bkup_data.csv", $mode); 
     446            if ($success) $success = $this->lfExeInsertSQL($objQuery, $work_dir, $mode); 
    446447 
    447448            // 自動採番の値をセット 
    448             if ($success) $this->lfSetAutoInc($objQuery, $bkup_dir . "autoinc_data.csv"); 
     449            if ($success) $this->lfSetAutoInc($objQuery, $work_dir . 'autoinc_data.csv'); 
    449450 
    450451            // リストア成功ならコミット失敗ならロールバック 
     
    461462        } 
    462463 
     464        // FIXME この辺りで、バックアップ時と同等の一時ファイルの削除を実行すべきでは? 
    463465    } 
    464466 
     
    467469     * 
    468470     * @param object $objQuery 
    469      * @param string $csv 
     471     * @param string $dir 
    470472     * @param string $mode 
    471473     * @return void 
    472474     */ 
    473     function lfExeInsertSQL(&$objQuery, $csv, $mode){ 
     475    function lfExeInsertSQL(&$objQuery, $dir, $mode){ 
    474476 
    475477        $tbl_flg = false; 
     
    477479        $ret = true; 
    478480        $pagelayout_flg = false; 
    479         $table_name = ""; 
    480481        $arrVal = array(); 
    481482        $arrCol = array(); 
    482  
    483         // csvファイルからデータの取得 
    484         $fp = fopen($csv, 'r'); 
    485         if($fp === false) { 
    486             SC_Utils_Ex::sfDispException($csv . ' のファイルオープンに失敗しました。'); 
    487         } 
    488  
    489         while (!feof($fp)) { 
    490             $data = fgetcsv($fp, 1000000); 
    491  
    492             //空白行のときはテーブル変更 
    493             if (count($data) <= 1 and $data[0] == "") { 
    494                 $tbl_flg = false; 
    495                 $col_flg = false; 
    496                 $table_name = ""; 
    497                 $arrVal = array(); 
    498                 $arrCol = array(); 
    499  
     483        $arrAllTableList = $objQuery->listTables(); 
     484 
     485        $objDir = dir($dir); 
     486        while (false !== ($file_name = $objDir->read())) { 
     487            if (!preg_match('/^((dtb|mtb)_(\w+))\.csv$/', $file_name, $matches)) { 
    500488                continue; 
    501489            } 
    502  
    503             // テーブルフラグがたっていない場合にはテーブル名セット 
    504             if (!$tbl_flg) { 
    505                 $table_name = $data[0]; 
    506                 $tbl_flg = true; 
    507  
    508                 if($table_name == "dtb_pagelayout"){ 
    509                     $pagelayout_flg = true; 
     490            var_dump($matches); 
     491            $file_path = $dir . $file_name; 
     492            $table = $matches[1]; 
     493 
     494            // テーブル存在チェック 
     495            if (!in_array($table, $arrAllTableList)) { 
     496                if ($mode === 'restore_config') { 
     497                    continue; 
    510498                } 
    511  
    512                 continue; 
    513             } 
    514  
    515             // カラムフラグがたっていない場合にはカラムセット 
    516             if (!$col_flg) { 
    517                 if ($mode != "restore_config"){ 
    518                     for($i = 0; $i < count($data); $i++){ 
    519                         $arrCol[$i] = $data[$i]; 
    520                     } 
     499                return false; 
     500            } 
     501 
     502            // csvファイルからデータの取得 
     503            $fp = fopen($file_path, 'r'); 
     504            if($fp === false) { 
     505                SC_Utils_Ex::sfDispException($file_name . ' のファイルオープンに失敗しました。'); 
     506            } 
     507 
     508            $line = 0; 
     509            while (!feof($fp)) { 
     510                $line++; 
     511                $arrCsvLine = fgetcsv($fp, 1000000); 
     512 
     513                // 1行目: 列名 
     514                if ($line === 1) { 
     515                    $arrColName = $arrCsvLine; 
     516                    continue; 
    521517                } 
    522                 $col_flg = true; 
    523                 continue; 
    524             } 
    525  
    526             for($i = 0; $i < count($data); $i++) { 
    527                 if($arrCol[$i] != '') { 
    528                     $arrVal[$arrCol[$i]] = $data[$i]; 
    529                 } 
    530             } 
    531  
    532             $err = $objQuery->insert($table_name, $arrVal); 
    533  
    534             // エラーがあれば終了 
    535             if (PEAR::isError($err)){ 
    536                 SC_Utils_Ex::sfErrorHeader(">> " . $objQuery->getlastquery(false)); 
    537                 return false; 
    538             } 
    539  
    540             if ($pagelayout_flg) { 
    541                 // dtb_pagelayoutの場合には最初のデータはpage_id = 0にする 
    542                 $arrVal['page_id'] = '0'; 
    543                 $objQuery->update("dtb_pagelayout", $arrVal); 
    544                 $pagelayout_flg = false; 
    545             } 
    546  
    547             // タイムアウトを防ぐ 
    548             SC_Utils_Ex::sfFlush(); 
    549         } 
    550         fclose($fp); 
     518 
     519                $arrVal = array_combine($arrColName, $arrCsvLine); 
     520                $objQuery->insert($table, $arrVal); 
     521 
     522                SC_Utils_Ex::extendTimeOut();  
     523            } 
     524 
     525            fclose($fp); 
     526        } 
    551527 
    552528        return $ret; 
     
    573549        foreach($arrTableList as $val){ 
    574550            // バックアップテーブルは削除しない 
     551            // XXX mtb_zip も削除不要では? 
    575552            if ($val != "dtb_bkup") { 
    576553                $ret = $objQuery->delete($val); 
Note: See TracChangeset for help on using the changeset viewer.