<?php
/* SVN FILE: $Id: DB.php 436 2008-05-20 08:48: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/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 436 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-20 17:48:56 +0900 (火, 20 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */

/**
 * BLOB_dbクラス
 *
 * @category        Binary Large OBject
 * @package         hitSuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 436 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-20 17:48:56 +0900 (火, 20 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */
class BLOB_Db extends BLOB_Common
{
    /**
     * データベース接続オブジェクト
     * @access private
     * @var object
     */
    protected $objdb = null;

    /**
     * ステートメントオブジェクト
     * @access private
     * @var object
     */
    protected $objstmt = null;

    /**
     * コンストラクタ
     *
     * @access public
     * @param string $dsn
     * @return void
     */
    public function __construct($dsn=BLOB_DSN)
    {
        $this->objdb = new PDO($dsn, DB_USER, DB_PASSWORD);
    }

    /**
     * 取得キーの変更
     *
     * @access public
     * @param string $oldname
     * @param string $newname
     * @return boolean
     */
    public function rename($oldname, $newname)
    {
        $sql = 
            'UPDATE '.RKT_TBL_BLOB.' '.
            'SET name = :name,'.
                'uid = :uid,'.
                'gid = :gid,'.
                'origin = :new_origin '.
            'WHERE origin = :old_origin';
        $this->objstmt = $this->objdb->prepare($sql);

        $this->name = basename($newname);
        $old_origin = sha1($oldname);
        $new_origin = sha1($newname);

        $this->objstmt->bindParam(':name',       $this->name, PDO::PARAM_STR);
        $this->objstmt->bindParam(':uid',        $this->uid,  PDO::PARAM_INT);
        $this->objstmt->bindParam(':gid',        $this->gid,  PDO::PARAM_INT);
        $this->objstmt->bindParam(':new_origin', $new_origin, PDO::PARAM_STR);
        $this->objstmt->bindParam(':old_origin', $old_origin, PDO::PARAM_STR);

        return $this->objstmt->execute();
    }

    /**
     * 対象データのコピー
     *
     * @access public
     * @param string $source
     * @param string $dest
     * @return boolean
     */
    public function copy($source, $dest)
    {
        if (!$this->load($source)){
            return false;
        }
        return $this->save($dest);
    }

    /**
     * 対象データの保存
     *
     * @access public
     * @param string $filename
     * @return boolean
     */
    public function save($filename)
    {
        $this->origin    = sha1($filename);
        $this->name      = basename($filename);
        $this->mime_type = $this->_getMimeType($filename);
        $modified        = date('Y-m-d H:i:s');
        
        $this->_setStatement();        

        $this->objstmt->bindParam(':modified',    $modified,        PDO::PARAM_STR);
        $this->objstmt->bindParam(':origin',      $this->origin,    PDO::PARAM_STR);
        $this->objstmt->bindParam(':name',        $this->name,      PDO::PARAM_STR);
        $this->objstmt->bindParam(':mime_type',   $this->mime_type, PDO::PARAM_STR);
        $this->objstmt->bindParam(':uid',         $this->uid,       PDO::PARAM_INT);
        $this->objstmt->bindParam(':gid',         $this->gid,       PDO::PARAM_INT);
        $this->objstmt->bindParam(':size',        $this->size,      PDO::PARAM_INT);
        $this->objstmt->bindParam(':buffer',      $this->buffer,    PDO::PARAM_LOB);

        return $this->objstmt->execute();
    }

