Index: branches/version-2_5-dev/data/class_extends/page_extends/admin/system/LC_Page_Admin_System_Editdb_Ex.php
===================================================================
--- branches/version-2_5-dev/data/class_extends/page_extends/admin/system/LC_Page_Admin_System_Editdb_Ex.php	(revision 19662)
+++ branches/version-2_5-dev/data/class_extends/page_extends/admin/system/LC_Page_Admin_System_Editdb_Ex.php	(revision 19662)
@@ -0,0 +1,67 @@
+<?php
+/*
+ * This file is part of EC-CUBE
+ *
+ * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
+ *
+ * http://www.lockon.co.jp/
+ *
+ * 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+// {{{ requires
+require_once(CLASS_PATH . "pages/admin/system/LC_Page_Admin_System_Editdb.php");
+
+/**
+ * システム情報 のページクラス(拡張).
+ *
+ * LC_Page_Admin_System_Editdb をカスタマイズする場合はこのクラスを編集する.
+ *
+ * @package Page
+ * @author LOCKON CO.,LTD.
+ * @version $Id: LC_Page_Admin_System_Editdb_Ex.php 18701 2010-06-14 08:30:18Z nanasess $
+ */
+class LC_Page_Admin_System_Editdb_Ex extends LC_Page_Admin_System_Editdb {
+
+    // }}}
+    // {{{ functions
+
+    /**
+     * Page を初期化する.
+     *
+     * @return void
+     */
+    function init() {
+        parent::init();
+    }
+
+    /**
+     * Page のプロセス.
+     *
+     * @return void
+     */
+    function process() {
+        parent::process();
+    }
+
+    /**
+     * デストラクタ.
+     *
+     * @return void
+     */
+    function destroy() {
+        parent::destroy();
+    }
+}
Index: branches/version-2_5-dev/data/class/SC_Initial.php
===================================================================
--- branches/version-2_5-dev/data/class/SC_Initial.php	(revision 18815)
+++ branches/version-2_5-dev/data/class/SC_Initial.php	(revision 19662)
@@ -86,6 +86,4 @@
                     DB_TYPE . "://" . DB_USER . ":" . DB_PASSWORD . "@"
                     . DB_SERVER . ":" .DB_PORT . "/" . DB_NAME);
-        } else {
-            define("DEFAULT_DSN", "pgsql://nobody:password@localhost:5432/eccubedb");
         }
     }
