Changeset 21730


Ignore:
Timestamp:
2012/04/10 13:14:02 (9 years ago)
Author:
Seasoft
Message:

#1716 (Postgres Plus Advanced Server 9.1 対応)

  • シーケンス

#1720 (バックアップ管理 同一シーケンス値を再発行させる不具合)
#1739 (PostgreSQL で SC_Query#setVal した直後 SC_Query#currVal == SC_Query#nextVal となる)

  • 根本的な解決ではない。

#1743 (バックアップファイルのみでのリストアに対応)
#1613 (typo修正・ソース整形・ソースコメントの改善)

Location:
branches/version-2_12-dev/data
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_12-dev/data/Smarty/templates/admin/system/bkup.tpl

    r21541 r21730  
    8787                    <td ><!--{$arrBkupList[cnt].bkup_memo}--></td> 
    8888                    <td align="center"><!--{$arrBkupList[cnt].create_date|sfCutString:19:true:false}--></td> 
    89                     <td align="center"><a href="#" onclick="fnRestore('<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">リストア</a></td> 
    90                     <td align="center"><a href="#" onclick="fnModeSubmit('download','list_name','<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">ダウンロード</a></td> 
     89                    <td align="center"><a href="javascript:;" onclick="fnRestore('<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">リストア</a></td> 
     90                    <td align="center"><a href="javascript:;" onclick="fnModeSubmit('download','list_name','<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">ダウンロード</a></td> 
    9191                    <td align="center"> 
    92                         <a href="#" onclick="fnModeSubmit('delete','list_name','<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">削除</a> 
     92                        <a href="javascript:;" onclick="fnModeSubmit('delete','list_name','<!--{$arrBkupList[cnt].bkup_name}-->'); return false;">削除</a> 
    9393                    </td> 
    9494                </tr> 
     
    9797    <!--{/if}--> 
    9898 
    99     <!--{if $restore_msg != ""}--> 
     99    <!--{if strlen($tpl_restore_msg) >= 1}--> 
    100100        <h2>実行結果</h2> 
    101101        <div class="message"> 
    102             <!--{if $restore_err == false}--> 
    103                 <div class="btn"><a class="btn-normal" href="javascript:;" name="restore_config" onClick="document.body.style.cursor = 'wait'; form1.mode.value='restore_config'; form1.list_name.value='<!--{$restore_name}-->'; submit(); return false;"><span>テーブル構成を無視してリストアする</span></a></div> 
     102            <!--{if $tpl_restore_err == false}--> 
     103                <div class="btn"><a class="btn-normal" href="javascript:;" name="restore_config" onClick="document.body.style.cursor = 'wait'; form1.mode.value='restore_config'; form1.list_name.value='<!--{$tpl_restore_name|h}-->'; submit(); return false;"><span>エラーを無視してリストアする</span></a></div> 
    104104            <!--{/if}--> 
    105             <!--{$restore_msg}--> 
     105            <!--{$tpl_restore_msg|h}--> 
    106106        </div> 
    107107    <!--{/if}--> 
  • branches/version-2_12-dev/data/class/pages/admin/system/LC_Page_Admin_System_Bkup.php

    r21693 r21730  
    3434class LC_Page_Admin_System_Bkup extends LC_Page_Admin_Ex { 
    3535 
     36    /** リストア中にエラーが発生したか */ 
     37    var $tpl_restore_err = false; 
     38 
     39    /** 対象外とするシーケンス生成器 */ 
     40    var $arrExcludeSequence = array( 
     41        'plsql_profiler_runid', // Postgres Plus Advanced Server 9.1 
     42        'snapshot_num',         // Postgres Plus Advanced Server 9.1 
     43    ); 
     44 
    3645    // }}} 
    3746    // {{{ functions 
     
    8291        $arrForm = array(); 
    8392 
    84         switch ($this->getMode()) { 
     93        $this->mode = $this->getMode(); 
     94        switch ($this->mode) { 
    8595 
    8696            // バックアップを作成する 
     
    93103                if (SC_Utils_Ex::isBlank($arrErrTmp[1])) { 
    94104                    // データ型以外のエラーチェック 
    95                     $arrErrTmp[2] = $this->lfCheckError($objFormParam->getHashArray(), $this->getMode()); 
     105                    $arrErrTmp[2] = $this->lfCheckError($objFormParam->getHashArray(), $this->mode); 
    96106                } 
    97107 
     
    131141            // リストア 
    132142            case 'restore_config': 
    133                 $this->mode = 'restore_config'; 
    134  
    135143            case 'restore': 
    136144                // データベースに存在するかどうかチェック 
    137                 $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->getMode()); 
     145                $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->mode); 
    138146 
    139147                // エラーがなければリストア処理を行う 
    140148                if (SC_Utils_Ex::isBlank($arrErr)) { 
    141149                    $arrData = $objFormParam->getHashArray(); 
    142                     $this->lfRestore($arrData['list_name'], $this->bkup_dir, $this->bkup_ext, $this->mode); 
     150 
     151                    $msg = '「' . $arrData['list_name'] . '」のリストアを開始します。'; 
     152                    GC_Utils_Ex::gfPrintLog($msg); 
     153 
     154                    $success = $this->lfRestore($arrData['list_name'], $this->bkup_dir, $this->bkup_ext, $this->mode); 
     155 
     156                    $msg = '「' . $arrData['list_name'] . '」の'; 
     157                    $msg .= $success ? 'リストアを終了しました。' : 'リストアに失敗しました。'; 
     158 
     159                    $this->tpl_restore_msg .= $msg . "\n"; 
     160                    GC_Utils_Ex::gfPrintLog($msg); 
    143161                } 
    144162                break; 
     
    148166 
    149167                // データベースに存在するかどうかチェック 
    150                 $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->getMode()); 
     168                $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->mode); 
    151169 
    152170                // エラーがなければリストア処理を行う 
     
    165183 
    166184                // データベースに存在するかどうかチェック 
    167                 $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->getMode()); 
     185                $arrErr = $this->lfCheckError($objFormParam->getHashArray(), $this->mode); 
    168186 
    169187                // エラーがなければダウンロード処理を行う 
     
    238256    function lfCheckError(&$arrForm, $mode) { 
    239257 
    240         $arrVal = array(); 
    241  
    242258        switch ($mode) { 
    243259            case 'bkup': 
    244                 $arrVal[] = $arrForm['bkup_name']; 
     260                $name = $arrForm['bkup_name']; 
    245261                break; 
    246262 
     
    249265            case 'download': 
    250266            case 'delete': 
    251                 $arrVal[] = $arrForm['list_name']; 
     267                $name = $arrForm['list_name']; 
    252268                break; 
    253269 
    254270            default: 
     271                trigger_error('不明な処理', E_USER_ERROR); 
    255272                break; 
    256273        } 
    257274 
    258275        // 重複・存在チェック 
    259         $ret = $this->lfGetBkupData('WHERE bkup_name = ?', $arrVal); 
     276        $ret = $this->lfGetBkupData('', $name); 
    260277        if (count($ret) > 0 && $mode == 'bkup') { 
    261278            $arrErr['bkup_name'] = 'バックアップ名が重複しています。別名を入力してください。'; 
     
    382399        $arrSequences = $objQuery->listSequences(); 
    383400 
    384         foreach ($arrSequences as $val) { 
    385             $seq = $objQuery->currVal($val); 
    386  
    387             $ret .= $val . ','; 
     401        foreach ($arrSequences as $name) { 
     402            if (in_array($name, $this->arrExcludeSequence, true)) { 
     403                continue 1; 
     404            } 
     405 
     406            // XXX SC_Query::currVal は、PostgreSQL で nextval と等しい値を戻すケースがある。欠番を生じうるが、さして問題無いと推測している。 
     407            $seq = $objQuery->currVal($name); 
     408 
     409            // TODO CSV 生成の共通処理を使う 
     410            $ret .= $name . ','; 
    388411            $ret .= is_null($seq) ? '0' : $seq; 
    389412            $ret .= "\r\n"; 
     
    404427    } 
    405428 
    406     // バックアップテーブルからデータを取得する 
    407     function lfGetBkupData($where = '', $data = array()) { 
     429    /** 
     430     * バックアップの一覧を取得する 
     431     */ 
     432    function lfGetBkupData($sql_option = '', $filter_bkup_name) { 
    408433        $objQuery =& SC_Query_Ex::getSingletonInstance(); 
    409434 
    410         $sql = 'SELECT bkup_name, bkup_memo, create_date FROM dtb_bkup '; 
    411         if ($where != '') { 
    412             $sql .= $where; 
    413         } 
    414  
    415         $ret = $objQuery->getAll($sql,$data); 
     435        // テーブルから取得 
     436        $arrVal = array(); 
     437 
     438        $sql = 'SELECT bkup_name, bkup_memo, create_date FROM dtb_bkup'; 
     439        if (strlen($filter_bkup_name) >= 1) { 
     440            $sql .= ' WHERE bkup_name = ?'; 
     441            $arrVal[] = $filter_bkup_name; 
     442        } 
     443        if ($sql_option != '') { 
     444            $sql .= ' ' . $sql_option; 
     445        } 
     446 
     447        $ret = $objQuery->getAll($sql, $arrVal); 
     448 
     449        // ファイルのみのものを取得 
     450        $glob = glob($this->bkup_dir . '*' . $this->bkup_ext); 
     451        if (is_array($glob)) { 
     452            foreach ($glob as $path) { 
     453                $bkup_name = basename($path, $this->bkup_ext); 
     454                if (strlen($filter_bkup_name) >= 1 && $bkup_name !== $filter_bkup_name) { 
     455                    continue 1; 
     456                } 
     457                unset($row); 
     458                foreach (array_keys($ret) as $key) { 
     459                    if ($ret[$key]['bkup_name'] == $bkup_name) { 
     460                        $row =& $ret[$key]; 
     461                    } 
     462                } 
     463                if (!isset($row)) { 
     464                    $ret[] = array(); 
     465                    $row =& $ret[array_pop(array_keys($ret))]; 
     466                    $row['bkup_name'] = $bkup_name; 
     467                    $row['bkup_memo'] = '(記録なし。バックアップファイルのみ。)'; 
     468                    $row['create_date'] = date("Y-m-d H:i:s", filemtime($path)); 
     469                } 
     470            } 
     471        } 
    416472 
    417473        return $ret; 
     
    455511        $success = $this->lfExeInsertSQL($objQuery, $work_dir, $mode); 
    456512 
    457         // 自動採番の値をセット 
    458         if ($success) $this->lfSetAutoInc($objQuery, $work_dir . 'autoinc_data.csv'); 
     513        // シーケンス生成器を復元する 
     514        if ($success) $this->restoreSequence($objQuery, $work_dir . 'autoinc_data.csv'); 
    459515 
    460516        // リストア成功ならコミット失敗ならロールバック 
    461517        if ($success) { 
    462518            $objQuery->commit(); 
    463             $this->restore_msg = 'リストア終了しました。'; 
    464             $this->restore_err = true; 
     519            $this->tpl_restore_err = true; 
    465520        } else { 
    466521            $objQuery->rollback(); 
    467             $this->restore_msg = 'リストアに失敗しました。'; 
    468             $this->restore_name = $bkup_name; 
    469             $this->restore_err = false; 
    470         } 
    471         GC_Utils_Ex::gfPrintLog($this->restore_msg); 
     522            $this->tpl_restore_name = $bkup_name; 
     523        } 
    472524 
    473525        // FIXME この辺りで、バックアップ時と同等の一時ファイルの削除を実行すべきでは? 
     526 
     527        return $success; 
    474528    } 
    475529 
     
    521575            while (!feof($fp)) { 
    522576                $line++; 
    523                 $arrCsvLine = fgetcsv($fp, 1000000); 
     577                $arrCsvLine = fgetcsv($fp, 1024 * 1024); 
    524578 
    525579                // 1行目: 列名 
     
    548602    } 
    549603 
    550     // 自動採番をセット 
    551     function lfSetAutoInc(&$objQuery, $csv) { 
     604    /** 
     605     * シーケンス生成器を復元する 
     606     */ 
     607    function restoreSequence(&$objQuery, $csv) { 
    552608        // csvファイルからデータの取得 
    553609        $arrCsvData = file($csv); 
    554610 
    555         foreach ($arrCsvData as $val) { 
    556             $arrData = explode(',', trim($val)); 
    557  
    558             $objQuery->setval($arrData[0], $arrData[1]); 
     611        foreach ($arrCsvData as $line) { 
     612            list($name, $currval) = explode(',', trim($line)); 
     613 
     614            if (in_array($name, $this->arrExcludeSequence, true)) { 
     615                continue 1; 
     616            } 
     617 
     618            // FIXME テーブルと同様に整合チェックを行う。また不整合時はスキップして続行する。 
     619 
     620            // XXX +1 ではなく、nextVal を呼ぶべきかも。 
     621            $objQuery->setVal($name, $currval + 1); 
    559622        } 
    560623    } 
Note: See TracChangeset for help on using the changeset viewer.