<?php
/* SVN FILE: $Id: database.php 444 2008-05-20 08:53:56Z bb_yujiro $ */
/**
 * 実行処理
 *
 * PHP versions 5
 *
 *      Hitsuji : Social Network Service <http://rakuto.net/rktSNS/>
 *      Copyright (c) 2007 Yujiro Takahashi
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @package         Hitsuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/rktSNS/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 444 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-20 17:53:56 +0900 (火, 20 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */

/**
 * Controllerクラス
 *
 * @category        Hitsuji : controller
 * @package         Hitsuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 444 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-20 17:53:56 +0900 (火, 20 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */
class Controller extends RKT_Controller
{
    /**
     * DB接続オジェクト
     * @var object
     */
    private $_objdb = null;

    /**
     * 変数の初期化
     *
     * @abstract
     * @access protected
     * @return void
     */
    protected function initValue()
    {
        $this->_objdb = RKT_DB::getInstance();
    }

    /**
     * 実行処理
     *
     * @access public
     * @return void
     **/
    protected function action()
    {
        if (!empty($_GET['complete'])){
            $this->assign('complete', true);
        }
        
        if (!empty($_REQUEST['action'])){
            switch ($_REQUEST['action']){
            case 'table':
                $this->_createTable();
                break;
            case 'data':
                $this->_insertData();
                break;
            case 'theme':
                $this->_defalutTheme();
                break;
            case 'complete':
                $this->_complete();
                break;
            default :
                $this->_default();
                break;
            } // switch ($_REQUEST['action'])
        }
    }

    /**
     * テーブル設定
     *
     * @access private
     * @return void
     **/
    private function _createTable()
    {
        $this->setBaseFile('common/frame/json.tpl');
        $this->setMimeType('application/json');

        $next = 'data';
        $per  = 100;
        try {
            $this->_objdb->beginTransaction();
            $this->_crateQuery();
            $this->_objdb->commit();
        } catch (PDOException $exception){
            $next = 'table';
            $per  = 0;
            $this->_objdb->rollBack();
        }
        $list = array(
            'bar'=>  'table',
            'per'=>  $per,
            'next'=> $next,
            'complete'=> false,
        );
        $this->assign('data', json_encode($list));
    }

    /**
     * 初期データ設定
     *
     * @access private
     * @return void
     **/
    private function _insertData()
    {
        $this->setBaseFile('common/frame/json.tpl');
        $this->setMimeType('application/json');

        $next = 'theme';
        $per  = 100;
        try {
            /* インサート */
            $query = file_get_contents(TMP_DIR.'sqls'.DS.'insert.sql');
            $queries = $this->_explodeQuery($query);

            $this->_objdb->beginTransaction();
            foreach ($queries as $query){
                $this->_objdb->exec($query);
            } // foreach ($queries as $query)
            $this->_objdb->commit();


            /* メールテンプレート */
            $query = file_get_contents(TMP_DIR.'sqls'.DS.'mailtpl.sql');
            $queries = $this->_explodeQuery($query);

            $this->_objdb->beginTransaction();
            foreach ($queries as $query){
                $this->_objdb->exec($query);
            } // foreach ($queries as $query)
            $this->_objdb->commit();
        } catch (PDOException $exception){
            $next = 'data';
            $per  = 0;
            $this->_objdb->rollBack();
        }
        $list = array(
            'bar'=>  'data',
            'per'=>  $per,
            'next'=> $next,
            'complete'=> false,
        );
        $this->assign('data', json_encode($list));
    }

    /**
     * テーマの設定
     *
     * @access private
     * @return void
     **/
    private function _defalutTheme()
    {
        $this->setBaseFile('common/frame/json.tpl');
        $this->setMimeType('application/json');

        include LIB_DIR.'rkt_model.php';
        include LIB_DIR.'rktModel'.DS.'Manip.php';
        include MODEL_DIR.'manips'.DS.'des_theme.php';

        $next     = '';
        $per      = 100;
        try {
            $theme = new des_theme();
            for ($id=1; $id<=5; $id++){
                $theme->setCurId($id);
                $theme->setInitValue();
                $theme->setUpdate();
                $theme->manip();
                $theme->refreshColumn();
            }
        } catch (PDOException $exception){
            $next     = 'theme';
            $per      = 0;
        }

        $list = array(
            'bar'=>  'theme',
            'per'=>  $per,
            'next'=> 'complete',
            'complete'=> false,
        );
        $this->assign('data', json_encode($list));
    }