Index: branches/version-2_5-dev/data/class/helper/SC_Helper_Session.php
===================================================================
--- branches/version-2_5-dev/data/class/helper/SC_Helper_Session.php	(revision 19661)
+++ branches/version-2_5-dev/data/class/helper/SC_Helper_Session.php	(revision 19662)
@@ -153,5 +153,6 @@
     function getToken() {
         if (empty($_SESSION[TRANSACTION_ID_NAME])) {
-            $_SESSION[TRANSACTION_ID_NAME] = $this->createToken();
+            // FIXME
+            //$_SESSION[TRANSACTION_ID_NAME] = $this->createToken();
         }
         return $_SESSION[TRANSACTION_ID_NAME];
Index: branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php
===================================================================
--- branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php	(revision 19456)
+++ branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php	(revision 19662)
@@ -897,33 +897,122 @@
     /**
      * カテゴリ数の登録を行う.
+     * 
      *
      * @param SC_Query $objQuery SC_Query インスタンス
      * @return void
      */
-    function sfCategory_Count($objQuery){
+    function sfCategory_Count($objQuery = NULL){
+        $objProduct = new SC_Product();
+        
+        if($objQuery == NULL) {
+                $objQuery =& SC_Query::getSingletonInstance();
+        }
+        $is_out_tarns = false;
+        //トランザクションの開始確認。開始していない場合は
+        if(!$objQuery->inTransaction()){
+            //TODO: トランザクション制御を足す？ (重い！）
+            //$objQuery->begin();
+            $is_out_trans = false;
+        }
+
+        //共通のfrom/where文の構築
+        $sql_where = 'alldtl.del_flg = 0 AND alldtl.status = 1';
+        // 在庫無し商品の非表示
+        if (NOSTOCK_HIDDEN === true) {
+            $sql_where_dtl = 'stock_max >= 1 OR stock_unlimited_max = 1';
+            $from = $objProduct->alldtlSQL($sql_where_dtl);
+        }else{
+            $from = " dtb_products as alldtl ";
+        }
+        
+        //dtb_category_countの構成
+        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを含まない。
+        // 2.5で消える予定だったが復活させます。
+        
+        //まずテーブル内容の元を取得
+        $arrCategoryCountOld = $objQuery->select('category_id,product_count','dtb_category_count');
 
         //テーブル内容の削除
         $objQuery->query("DELETE FROM dtb_category_count");
-        $objQuery->query("DELETE FROM dtb_category_total_count");
-
-        $sql_where .= 'alldtl.del_flg = 0 AND alldtl.status = 1';
-        // 在庫無し商品の非表示
-        if (NOSTOCK_HIDDEN === true) {
-            $sql_where .= ' AND (alldtl.stock_max >= 1 OR alldtl.stock_unlimited_max = 1)';
-        }
-
-        //子カテゴリ内の商品数を集計する
-
-        // カテゴリ情報を取得
-        $arrCat = $objQuery->select('category_id', 'dtb_category');
-
-        $objProduct = new SC_Product();
-
-        foreach ($arrCat as $row) {
-            $category_id = $row['category_id'];
+
+        //各カテゴリ内の商品数を数えて格納
+        // これは単純集計なので比較的軽い
+        $sql = <<< __EOS__
+            INSERT INTO dtb_category_count(category_id, product_count, create_date)
+            SELECT T1.category_id, count(T2.category_id), now()
+            FROM dtb_category AS T1
+                LEFT JOIN dtb_product_categories AS T2
+                    ON T1.category_id = T2.category_id
+                LEFT JOIN $from
+                    ON T2.product_id = alldtl.product_id
+            WHERE $sql_where
+            GROUP BY T1.category_id, T2.category_id
+__EOS__;
+        $objQuery->query($sql);
+                
+        //dtb_category_total_countの構成
+        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを「含む」。        
+        //差分を取得して、更新対象カテゴリだけを確認する。
+        
+        //各カテゴリ毎のデータ値において以前との差を見る
+        $arrCategoryCountNew = $objQuery->select('category_id, product_count','dtb_category_count');
+        
+        //古いデータの構造入れ替え
+        $arrOld = array();
+        foreach($arrCategoryCountOld as $item){
+            $arrOld[$item['category_id']] = $item;
+        }
+        //新しいデータの構造入れ替え
+        $arrNew = array();
+        foreach($arrCategoryCountNew as $item){
+            $arrNew[$item['category_id']] = $item;
+        }
+        $arrDiffCategory_id = array();
+        //新しいカテゴリ一覧から見て商品数が異なるデータが無いか確認
+        foreach($arrCategoryCountNew as $item){
+            $category_id = $item['category_id'];
+            if($arrOld[$category_id]['product_count'] != $item['product_count']){
+                $arrDiffCategory_id[] = $category_id;
+            }
+        }
+        //削除カテゴリを想定して、古いカテゴリ一覧から見て商品数が異なるデータが無いか確認。
+        foreach($arrCategoryCountOld as $item){
+            $category_id = $item['category_id'];
+            if($arrNew[$category_id]['product_count'] != $item['product_count']){
+                $arrDiffCategory_id[] = $category_id;
+            }
+        }
+        
+        //対象IDが無ければ終了
+        if(count($arrDiffCategory_id) == 0){
+            if($is_out_tarns){
+                $objQuery->commit();
+            }
+            return;
+        }
+
+        //差分対象カテゴリIDの重複を除去
+        $arrDiffCategory_id = array_unique($arrDiffCategory_id);
+        //差分があったIDとその親カテゴリIDのリストを取得する
+        $arrTgtCategory_id = array();
+        foreach ($arrDiffCategory_id as $parent_category_id) {
+            $arrTgtCategory_id[] = $parent_category_id;
+            $arrParentID = $this->sfGetParents($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
+            foreach($arrParentID as $pid) {
+                $arrTgtCategory_id[] = $pid;
+            }
+        }
+        
+        //重複を取り除く
+        $arrTgtCategory_id = array_unique($arrTgtCategory_id);
+
+        //dtb_cateogry_total_count 集計処理開始
+        //旧データの削除
+        $objQuery->query("DELETE FROM dtb_category_total_count WHERE category_id in (" . implode(',',$arrTgtCategory_id) . ")");
+
+        //カテゴリ毎に処理
+        foreach ($arrTgtCategory_id as $category_id) {
             $arrval = array();
-
             $arrval[] = $category_id;
-
             list($tmp_where, $tmp_arrval) = $this->sfGetCatWhere($category_id);
             if ($tmp_where != "") {
@@ -945,6 +1034,9 @@
                WHERE $where
 __EOS__;
-
             $objQuery->query($sql, $arrval);
+        }
+        //トランザクションの終了処理。
+        if($is_out_tarns){
+            $objQuery->commit();
         }
     }
Index: branches/version-2_5-dev/data/class/SC_Query.php
===================================================================
--- branches/version-2_5-dev/data/class/SC_Query.php	(revision 18820)
+++ branches/version-2_5-dev/data/class/SC_Query.php	(revision 19662)
@@ -65,10 +65,8 @@
             $this->conn = MDB2::singleton($dsn, $options);
         }
-
         if (!PEAR::isError($this->conn)) {
             $this->conn->setCharset(CHAR_CODE);
             $this->conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
         }
-
         $this->dbFactory = SC_DB_DBFactory_Ex::getInstance();
         $this->force_run = $force_run;
@@ -733,5 +731,28 @@
         return $this->conn->listTableIndexes($table);
     }
-
+    
+    /**
+     * テーブルにインデックスを付与する
+     *
+     * @param string $table テーブル名
+     * @param string $name インデックス名
+     * @param array $definition フィールド名など　通常のフィールド指定時は、$definition=array('fields' => array('フィールド名' => array()));
+     */
+    function createIndex($table, $name, $definition) {
+        $this->conn->loadModule('Manager');
+        return $this->conn->createIndex($table, $name, $definition);
+    }
+
+    /**
+     * テーブルにインデックスを破棄する
+     *
+     * @param string $table テーブル名
+     * @param string $name インデックス名
+     */
+    function dropIndex($table, $name) {
+        $this->conn->loadModule('Manager');
+        return $this->conn->dropIndex($table, $name);
+    }
+    
     /**
      * 値を適切にクォートする.
@@ -777,5 +798,18 @@
      */
     function execute(&$sth, $arrVal = array()) {
+        $timeStart = SC_Utils_Ex::sfMicrotimeFloat();
         $affected =& $sth->execute($arrVal);
+
+        // 一定以上時間かかったSQLの場合、ログ出力する。
+        if(defined('SQL_QUERY_LOG_MODE') && SQL_QUERY_LOG_MODE == true) {
+            $timeEnd = SC_Utils_Ex::sfMicrotimeFloat();;
+            $timeExecTime = $timeEnd - $timeStart;
+            if(defined('SQL_QUERY_LOG_MIN_EXEC_TIME') && $timeExecTime >= (float)SQL_QUERY_LOG_MIN_EXEC_TIME) {
+                //$logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $this->getLastQuery(false));
+                $logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $sth->query);
+                GC_Utils_Ex::gfPrintLog($logMsg);
+            }
+        }
+
         if (PEAR::isError($affected)) {
             $sql = isset($sth->query) ? $sth->query : '';
Index: branches/version-2_5-dev/data/class/SC_Product.php
===================================================================
--- branches/version-2_5-dev/data/class/SC_Product.php	(revision 18882)
+++ branches/version-2_5-dev/data/class/SC_Product.php	(revision 19662)
@@ -46,7 +46,23 @@
     var $classCat2_find;
     var $classCats1;
-
-    /**
-     * SC_Queryインスタンスに設定された検索条件をもとに商品IDの配列を取得する.
+    /** 検索用並び替え条件配列 */
+    var $arrOrderData;
+    
+    /**
+     * 商品検索結果の並び順を指定する。
+     *
+     * ただし指定できるテーブルはproduct_idを持っているテーブルであることが必要.
+     *
+     * @param string $col 並び替えの基準とするフィールド
+     * @param string $table 並び替えの基準とするフィールドがあるテーブル
+     * @param string $order 並び替えの順序 ASC / DESC
+     * @return void
+     */
+    function setProductsOrder($col, $table = 'dtb_products', $order = 'ASC') {
+        $this->arrOrderData = array('col' => $col, 'table' => $table, 'order' => $order);
+    }
+
+    /**
+     * SC_Queryインスタンスに設定された検索条件を元に並び替え済みの検索結果商品IDの配列を取得する。
      *
      * 検索条件は, SC_Query::getWhere() 関数で設定しておく必要があります.
@@ -56,5 +72,49 @@
      * @return array 商品IDの配列
      */
-    function findProductIds(&$objQuery, $arrVal = array()) {
+    function findProductIdsOrder(&$objQuery, $arrVal = array(), $where) {
+        $table = <<< __EOS__
+                 dtb_products AS alldtl
+            JOIN dtb_products_class AS T1
+              ON alldtl.product_id = T1.product_id
+            JOIN dtb_product_categories AS T2
+              ON alldtl.product_id = T2.product_id
+            JOIN dtb_category
+              ON T2.category_id = dtb_category.category_id
+__EOS__;
+        $objQuery->setGroupBy('alldtl.product_id');
+        if(is_array($this->arrOrderData) and $objQuery->order == ""){
+            $o_col = $this->arrOrderData['col'];
+            $o_table = $this->arrOrderData['table'];
+            $o_order = $this->arrOrderData['order'];
+            $order = <<< __EOS__
+                    (
+                        SELECT $o_col
+                        FROM
+                            $o_table as T2
+                        WHERE T2.product_id = alldtl.product_id
+                        ORDER BY T2.$o_col $o_order
+                        LIMIT 1
+                    ) $o_order, product_id
+__EOS__;
+            $objQuery->setOrder($order);
+        }
+        $results = $objQuery->select('alldtl.product_id', $table, "", $arrVal,
+                                     MDB2_FETCHMODE_ORDERED);
+        foreach ($results as $val) {
+            $resultValues[] = $val[0];
+        }
+        return $resultValues;
+    }
+
+    /**
+     * SC_Queryインスタンスに設定された検索条件をもとに対象商品数を取得する.
+     *
+     * 検索条件は, SC_Query::getWhere() 関数で設定しておく必要があります.
+     *
+     * @param SC_Query $objQuery SC_Query インスタンス
+     * @param array $arrVal 検索パラメータの配列
+     * @return array 対象商品ID数
+     */
+    function findProductCount(&$objQuery, $arrVal = array()) {
         $table = <<< __EOS__
                  dtb_products AS alldtl
@@ -64,11 +124,7 @@
               ON T2.category_id = dtb_category.category_id
 __EOS__;
-        // SC_Query::getCol() ではパフォーマンスが出ない
-        $results = $objQuery->select('alldtl.product_id', $table, "", $arrVal,
-                                     MDB2_FETCHMODE_ORDERED);
-        foreach ($results as $val) {
-            $resultValues[] = $val[0];
-        }
-        return array_unique($resultValues);
+        $objQuery->setGroupBy('alldtl.product_id');
+        $sql_base = $objQuery->getSql('alldtl.product_id',$table);
+        return $objQuery->getOne( "SELECT count(*) FROM ( $sql_base ) as t" , $arrVal);
     }
 
@@ -109,6 +165,7 @@
             ,update_date
 __EOS__;
-        return $objQuery->select($col, $this->alldtlSQL($objQuery->where),
+        $res = $objQuery->select($col, $this->alldtlSQL($objQuery->where),
                                  "", $arrVal);
+        return $res;
     }
 
Index: branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php
===================================================================
--- branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php	(revision 19661)
+++ branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php	(revision 19662)
@@ -328,5 +328,4 @@
     /* 商品一覧の表示 */
     function lfDispProductsList() {
-
         $objDb = new SC_Helper_DB_Ex();
         $arrval = array();
@@ -338,18 +337,15 @@
             list($where_category, $arrval_category) = $objDb->sfGetCatWhere($this->arrSearchData['category_id']);
         }
-
         // ▼対象商品IDの抽出
         // 商品検索条件の作成（未削除、表示）
-        $where = "del_flg = 0 AND status = 1 ";
-        $where1 = "alldtl.del_flg = 0 AND alldtl.status = 1 ";
+        $where = "alldtl.del_flg = 0 AND alldtl.status = 1 ";
 
         // 在庫無し商品の非表示
         if (NOSTOCK_HIDDEN === true) {
-            $where .= ' AND (stock_max >= 1 OR stock_unlimited_max = 1)';
+            $where .= ' AND (stock >= 1 OR stock_unlimited = 1)';
         }
 
         if (strlen($where_category) >= 1) {
-            $where.= " AND $where_category";
-            $where1 .= " AND T2.$where_category";
+            $where .= " AND T2.$where_category";
             $arrval = array_merge($arrval, $arrval_category);
         }
@@ -365,6 +361,5 @@
         foreach ($names as $val) {
             if ( strlen($val) > 0 ) {
-                $where .= " AND ( name ILIKE ? OR comment3 ILIKE ?) ";
-                $where1 .= " AND ( alldtl.name ILIKE ? OR alldtl.comment3 ILIKE ?) ";
+                $where .= " AND ( alldtl.name ILIKE ? OR alldtl.comment3 ILIKE ?) ";
                 $arrval[] = "%$val%";
                 $arrval[] = "%$val%";
@@ -374,18 +369,13 @@
         // メーカーらのWHERE文字列取得
         if ($this->arrSearchData['maker_id']) {
-            $where .= " AND maker_id = ? ";
-            $where1 .= " AND alldtl.maker_id = ? ";
+            $where .= " AND alldtl.maker_id = ? ";
             $arrval[] = $this->arrSearchData['maker_id'];
         }
-
-        // 一覧表示する商品IDを取得
+ 
+        // 検索結果対象となる商品の数を取得
         $objQuery =& SC_Query::getSingletonInstance();
-        $objQuery->setWhere($where1);
+        $objQuery->setWhere($where);
         $objProduct = new SC_Product();
-        $arrProduct_id = $objProduct->findProductIds($objQuery, $arrval);
-
-        // 行数の取得
-        $linemax = count($arrProduct_id);
-
+        $linemax = $objProduct->findProductCount($objQuery, $arrval);
         $this->tpl_linemax = $linemax;   // 何件が該当しました。表示用
 
@@ -399,24 +389,16 @@
         $startno = $this->objNavi->start_row;                 // 開始行
 
-        // WHERE 句
-        $where = '0=0';
-        if (is_array($arrProduct_id) && !empty($arrProduct_id)) {
-            $where .= ' AND product_id IN (' . implode(',', $arrProduct_id) . ')';
-        } else {
-            // 一致させない
-            $where .= ' AND 0<>0';
-        }
-
+        $objProduct = new SC_Product();
+        $objQuery =& SC_Query::getSingletonInstance();
         // 表示順序
         switch ($this->orderby) {
-
-            // 販売価格順
+            // 販売価格が安い順
             case 'price':
-                $order = "price02_min, product_id";
+                $objProduct->setProductsOrder('price02', 'dtb_products_class', 'ASC');
                 break;
 
             // 新着順
             case 'date':
-                $order = "create_date DESC, product_id";
+                $objProduct->setProductsOrder('create_date', 'dtb_products', 'DESC');
                 break;
 
@@ -453,25 +435,38 @@
                     ,product_id
 __EOS__;
+                    $objQuery->setOrder($order);
                 break;
         }
-
         // 取得範囲の指定(開始行番号、行数のセット)
+        $objQuery->setLimitOffset($this->disp_number, $startno)
+                 ->setWhere($where);
+
+         // 表示すべきIDとそのIDの並び順を一気に取得
+        $arrProduct_id = $objProduct->findProductIdsOrder($objQuery, array_merge($arrval, $arrval_order));
+
+        // 取得した表示すべきIDだけを指定して情報を取得。
+        $where = "";
+        if (is_array($arrProduct_id) && !empty($arrProduct_id)) {
+            $where = 'product_id IN (' . implode(',', $arrProduct_id) . ')';
+        } else {
+            // 一致させない
+            $where = '0<>0';
+        }
         $objQuery =& SC_Query::getSingletonInstance();
-        $objQuery->setLimitOffset($this->disp_number, $startno)
-                 ->setOrder($order)
-                 ->setWhere($where);
-
-        // 検索結果の取得
-        $objProduct = new SC_Product();
-        $this->arrProducts = $objProduct->lists($objQuery, $arrval_order);
-
-        $arrProductId = array();
-        // 規格セレクトボックス設定
-        foreach ($this->arrProducts as $product) {
-            $arrProductId[] = $product['product_id'];
+        $objQuery->setWhere($where);
+        $arrProducts = $objProduct->lists($objQuery, $arrProduct_id);
+
+        //取得している並び順で並び替え
+        $arrProducts2 = array();
+        foreach($arrProducts as $item) {
+            $arrProducts2[ $item['product_id'] ] = $item;
+        }
+        $this->arrProducts = array();
+        foreach($arrProduct_id as $product_id) {
+            $this->arrProducts[] = $arrProducts2[$product_id];
         }
 
         // 規格を設定
-        $objProduct->setProductsClassByProductIds($arrProductId);
+        $objProduct->setProductsClassByProductIds($arrProduct_id);
 
         // 規格1クラス名
@@ -494,5 +489,5 @@
 
         // 商品ステータスを取得
-        $this->productStatus = $objProduct->getProductStatus($arrProductId);
+        $this->productStatus = $objProduct->getProductStatus($arrProduct_id);
 
         $productsClassCategories = $objProduct->classCategories;
Index: branches/version-2_5-dev/data/class/pages/LC_Page.php
===================================================================
--- branches/version-2_5-dev/data/class/pages/LC_Page.php	(revision 19661)
+++ branches/version-2_5-dev/data/class/pages/LC_Page.php	(revision 19662)
@@ -85,4 +85,7 @@
      */
     function init() {
+        // 開始時刻を設定する。
+        $this->timeStart = SC_Utils_Ex::sfMicrotimeFloat();
+
         $this->tpl_authority = $_SESSION['authority'];
         // XXX すべてのページで宣言するべき
@@ -149,5 +152,16 @@
      * @return void
      */
-    function destroy() {}
+    function destroy() {
+        // 一定時間以上かかったページの場合、ログ出力する。
+        if(defined('PAGE_DISPLAY_TIME_LOG_MODE') && PAGE_DISPLAY_TIME_LOG_MODE == true) {
+            $timeEnd = SC_Utils_Ex::sfMicrotimeFloat();;
+            $timeExecTime = $timeEnd - $this->timeStart;
+            if(defined('PAGE_DISPLAY_TIME_LOG_MIN_EXEC_TIME') && $timeExecTime >= (float)PAGE_DISPLAY_TIME_LOG_MIN_EXEC_TIME) {
+                $logMsg = sprintf("PAGE_DISPLAY_TIME_LOG [%.2fsec]", $timeExecTime);
+                GC_Utils_Ex::gfPrintLog($logMsg);
+            }
+        }
+
+    }
 
     /**
Index: branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php
===================================================================
--- branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php	(revision 19661)
+++ branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php	(revision 19662)
@@ -71,5 +71,4 @@
         $objSess = new SC_Session();
         $objDb = new SC_Helper_DB_Ex();
-        $objQuery = new SC_Query();
 
         // 認証可否の判定
@@ -91,5 +90,5 @@
             $this->lfConvertParam();
 
-            $where = "del_flg = 0";
+            $where = "alldtl.del_flg = 0";
             $arrval = array();
 
@@ -108,10 +107,10 @@
                     list($tmp_where, $tmp_arrval) = $objDb->sfGetCatWhere($val);
                     if($tmp_where != "") {
-                        $where.= " AND product_id IN (SELECT product_id FROM dtb_product_categories WHERE " . $tmp_where . ")";
+                        $where.= " AND alldtl.product_id IN (SELECT product_id FROM dtb_product_categories WHERE " . $tmp_where . ")";
                         $arrval = array_merge((array)$arrval, (array)$tmp_arrval);
                     }
                     break;
                 case 'search_product_code':
-                    $where .= " AND product_id IN (SELECT product_id FROM dtb_products_class WHERE product_code LIKE ? GROUP BY product_id)";
+                    $where .= " AND alldtl.product_id IN (SELECT product_id FROM dtb_products_class WHERE product_code LIKE ? GROUP BY product_id)";
                     $arrval[] = "$val%";
                     break;
@@ -121,10 +120,10 @@
             }
 
+            // 検索結果対象となる商品の数を取得
+            $objQuery =& SC_Query::getSingletonInstance();
+            $objQuery->setWhere($where);
             $objProduct = new SC_Product();
-            $productIds = $objProduct->findProductIds($objQuery, $arrval);
-
-            // 行数の取得
-            $linemax = count($productIds);
-            $this->tpl_linemax = $linemax;
+            $linemax = $objProduct->findProductCount($objQuery, $arrval);
+            $this->tpl_linemax = $linemax;   // 何件が該当しました。表示用
 
             // ページ送りの処理
@@ -141,4 +140,8 @@
             $startno = $objNavi->start_row;
 
+            $objProduct = new SC_Product();
+            $objQuery =& SC_Query::getSingletonInstance();
+            $objQuery->setWhere($where);
+
             // 取得範囲の指定(開始行番号、行数のセット)
             $objQuery->setLimitOffset($page_max, $startno);
@@ -147,6 +150,28 @@
 
             // 検索結果の取得
-            $this->arrProducts = $objProduct->lists($objQuery, $arrval);
-            $objProduct->setProductsClassByProductIds($productIds);
+            $arrProduct_id = $objProduct->findProductIdsOrder($objQuery, $arrval);
+
+            $where = "";
+            if (is_array($arrProduct_id) && !empty($arrProduct_id)) {
+                $where = 'product_id IN (' . implode(',', $arrProduct_id) . ')';
+            } else {
+                // 一致させない
+                $where = '0<>0';
+            }
+            $objQuery =& SC_Query::getSingletonInstance();
+            $objQuery->setWhere($where);
+            $arrProducts = $objProduct->lists($objQuery, $arrProduct_id);
+
+            //取得している並び順で並び替え
+            $arrProducts2 = array();
+            foreach($arrProducts as $item) {
+                $arrProducts2[ $item['product_id'] ] = $item;
+            }
+            $this->arrProducts = array();
+            foreach($arrProduct_id as $product_id) {
+                $this->arrProducts[] = $arrProducts2[$product_id];
+            }
+
+            $objProduct->setProductsClassByProductIds($arrProduct_id);
             $objJson = new Services_JSON();
             $this->tpl_javascript .= 'productsClassCategories = ' . $objJson->encode($objProduct->classCategories) . '; ';
Index: branches/version-2_5-dev/data/class/pages/admin/system/LC_Page_Admin_System_Editdb.php
===================================================================
--- branches/version-2_5-dev/data/class/pages/admin/system/LC_Page_Admin_System_Editdb.php	(revision 19662)
+++ branches/version-2_5-dev/data/class/pages/admin/system/LC_Page_Admin_System_Editdb.php	(revision 19662)
@@ -0,0 +1,172 @@
+<?php
+/*
+ * This file is part of EC-CUBE
+ *
+ * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
+ *
+ * http://www.lockon.co.jp/
+ *
+ * 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+// {{{ requires
+require_once(CLASS_PATH . "pages/LC_Page.php");
+
+/**
+ * システム情報 のページクラス.
+ *
+ * @package Page
+ * @author LOCKON CO.,LTD.
+ * @version $Id: LC_Page_Admin_System_Editdb.php 18701 2010-06-14 08:30:18Z nanasess $
+ */
+class LC_Page_Admin_System_Editdb extends LC_Page {
+
+    // }}}
+    // {{{ functions
+
+    /**
+     * Page を初期化する.
+     *
+     * @return void
+     */
+    function init() {
+        parent::init();
+        $this->tpl_mainpage = 'system/editdb.tpl';
+        $this->tpl_subnavi  = 'system/subnavi.tpl';
+        $this->tpl_subno    = 'editdb';
+        $this->tpl_mainno   = 'system';
+        $this->tpl_subtitle = '高度なデータベース管理';
+    }
+
+    /**
+     * フォームパラメータ初期化
+     *
+     * @return void
+     */
+    function initForm() {
+        $objForm = new SC_FormParam();
+        $objForm->addParam('mode', 'mode', INT_LEN, '', array('ALPHA_CHECK', 'MAX_LENGTH_CHECK'));
+        $objForm->addParam('table_name', 'テーブル名');
+        $objForm->addParam('column_name', 'カラム名');
+        $objForm->addParam('indexflag', 'インデックス');
+	$objForm->addParam('indexflag_new', 'インデックス（変更後）');
+	
+	$objForm->setParam($_POST);
+        $this->objForm = $objForm;
+    }
+
+    /**
+     * Page のプロセス.
+     *
+     * @return void
+     */
+    function process() {
+
+        SC_Utils_Ex::sfIsSuccess(new SC_Session);
+        $objView = new SC_AdminView();
+	$objSiteInfo = new SC_SiteInfo();
+        $objQuery = new SC_Query();
+        $objDb = new SC_Helper_DB_Ex();
+        $objProduct = new SC_Product();
+
+	//インデックスの値を取得
+	$this->arrForm = $this->lfGetIndexList();
+
+	//フォームの値を取得
+        $this->initForm();
+	
+        switch($this->objForm->getValue('mode')) {
+	//確認画面へ
+	case 'confirm' :
+	    //POSTの値と配列の値を比較
+	    // TODO: $_POSTを使わないように修正する。
+            $arrIndexFlag  = $_POST['indexflag'];
+            $arrIndexFlagNewIndex  = $_POST['indexflag_new'];
+
+            $arrIndexFlagNew = array();
+            for($i = 0; $i < count($arrIndexFlag); $i++) {
+                if(array_search($i, $arrIndexFlagNewIndex) !== false) {
+                    $arrIndexFlagNew[] = true;
+                } else {
+                    $arrIndexFlagNew[] = false;
+		}
+	    }
+
+            $objQuery = new SC_Query();
+	    foreach($arrIndexFlag as $key => $val){
+		if($val != $arrIndexFlagNew[$key]) {
+                    //値が異なっていた場合、インデックスのアップデートをかける
+                    $index_name = $_POST["table_name"][$key] . "_" . $_POST["column_name"][$key] . "_key";
+                    if($arrIndexFlagNew[$key] == false) {
+                        $objQuery->dropIndex($_POST["table_name"][$key], $index_name);
+                    } else {
+                        $objQuery->createIndex($_POST["table_name"][$key], $index_name, array('fields' => array($_POST["column_name"][$key] => array())));
+                    }
+
+                    // フォームに引継ぐ
+                    $this->arrForm[$key]["indexflag"] = true;
+		}
+	    }
+	    
+	    $this->tpl_onload = "window.alert('インデックスの変更が完了しました。');";
+        default:
+        break;
+        }
+
+        $objView->assignobj($this);
+        $objView->display(MAIN_FRAME);
+    }
+
+    /**
+     * デストラクタ.
+     *
+     * @return void
+     */
+    function destroy() {
+        parent::destroy();
+    }
+    
+    /**
+     * インデックス設定を行う一覧を返す関数
+     *
+     * @return void
+     */
+    function lfGetIndexList()
+    {
+        // データベースからインデックス設定一覧を取得する
+        $objQuery = new SC_Query();
+        $objQuery->setOrder("table_name, column_name");
+        $arrIndexList = $objQuery->select("table_name , column_name , recommend_flg, recommend_comment", "dtb_index_list");
+
+        $table = "";
+        foreach($arrIndexList as $key => $arrIndex) {
+            // テーブルに対するインデックス一覧を取得
+            if($table !== $arrIndex["table_name"]) {
+                $table = $arrIndex["table_name"];
+                $arrIndexes = $objQuery->listTableIndexes($table);
+            }
+ 
+            // インデックスが設定されているかを取得
+            if(array_search($table . "_" . $arrIndex["column_name"] . "_key", $arrIndexes) === false) {
+                $arrIndexList[$key]["indexflag"] = false;
+            } else {
+                $arrIndexList[$key]["indexflag"] = true;
+            }
+        }
+    
+        return $arrIndexList;
+    }
+    
+}
Index: branches/version-2_5-dev/data/Smarty/templates/admin/system/subnavi.tpl
===================================================================
--- branches/version-2_5-dev/data/Smarty/templates/admin/system/subnavi.tpl	(revision 19661)
+++ branches/version-2_5-dev/data/Smarty/templates/admin/system/subnavi.tpl	(revision 19662)
@@ -30,3 +30,4 @@
 <li<!--{if $tpl_subno == 'plugin'}--> class="on"<!--{/if}--> id="navi-system-plugin"><a href="<!--{$smarty.const.URL_DIR}-->admin/system/plugin.php"><span>プラグイン管理</span></a></li>
 <li<!--{if $tpl_mainno == 'system' && $tpl_subno == 'log'}--> class="on"<!--{/if}--> id="navi-system-log"><a href="<!--{$smarty.const.URL_DIR}-->admin/system/log.php"><span>ログ表示</span></a></li>
+<li<!--{if $tpl_mainno == 'system' && $tpl_subno == 'editdb'}--> class="on"<!--{/if}--> id="navi-system-editdb"><a href="<!--{$smarty.const.URL_DIR}-->admin/system/editdb.php"><span>高度なデータベース管理</span></a></li>
 </ul>
Index: branches/version-2_5-dev/data/Smarty/templates/admin/system/editdb.tpl
===================================================================
--- branches/version-2_5-dev/data/Smarty/templates/admin/system/editdb.tpl	(revision 19662)
+++ branches/version-2_5-dev/data/Smarty/templates/admin/system/editdb.tpl	(revision 19662)
@@ -0,0 +1,54 @@
+<!--{*
+/*
+ * This file is part of EC-CUBE
+ *
+ * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
+ *
+ * http://www.lockon.co.jp/
+ *
+ * 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+*}-->
+
+<h2>インデックス管理</h2>
+
+<form name="index_form"  method="post" action="?"> 
+  <input type="hidden" name="mode" value="confirm" />
+      <table class="list">
+      <tr>
+        <th>インデックス</th>
+        <th>テーブル名</th>
+        <th>カラム名</th>
+        <th>説明</th>
+      </tr>
+
+      
+ <!--{section name=cnt loop=$arrForm}-->
+  
+    <tr>
+    <td><input type="checkbox" name="indexflag_new[]" value="<!--{$smarty.section.cnt.index}-->" <!--{if $arrForm[cnt].indexflag == "1"}-->checked<!--{/if}--> /></td>
+    <td><!--{$arrForm[cnt].table_name}--></td>
+    <td><!--{$arrForm[cnt].column_name}--></td>
+    <td><!--{$arrForm[cnt].recommend_comment}--></td>
+    </tr>
+<input type="hidden" name="table_name[]" value="<!--{$arrForm[cnt].table_name}-->" />
+<input type="hidden" name="column_name[]" value="<!--{$arrForm[cnt].column_name}-->" />
+<input type="hidden" name="indexflag[]" value="<!--{$arrForm[cnt].indexflag}-->" />
+
+<!--{/section}-->
+</table>
+
+<input type="submit" value="変更する">
+</form>