    /**
     * 対象データの読み込み
     *
     * @access public
     * @param string $filename
     * @return boolean
     */
    public function load($filename)
    {
        $this->origin = sha1($filename);
        $sql=
            'SELECT name,mime_type,size,buffer'.
            ' FROM '.RKT_TBL_BLOB.' WHERE origin = :origin';
        $this->objstmt = $this->objdb->prepare($sql);
        $this->objstmt->execute(array(':origin'=> $this->origin));
        $result = $this->objstmt->fetch(PDO::FETCH_ASSOC);
        $this->objstmt->closeCursor();

        if (empty($result)){
            $this->name      = '';
            $this->mime_type = '';
            $this->size      = 0;
            $this->buffer    = '';
            return false;
        }

        $this->name      = $result['name'];
        $this->mime_type = $result['mime_type'];
        $this->size      = $result['size'];

        $func = array(
            'mysql'=>  '_throughBuffer',
            'pgsql'=>  '_dumpBuffer',
            'sqlite'=> '_throughBuffer',
        );
        $driver = $this->objdb->getAttribute(PDO::ATTR_DRIVER_NAME);
        call_user_func(array(&$this, $func[$driver]), $result['buffer']);

        $this->size = empty($this->size)? strlen($this->buffer):$this->size;

        return true;
    }

    /**
     * 指定ファイルの削除処理
     *
     * @access private
     * @param array $values
     * @return boolean
     */
    public function unlink($filename)
    {
        $origin = sha1($filename);
        $sql = 
            'DELETE FROM '.RKT_TBL_BLOB.' '.
            'WHERE origin = '.$this->objdb->quote($origin);
        return $this->objdb->exec($sql);
    }

    /**
     * 削除処理
     *
     * @access private
     * @param array $params
     * @return boolean
     */
    public function delete($key)
    {
        if (empty($this->$key)){
            return false;
        }
        $sql = 
            'DELETE FROM '.RKT_TBL_BLOB.' '.
            'WHERE '.$key.' = '.$this->objdb->quote($this->$key);
        return $this->objdb->exec($sql);
    }

    /**
     * ステートメント設定
     *
     * @access private
     * @return boolean
     */
    private function _setStatement()
    {
        $sql=
            'SELECT id FROM '.RKT_TBL_BLOB.' WHERE origin = :origin';
        $this->objstmt = $this->objdb->prepare($sql); 
        $this->objstmt->execute(array(':origin'=> $this->origin));
        $result = $this->objstmt->fetch(PDO::FETCH_ASSOC);
        $this->objstmt->closeCursor();
        
        if (empty($result['id'])){
            $this->_setInsert();
        } else {
            $this->_setUpdate();
        }
    }

    /**
     * 挿入処理設定
     *
     * @access private
     * @return boolean
     */
    private function _setInsert()
    {
        $sql =
            'INSERT INTO '.
                RKT_TBL_BLOB.' ('.
                    'modified,'.
                    'regist_date,'.
                    'origin,'.
                    'name,'.
                    'mime_type,'.
                    'uid,'.
                    'gid,'.
                    'size,'.
                    'buffer'.
                ') VALUES ('.
                    ':modified,'.
                    ':modified,'.
                    ':origin,'.
                    ':name,'.
                    ':mime_type,'.
                    ':uid,'.
                    ':gid,'.
                    ':size,'.
                    ':buffer'.
                ')';
        $this->objstmt = $this->objdb->prepare($sql);
    }

    /**
     * 更新処理設定
     *
     * @access private
     * @return boolean
     */
    private function _setUpdate()
    {
        $sql = 
            'UPDATE '.
                RKT_TBL_BLOB.' '.
            'SET '.
                'modified = :modified,'.
                'name = :name,'.
                'mime_type = :mime_type,'.
                'uid = :uid,'.
                'gid = :gid,'.
                'size = :size,'.
                'buffer = :buffer '.
            'WHERE '.
                'origin = :origin';
        $this->objstmt = $this->objdb->prepare($sql);
    }

    /**
     * バッファー内容を保存
     *
     * @access private
     * @param resource $resource
     * @return void
     */
    private function _throughBuffer($buffer)
    {
        $this->buffer = $buffer;
    }

    /**
     * リソースのダンプ
     *
     * @access private
     * @param resource $resource
     * @return void
     */
    private function _dumpBuffer($resource)
    {
        if (!is_resource($resource)){
            $this->buffer = $resource;
            return ;
        }

        ob_start();
        fpassthru($resource);
        $this->buffer = ob_get_contents();
        ob_end_clean();
    }
} // BLOB_dbの終了
?>