    /**
     * Completeの設定
     *
     * @access private
     * @return void
     **/
    private function _complete()
    {
        $this->setBaseFile('common/frame/json.tpl');
        $this->setMimeType('application/json');

        $list = array(
            'bar'=>  'none',
            'per'=>  100,
            'next'=> 'none',
            'complete'=> true,
        );
        $this->assign('data', json_encode($list));
    }

    /**
     * Defaultの設定
     *
     * @access private
     * @return void
     **/
    private function _default()
    {
        $this->setBaseFile('common/frame/json.tpl');
        $this->setMimeType('application/json');

        $list = array(
            'bar'=>  'none',
            'per'=>  100,
            'next'=> 'none',
            'complete'=> false,
        );
        $this->assign('data', json_encode($list));
    }

    /**
     * SQLクエリを解析し配列を返す
     *
     * @access public
     * @param string $query クエリ文字列
     * @return array 解析結果の配列
     */
    private function _explodeQuery($query)
    {
        $manips = 'CREATE|DROP|INSERT|UPDATE|DELETE|'.
                  'ROLLBACK|COPY|VACUUM|REPLACE|'.
                  'ATTACH|DETACH|CONFLICT';
        $query = preg_replace('/--.+\n/i', '', $query);
        $query = preg_replace('/\/\*.+\*\//is', '', $query);
        $query = preg_replace('/\\\"/i', '%dqt%', $query);
        $func = array('RKT_DB','__remove_semicolon');
        //$query = preg_replace_callback('/"\s+.+"/is', $func, $query);

        $queries = explode(';', $query);
        $is_trigger = false;
        $result = array();
        $count = count($queries);
    
        for ($row=0; $row<$count; $row++){
            $query = trim($queries[$row]);
            if ($is_trigger){       // トリガークエリ
                if (preg_match('/END/i', $query)){
                    $trigger .= $query.';';
                    $is_trigger = false;
                    $trigger = preg_replace('/(%dqt%)/i', '\"', $trigger);
                    $result[] = preg_replace('/%semi%/i', ';', $trigger);
                } else {
                    $trigger .= $query.';';
                }
            } else {                // 通常のクエリ
                if (preg_match('/CREATE TRIGGER/i', $query)){
                    $is_trigger = true;
                    $trigger = $query.';';
                } else if (!preg_match('/^(BEGIN|END|COMMIT)\s/i', $query)
                    && preg_match('/'.$manips.'/i', $query)){
                    $temp = preg_replace('/(%dqt%)/i', '\"', $query);
                    $result[] = preg_replace('/%semi%/i', ';', $temp);
                }
            } // if ($is_trigger)
        } // for ($row=0; $row<$count; $row++)

        return ($result);
    }

    /********************************************************************
     **                        テーブル作成                            **
     ********************************************************************/
    /**
     * テーブルの作成
     *
     * @access public
     * @return void
     */
    private function _crateQuery()
    {
        $method = '_'.DB_DRIVER.'Query';
        if (USE_SET_NAMES && DB_DRIVER == 'mysql'){
            $method = '_defaultQuery';
        }
        $func = array(&$this, $method);

        $query = file_get_contents(TMP_DIR.'sqls'.DS.'create.sql');
        $queries = $this->_explodeQuery($query);
        foreach ($queries as $query){
            call_user_func($func, $query);
        } // foreach ($queries as $query)
    }

    /**
     * MySQL4.1以上用
     *
     * @access public
     * @param string $query クエリ文字列
     * @return boolean
     */
    private function _defaultQuery($query)
    {
        $this->_objdb->exec($query);
    }

    /**
     * MySQL4.1以下用
     *
     * @access public
     * @param string $query クエリ文字列
     * @return boolean
     */
    private function _mysqlQuery($query)
    {
        $query = str_replace(' default CURRENT_TIMESTAMP', '', $query);
        $query = str_replace('on update CURRENT_TIMESTAMP', '', $query);
        $query = str_replace(' DEFAULT CHARSET=utf8', '', $query);

        $this->_objdb->exec($query);
    }

