Guest User

Connection.php - Fuel OIL

a guest
Apr 12th, 2013
25
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. /**
  3.  * PDO database connection.
  4.  *
  5.  * @package    Fuel/Database
  6.  * @category   Drivers
  7.  * @author     Kohana Team
  8.  * @copyright  (c) 2008-2009 Kohana Team
  9.  * @license    http://kohanaphp.com/license
  10.  */
  11.  
  12. namespace Fuel\Core;
  13.  
  14.  
  15. class Database_PDO_Connection extends \Database_Connection
  16. {
  17.     /**
  18.      * @var  \PDO  Raw server connection
  19.      */
  20.     protected $_connection;
  21.  
  22.     /**
  23.      * @var  string  PDO uses no quoting by default for identifiers
  24.      */
  25.     protected $_identifier = '';
  26.  
  27.     /**
  28.      * @var  bool  Allows transactions
  29.      */
  30.     protected $_in_transaction = false;
  31.  
  32.     /**
  33.      * @var  string  Which kind of DB is used
  34.      */
  35.     public $_db_type = '';
  36.  
  37.     protected function __construct($name, array $config)
  38.     {
  39.         parent::__construct($name, $config);
  40.  
  41.         if (isset($this->_config['identifier']))
  42.         {
  43.             // Allow the identifier to be overloaded per-connection
  44.             $this->_identifier = (string) $this->_config['identifier'];
  45.         }
  46.     }
  47.  
  48.     public function connect()
  49.     {
  50.         if ($this->_connection)
  51.         {
  52.             return;
  53.         }
  54.  
  55.         // Extract the connection parameters, adding required variabels
  56.         extract($this->_config['connection'] + array(
  57.             'dsn'        => 'dbname=fuel;mysql:host=localhost',
  58.             'username'   => 'jack',
  59.             'password'   => 'password',
  60.             'persistent' => true,
  61.             'compress'   => false,
  62.         ));
  63.  
  64.         // Clear the connection parameters for security
  65.         $this->_config['connection'] = array();
  66.  
  67.         // determine db type
  68.         $_dsn_find_collon = strpos($dsn, ':');
  69.         $this->_db_type = $_dsn_find_collon ? substr($dsn, 0, $_dsn_find_collon) : null;
  70.  
  71.         // Force PDO to use exceptions for all errors
  72.         $attrs = array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION);
  73.  
  74.         if ( ! empty($persistent))
  75.         {
  76.             // Make the connection persistent
  77.             $attrs[\PDO::ATTR_PERSISTENT] = true;
  78.         }
  79.  
  80.         if (in_array(strtolower($this->_db_type), array('mysql', 'mysqli')) and $compress)
  81.         {
  82.             // Use client compression with mysql or mysqli (doesn't work with mysqlnd)
  83.             $attrs[\PDO::MYSQL_ATTR_COMPRESS] = true;
  84.         }
  85.  
  86.         try
  87.         {
  88.             // Create a new PDO connection
  89.             $this->_connection = new \PDO($dsn, $username, $password, $attrs);
  90.         }
  91.         catch (\PDOException $e)
  92.         {
  93.             $error_code = is_numeric($e->getCode()) ? $e->getCode() : 0;
  94.             throw new \Database_Exception($e->getMessage(), $error_code, $e);
  95.         }
  96.  
  97.         if ( ! empty($this->_config['charset']))
  98.         {
  99.             // Set Charset for SQL Server connection
  100.             if (strtolower($this->driver_name()) == 'sqlsrv')
  101.             {
  102.                 $this->_connection->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_SYSTEM);
  103.             }
  104.             else
  105.             {
  106.                 // Set the character set
  107.                 $this->set_charset($this->_config['charset']);
  108.             }
  109.         }
  110.     }
  111.  
  112.     public function disconnect()
  113.     {
  114.         // Destroy the PDO object
  115.         $this->_connection = null;
  116.  
  117.         return true;
  118.     }
  119.  
  120.     /**
  121.      * Get the current PDO Driver name
  122.      * @return string
  123.      */
  124.     public function driver_name()
  125.     {
  126.         return $this->_connection->getAttribute(\PDO::ATTR_DRIVER_NAME);
  127.     }
  128.  
  129.     public function set_charset($charset)
  130.     {
  131.         // Make sure the database is connected
  132.         $this->_connection or $this->connect();
  133.  
  134.         // Execute a raw SET NAMES query
  135.         $this->_connection->exec('SET NAMES '.$this->quote($charset));
  136.     }
  137.  
  138.     public function query($type, $sql, $as_object)
  139.     {
  140.         // Make sure the database is connected
  141.         $this->_connection or $this->connect();
  142.  
  143.         if ( ! empty($this->_config['profiling']))
  144.         {
  145.             // Benchmark this query for the current instance
  146.             $benchmark = \Profiler::start("Database ({$this->_instance})", $sql);
  147.         }
  148.  
  149.         // run the query. if the connection is lost, try 3 times to reconnect
  150.         $attempts = 3;
  151.  
  152.         do
  153.         {
  154.             try
  155.             {
  156.                 $result = $this->_connection->query($sql);
  157.                 break;
  158.             }
  159.             catch (\Exception $e)
  160.             {
  161.                 if (strpos($e->getMessage(), '2006 MySQL') !== false)
  162.                 {
  163.                     $this->connect();
  164.                 }
  165.                 else
  166.                 {
  167.                     if (isset($benchmark))
  168.                     {
  169.                         // This benchmark is worthless
  170.                         \Profiler::delete($benchmark);
  171.                     }
  172.  
  173.                     // Convert the exception in a database exception
  174.                     $error_code = is_numeric($e->getCode()) ? $e->getCode() : 0;
  175.                     throw new \Database_Exception($e->getMessage().' with query: "'.$sql.'"', $error_code, $e);
  176.                 }
  177.             }
  178.         }
  179.         while ($attempts-- > 0);
  180.  
  181.         if (isset($benchmark))
  182.         {
  183.             \Profiler::stop($benchmark);
  184.         }
  185.  
  186.         // Set the last query
  187.         $this->last_query = $sql;
  188.  
  189.         if ($type === \DB::SELECT)
  190.         {
  191.             // Convert the result into an array, as PDOStatement::rowCount is not reliable
  192.             if ($as_object === false)
  193.             {
  194.                 $result = $result->fetchAll(\PDO::FETCH_ASSOC);
  195.             }
  196.             elseif (is_string($as_object))
  197.             {
  198.                 $result = $result->fetchAll(\PDO::FETCH_CLASS, $as_object);
  199.             }
  200.             else
  201.             {
  202.                 $result = $result->fetchAll(\PDO::FETCH_CLASS, 'stdClass');
  203.             }
  204.  
  205.  
  206.             // Return an iterator of results
  207.             return new \Database_Result_Cached($result, $sql, $as_object);
  208.         }
  209.         elseif ($type === \DB::INSERT)
  210.         {
  211.             // Return a list of insert id and rows created
  212.             return array(
  213.                 $this->_connection->lastInsertId(),
  214.                 $result->rowCount(),
  215.             );
  216.         }
  217.         else
  218.         {
  219.             // Return the number of rows affected
  220.             return $result->errorCode() === '00000' ? $result->rowCount() : -1;
  221.         }
  222.     }
  223.  
  224.     public function list_tables($like = null)
  225.     {
  226.         throw new \FuelException('Database method '.__METHOD__.' is not supported by '.__CLASS__);
  227.     }
  228.  
  229.     public function list_columns($table, $like = null)
  230.     {
  231.         $this->_connection or $this->connect();
  232.         $q = $this->_connection->prepare("DESCRIBE ".$table);
  233.         $q->execute();
  234.         $result  = $q->fetchAll();
  235.         $count   = 0;
  236.         $columns = array();
  237.         ! is_null($like) and $like = str_replace('%', '.*', $like);
  238.         foreach ($result as $row)
  239.         {
  240.             if ( ! is_null($like) and ! preg_match('#'.$like.'#', $row['Field'])) continue;
  241.             list($type, $length) = $this->_parse_type($row['Type']);
  242.  
  243.             $column = $this->datatype($type);
  244.  
  245.             $column['name']             = $row['Field'];
  246.             $column['default']          = $row['Default'];
  247.             $column['data_type']        = $type;
  248.             $column['null']             = ($row['Null'] == 'YES');
  249.             $column['ordinal_position'] = ++$count;
  250.             switch ($column['type'])
  251.             {
  252.                 case 'float':
  253.                     if (isset($length))
  254.                     {
  255.                         list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length);
  256.                     }
  257.                     break;
  258.                 case 'int':
  259.                     if (isset($length))
  260.                     {
  261.                         // MySQL attribute
  262.                         $column['display'] = $length;
  263.                     }
  264.                     break;
  265.                 case 'string':
  266.                     switch ($column['data_type'])
  267.                     {
  268.                         case 'binary':
  269.                         case 'varbinary':
  270.                             $column['character_maximum_length'] = $length;
  271.                             break;
  272.  
  273.                         case 'char':
  274.                         case 'varchar':
  275.                             $column['character_maximum_length'] = $length;
  276.                         case 'text':
  277.                         case 'tinytext':
  278.                         case 'mediumtext':
  279.                         case 'longtext':
  280.                             $column['collation_name'] = isset($row['Collation']) ? $row['Collation'] : null;
  281.                             break;
  282.  
  283.                         case 'enum':
  284.                         case 'set':
  285.                             $column['collation_name'] = isset($row['Collation']) ? $row['Collation'] : null;
  286.                             $column['options']        = explode('\',\'', substr($length, 1, - 1));
  287.                             break;
  288.                     }
  289.                     break;
  290.             }
  291.  
  292.             // MySQL attributes
  293.             $column['comment']    = isset($row['Comment']) ? $row['Comment'] : null;
  294.             $column['extra']      = $row['Extra'];
  295.             $column['key']        = $row['Key'];
  296.             $column['privileges'] = isset($row['Privileges']) ? $row['Privileges'] : null;
  297.  
  298.             $columns[$row['Field']] = $column;
  299.         }
  300.  
  301.         return $columns;
  302.     }
  303.  
  304.     public function datatype($type)
  305.     {
  306.         // try to determine the datatype
  307.         $datatype = parent::datatype($type);
  308.  
  309.         // if not an ANSI database, assume it's string
  310.         return empty($datatype) ? array('type' => 'string') : $datatype;
  311.     }
  312.  
  313.     public function escape($value)
  314.     {
  315.         // Make sure the database is connected
  316.         $this->_connection or $this->connect();
  317.  
  318.         $result = $this->_connection->quote($value);
  319.         // poor-mans workaround for the fact that not all drivers implement quote()
  320.         if (empty($result))
  321.         {
  322.             $result = "'".str_replace("'", "''", $value)."'";
  323.         }
  324.         return $result;
  325.     }
  326.  
  327.     public function error_info()
  328.     {
  329.         return $this->_connection->errorInfo();
  330.     }
  331.  
  332.     public function in_transaction()
  333.     {
  334.         return $this->_in_transaction;
  335.     }
  336.  
  337.     public function start_transaction()
  338.     {
  339.         $this->_connection or $this->connect();
  340.         $this->_in_transaction = true;
  341.         return $this->_connection->beginTransaction();
  342.     }
  343.  
  344.     public function commit_transaction()
  345.     {
  346.         $this->_in_transaction = false;
  347.         return $this->_connection->commit();
  348.     }
  349.  
  350.     public function rollback_transaction()
  351.     {
  352.         $this->_in_transaction = false;
  353.         return $this->_connection->rollBack();
  354.     }
  355.  
  356. }
RAW Paste Data