<?php
/*
* 项目: iOrange(橘子)
* 作者: 离家出走(yzxh24)
* Email: yzxh24@gmail.com
* 主页: www.iorange.cc
*/
/* vim: set ts=4 sw=4: */
 class Db
 {
     private $conn = null;
     
     private $resource = null;
     
     private $queryString = '';
     
     private $queryCount = 0;
     
     private $sqlTemplate = array('select' => 'SELECT ', 'update' => 'UPDATE ', 'insert' => 'INSERT INTO ', 'delete' => 'DELETE FROM ');
     
     private static $selfObj = null;
     
     private function __construct()
     {
         $configFile = ROOT_PATH . 'cache/Db.conf.php';
         if (!is_file($configFile))
         {
             exit;
         }
         $config = require_once $configFile;
         $this->conn = mysql_connect($config['host'], $config['user'], $config['password']) or trigger_error(mysql_error());
         mysql_query("SET NAMES utf8");
         mysql_select_db($config['database']) or trigger_error(mysql_error());
     }

     static public function getInstance()
     {
         if (is_null(self::$selfObj))
         {
             $className = __CLASS__;
             self::$selfObj = new $className;
         }
         
         return self::$selfObj;
     }
     
     public function query($sql)
     {
         return $this->_exec($sql);
     }
     
     public function getArr ($result)
     {
         return mysql_fetch_array($result, MYSQL_ASSOC);
     }
     
     public function select($fields = '*')
     {
         if (is_string($fields) && '*' == $fields)
         {
            $this->queryString = $this->sqlTemplate['select'] . $fields;
         }
         else if (is_array($fields))
         {
             foreach ($fields as $value)
             {
                 $keys[] = $this->addSpecialChar($value);
             }
             $this->queryString = $this->sqlTemplate['select'] . implode(',', $keys);
         }
         
         return $this;
     }
     
     public function find($one = false)
     {
         if (empty($this->queryString))
         {
             throw new Exception("Empty SQL");
         }

         $result = $this->_exec($this->queryString);
         if ($one)
         {
             $return = mysql_fetch_array($result,MYSQL_ASSOC);
         }
         else
         {
             while ($row = mysql_fetch_array($result,MYSQL_ASSOC))
             {
                 $return[] = $row;
             }
         }
         
         return $return;
     }
     
     public function from($table)
     {
         if (is_string($table))
         {
             $table = $this->addSpecialChar($table);
         }
         else
         {
             foreach ($table as $value)
             {
                 $tables[] = $this->addSpecialChar($value);
             }
             $table = implode(',', $tables);
         }
         $this->queryString .= " FROM $table ";
         
         return $this;
     }
     
     public function where($conditions)
     {
         if (is_array($conditions))
         {
             foreach ($conditions as $key => $value)
             {
                 if (is_array($value))
                 {
                     if (!empty($value[2]))
                     {
                         $operator = $value[2];
                     }
                     else
                     {
                         $operator = '=';
                     }
                     $where[] = '' . $this->addSpecialChar($value[0]) . " $operator '" . $value[1] . "'";
                 }
                 else
                 {
                     $where[] = '' . $key . " = '" . $value . "'";
                 }
             }
             $condition = implode(' AND ', $where);
         }
         else if (is_string($conditions))
         {
             $condition = $conditions;
         }
         $this->queryString .= ' WHERE ' . $condition;
         
         return $this;
     }
     
     public function innerjoin($table, $conditions)
     {
         $this->queryString .= ' INNER JOIN ' . $this->addSpecialChar($table) . ' ON ' . $conditions;
         
         return $this;
     }
     
     public function leftjoin($table, $conditions)
     {
         $this->queryString .= ' LEFT JOIN ' . $this->addSpecialChar($table) . ' ON ' . $conditions;
         
         return $this;
     }
     
     public function rightjoin($table, $conditions)
     {
         $this->queryString .= ' RIGHT JOIN ' . $this->addSpecialChar($table) . ' ON ' . $conditions;
         
         return $this;
     }
     
     public function asc($field)
     {
         $this->queryString .= ' ORDER BY ' . $this->addSpecialChar($field) . ' ASC';

		 return $this;
     }
     
     public function desc($field)
     {
         $this->queryString .= ' ORDER BY ' . $this->addSpecialChar($field) . ' DESC';
         
         return $this;
     }
     
     public function groupby($group)
     {
         $this->queryString .= ' GORUP BY ' . $this->addSpecialChar($group);
         
         return $this;
     }
     
     public function limit($start, $end = null)
     {
         $this->queryString .= ' LIMIT ' . $start;
         if (!is_null($end))
         {
             $this->queryString .= ',' . $end;
         }
         
         return $this;
     }
     
     public function insert($table)
     {
         $this->queryString = $this->sqlTemplate['insert'] . $this->addSpecialChar($table) . ' SET ';
         
         return $this;
     }
     
     public function delete($table)
     {
         $this->queryString = $this->sqlTemplate['delete'] . $this->addSpecialChar($table);
         
         return $this;
     }
     
     public function update($table)
     {
         $this->queryString = $this->sqlTemplate['update'] . $this->addSpecialChar($table) . ' SET ';
         
         return $this;
     }
     
     public function incrField($fields)
     {
         foreach ($fields as $key => $value)
         {
             $tmp[] = $this->addSpecialChar($key) . ' = ' . $this->addSpecialChar($key) . ' + ' . $value;
         }
         $sql = implode(',', $tmp);
         $this->queryString .= $sql;
         
         return $this;
     }
     
     public function decrField($fields)
     {
         foreach ($fields as $key => $value)
         {
             $tmp[] = $this->addSpecialChar($key) . ' = ' . $this->addSpecialChar($key) . ' - ' . $value;
         }
         $sql = implode(',', $tmp);
         $this->queryString .= $sql;
         
         return $this;
     }
     
     public function value($values)
     {
         if (is_array($values))
         {
             foreach ($values as $key => $value)
             {
                 $v[] = $this->addSpecialChar($key) . " = '" . $value . "'";
             }
             $value = implode(', ', $v);
         }
         else if (is_string($values))
         {
             $value = $values;
         }
         $this->queryString .= $value;
         
         return $this;
     }

     public function getValue($sql)
     {
         $result = mysql_fetch_row(mysql_query($sql));

         return empty($result) ? '' : $result[0];
     }
     
     public function getInsertId()
     {
         return mysql_insert_id();
     }
     
     public function getLastSql()
     {
         return $this->queryString;
     }

     public function affectedRows()
     {
         return mysql_affected_rows($this->conn);
     }
     
     public function version ()
     {
         return mysql_get_server_info($this->conn);
     }
     
     public function setQueryString($s)
     {
         $this->queryString = $s;
 
         return $this;
     }
     
     private function _exec($sql)
     {
         $this->resource = mysql_query($sql);
         $this->queryCount += 1;
         
         return $this->resource;
     }
     
     public function getQueryCount()
     {
         return $this->queryCount;
     }
     
     public function q()
     {
         mysql_query($this->queryString);
     }
     
     public function getCount ($sql)
     {
         return @mysql_num_rows(mysql_query($sql));
     }
     
     public function free()
     {
         mysql_free_result($this->resource);
     }
     
     private function addSpecialChar(&$value) 
     {    
         if( '*' == $value ||  false !== strpos($value,'(') || false !== strpos($value,'.') || false !== strpos($value,'`')) 
         {
             //如果包含* 或者 使用了sql方法 则不作处理
         }
         elseif(false === strpos($value,'`') ) 
         {
             $value = '`'.trim($value).'`';
         }
         
         return $value;
    }
 }