    /**
     * PostgreSQL用
     *
     * @access public
     * @param string $query クエリ文字列
     * @return boolean
     */
    private function _pgsqlQuery($query)
    {
        $matches = array();
        preg_match('/CREATE TABLE `([\w\_]+)`/', $query, $matches);
        $table = $matches[1];

        $pos = strrpos($query, 'auto_increment');
        if ($pos !== false) {
            $sequence = str_replace(DB_PREFIX, 'seq_', $table);
            $this->_objdb->exec('CREATE SEQUENCE '.$sequence.' start 1 increment 1 maxvalue 9223372036854775807 minvalue 1 cache 1');

            $query = str_replace('NOT NULL auto_increment',
                     "DEFAULT nextval('".$sequence."'::text) NOT NULL", $query);
            $query = str_replace(' AUTO_INCREMENT=1', '', $query);
        }
        $query = str_replace('`'.$table.'`', $table, $query);
        $query = str_replace('ENGINE=MyISAM DEFAULT CHARSET=utf8', '', $query);
        $query = str_replace('`', '"', $query);

        $query = str_replace('int(11)', 'integer', $query);
        $query = str_replace(' unsigned', '', $query);
        $query = str_replace('mediumblob', 'bytea', $query);
        $query = str_replace('blob', 'bytea', $query);
        $query = str_replace('timestamp', 'timestamp without time zone', $query);
        $query = str_replace('datetime', 'timestamp without time zone', $query);
        $query = str_replace(" default '0000-00-00 00:00:00'", '', $query);
        $query = str_replace(" default '0000-00-00'", '', $query);
        $query = str_replace('on update CURRENT_TIMESTAMP', '', $query);
        $query = preg_replace("/default '(\d)'/", 'DEFAULT \1', $query);
        $query = preg_replace('/UNIQUE KEY "[\w_]+"/', 'UNIQUE', $query);

        /* Index用処理 */
        $line = explode("\r\n", $query);
        $queries = array();
        $index = array();
        $count = 1;
        foreach ($line as $row){
            $matches = array();
            if (preg_match('/  KEY "[\w_]+" \(("[\w_,"]+")\)/', $row, $matches)){
                $indexname = str_replace(DB_PREFIX, 'key_', $table).'_'.$count;
                $index[] = 'CREATE INDEX '.$indexname.' ON '.$table.' ('.$matches[1].')';
                $row = preg_replace('/  KEY "([\w_]+)" \("[\w_,"]+"\)/', '', $row);
                $count++;
            } else {
                $queries[] = $row;
            }
        }
        $row = count($queries) -2;
        $queries[$row] = str_replace('),', ')', $queries[$row] );
        $query = implode("\r\n", $queries);
        $this->_objdb->exec($query);

        foreach ($index as $query){
            $this->_objdb->exec($query);
        }
    }

    /**
     * SQLite用
     *
     * @access public
     * @param string $query クエリ文字列
     * @return boolean
     */
    private function _sqliteQuery($query)
    {
        $matches = array();
        preg_match('/CREATE TABLE `([\w\_]+)`/', $query, $matches);
        $table = $matches[1];

        $query = str_replace('`', "'", $query);
        $query = str_replace(' AUTO_INCREMENT=1', '', $query);
        $query = str_replace('ENGINE=MyISAM DEFAULT CHARSET=utf8', '', $query);

        $query = str_replace(' auto_increment', '', $query);
        $query = str_replace('int(11)', 'integer', $query);
        $query = str_replace(' unsigned', '', $query);
        $query = str_replace('mediumblob', 'blob', $query);
        $query = str_replace('datetime', 'timestamp', $query);
        $query = str_replace('on update CURRENT_TIMESTAMP', '', $query);

        $query = preg_replace("/UNIQUE KEY '[\w_]+'/", 'UNIQUE', $query);

        /* Index用処理 */
        $line = explode("\r\n", $query);
        $queries = array();
        $index = array();
        $count = 1;
        foreach ($line as $row){
            $matches = array();
            if (preg_match("/  KEY '[\w_]+' \(('[\w_,']+')\)/", $row, $matches)){
                $indexname = str_replace(DB_PREFIX, 'key_', $table).'_'.$count;
                $index[] = 'CREATE INDEX '.$indexname.' ON '.$table.' ('.$matches[1].')';
                $row = preg_replace("/  KEY '[\w_]+' \('[\w_,']+'\)/", '', $row);
                $count++;
            } else {
                $queries[] = $row;
            }
        }
        $row = count($queries) -2;
        $queries[$row] = str_replace('),', ')', $queries[$row] );
        $query = implode("\r\n", $queries);
        $this->_objdb->exec($query);

        foreach ($index as $query){
            $this->_objdb->exec($query);
        }
    }
} // Controller
?>