<?php
/**
 * DatabaseException class
 *
 * LICENSE: This source file is subject to GNU GENERAL PUBLIC LICENSE Version 3
 * http://www.gnu.org/licenses/gpl-3.0.txt.
 *
 * @package    LabbitBox
 * @subpackage DB
 * @copyright  2010 LabbitBox Development Team.
 * @license    GPL v3 http://www.gnu.org/licenses/gpl-3.0.txt
 * @author     minotaur <minotaur@labbitbox.org>
 * @version    v0.1
 * @since      -
 * @link       http://labbitbox.org/
 * @see        http://labbitbox.org/
 */
class DB_Exception extends Exception{

    protected $_srcSql     = NULL;
    protected $_errMessage = NULL;
    protected $_errCode    = NULL;
    protected $_prmV       = NULL;
    protected $_prmR       = NULL;
    protected $_sql        = NULL;
    protected $_reportTo   = NULL;
    protected $_reported   = FALSE;


    /**
     * constructor
     *
     * @param string  $errMessage    Error Message by each DMBS
     * @param integer $errCode       Error code by each DBMS
     * @param string  $srcSql        SQL string before replacement with params
     * @param mixed   $prmV          SQL parameters for validation
     * @param mixed   $prmR          SQL parameters for raw(non-validation)
     * @param string  $sql           replaced SQL string
     * @param integer $transactionId TransactionId in DB Class
     * @param string  $reportTo      Default:NULL FilePath or eMail
     */
    public function __construct($errMessage, $errCode, $srcSql, $prmV, $prmR, $sql, $transactionId, $reportTo=NULL){
        parent::__construct($errMessage, $errCode);
        $this->_errMessage = $errMessage;
        $this->_errCode    = $errCode;
        $this->_srcSql     = $srcSql;
        $this->_prmV       = $prmV;
        $this->_prmR       = $prmR;
        $this->_sql        = $sql;
        $this->_transactionId = $transactionId;
        $this->_reportTo   = $reportTo;
    }


    
    /**
     * Destructor
     */
    public function __destruct(){
        $this->report($this->_reportTo);
    }



    /**
     * get error code
     */
    public function getErrorCode(){
        return $this->_errCode;
    }



    /**
     * get error message
     */
    public function getErrorMessage(){
        return $this->_errMessage;
    }



    /**
     * get detailed error message
     *
     * @return string detailed error message
     */
    public function getDetail(){
        $s    = "\n\n--------------------------------\n";
        $msg  = NULL;
        $msg[]= "LabbitBox DB ErrorReport [".__FILE__."]";
        $msg[]= "ErrorCode: ".$this->_errCode;
        $msg[]= "ErrorMessage:\n".$this->_errMessage;
        $msg[]= "SQL(source):\n".$this->_srcSql;
        $msg[]= "SQL(destination):\n".$this->_sql;
        $msg[]= "ValidatedParams:\n".print_r($this->_prmV, TRUE);
        $msg[]= "RawParams:\n".print_r($this->_prmR, TRUE);
        $msg[]= "Transaction: ".$this->_transactionId;
        return implode($s, $msg);
    }



    /**
     * Report
     *
     * @param string $reportTo report
     *
     * @return boolean always TRUE
     */
    public function report($reportTo=NULL){
        if($this->_reported===FALSE){
            if($reportTo===NULL) $reportTo = $this->_reportTo;
            if($reportTo===NULL){
                // output to STDOUT and die.
                die($this->getDetail());
            }else{
                if(strpos($reportTo, '@')===FALSE){
                    // write log to file
                    file_put_contents($reportTo, $this->getDetail(), FILE_APPEND);
                }else{
                    // mail to specified address
                    require_once(dirname(__FILE__).'/../EMail.php');
                    if($_SERVER['SERVER_ADMIN']){
                        $from = $_SERVER['SERVER_ADMIN'];
                    }else{
                        $from = 'labbitbox@'.$_SERVER['HOSTNAME'];
                    }
                    $mail = new EMail($reportTo, $from, "LabbitBox DB ErrorReport [".__FILE__."]");
                    $mail->send($this->getDetail());
                }
            }
        }
        $this->_reported = TRUE;
    }



}
?>
