This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jun 18th, 2012  |  syntax: PHP  |  size: 17.81 KB  |  views: 154  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * CodeIgniter
  4.  *
  5.  * An open source application development framework for PHP 5.1.6 or newer
  6.  *
  7.  * @package             CodeIgniter
  8.  * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
  9.  * @license             http://codeigniter.com/user_guide/license.html
  10.  * @author              EllisLab Dev Team
  11.  * @link                http://codeigniter.com
  12.  * @since               Version 2.1.0
  13.  * @filesource
  14.  */
  15.  
  16. // ------------------------------------------------------------------------
  17.  
  18. /**
  19.  * PDO Database Adapter Class
  20.  *
  21.  * Note: _DB is an extender class that the app controller
  22.  * creates dynamically based on whether the active record
  23.  * class is being used or not.
  24.  *
  25.  * @package             CodeIgniter
  26.  * @subpackage  Drivers
  27.  * @category    Database
  28.  * @author              EllisLab Dev Team
  29.  * @link                http://codeigniter.com/user_guide/database/
  30.  */
  31. class CI_DB_pdo_driver extends CI_DB {
  32.  
  33.         var $dbdriver = 'pdo';
  34.  
  35.         // the character used to excape - not necessary for PDO
  36.         var $_escape_char = '';
  37.         var $_like_escape_str;
  38.         var $_like_escape_chr;
  39.        
  40.  
  41.         /**
  42.          * The syntax to count rows is slightly different across different
  43.          * database engines, so this string appears in each driver and is
  44.          * used for the count_all() and count_all_results() functions.
  45.          */
  46.         var $_count_string = "SELECT COUNT(*) AS ";
  47.         var $_random_keyword;
  48.        
  49.         var $options = array();
  50.  
  51.         function __construct($params)
  52.         {
  53.                 parent::__construct($params);
  54.                
  55.                 // clause and character used for LIKE escape sequences
  56.                 if (strpos($this->hostname, 'mysql') !== FALSE)
  57.                 {
  58.                         $this->_like_escape_str = '';
  59.                         $this->_like_escape_chr = '';
  60.                        
  61.                         //Prior to this version, the charset can't be set in the dsn
  62.                         if(is_php('5.3.6'))
  63.                         {
  64.                                 $this->hostname .= ";charset={$this->char_set}";
  65.                         }
  66.                        
  67.                         //Set the charset with the connection options
  68.                         $this->options['PDO::MYSQL_ATTR_INIT_COMMAND'] = "SET NAMES {$this->char_set}";
  69.                 }
  70.                 else if (strpos($this->hostname, 'odbc') !== FALSE)
  71.                 {
  72.                         $this->_like_escape_str = " {escape '%s'} ";
  73.                         $this->_like_escape_chr = '!';
  74.                 }
  75.                 else
  76.                 {
  77.                         $this->_like_escape_str = " ESCAPE '%s' ";
  78.                         $this->_like_escape_chr = '!';
  79.                 }
  80.                
  81.                 $this->hostname = 'mysql:dbname='.$this->database.';host='.$this->hostname;
  82.  
  83.                 $this->trans_enabled = FALSE;
  84.  
  85.                 $this->_random_keyword = ' RND('.time().')'; // database specific random keyword
  86.         }
  87.  
  88.         /**
  89.          * Non-persistent database connection
  90.          *
  91.          * @access      private called by the base class
  92.          * @return      resource
  93.          */
  94.         function db_connect()
  95.         {
  96.                 $this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
  97.                
  98.                 return new PDO($this->hostname, $this->username, $this->password, $this->options);
  99.         }
  100.  
  101.         // --------------------------------------------------------------------
  102.  
  103.         /**
  104.          * Persistent database connection
  105.          *
  106.          * @access      private called by the base class
  107.          * @return      resource
  108.          */
  109.         function db_pconnect()
  110.         {
  111.                 $this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
  112.                 $this->options['PDO::ATTR_PERSISTENT'] = TRUE;
  113.        
  114.                 return new PDO($this->hostname, $this->username, $this->password, $this->options);
  115.         }
  116.  
  117.         // --------------------------------------------------------------------
  118.  
  119.         /**
  120.          * Reconnect
  121.          *
  122.          * Keep / reestablish the db connection if no queries have been
  123.          * sent for a length of time exceeding the server's idle timeout
  124.          *
  125.          * @access      public
  126.          * @return      void
  127.          */
  128.         function reconnect()
  129.         {
  130.                 if ($this->db->db_debug)
  131.                 {
  132.                         return $this->db->display_error('db_unsuported_feature');
  133.                 }
  134.                 return FALSE;
  135.         }
  136.  
  137.         // --------------------------------------------------------------------
  138.  
  139.         /**
  140.          * Select the database
  141.          *
  142.          * @access      private called by the base class
  143.          * @return      resource
  144.          */
  145.         function db_select()
  146.         {
  147.                 // Not needed for PDO
  148.                 return TRUE;
  149.         }
  150.  
  151.         // --------------------------------------------------------------------
  152.  
  153.         /**
  154.          * Set client character set
  155.          *
  156.          * @access      public
  157.          * @param       string
  158.          * @param       string
  159.          * @return      resource
  160.          */
  161.         function db_set_charset($charset, $collation)
  162.         {
  163.                 // @todo - add support if needed
  164.                 return TRUE;
  165.         }
  166.  
  167.         // --------------------------------------------------------------------
  168.  
  169.         /**
  170.          * Version number query string
  171.          *
  172.          * @access      public
  173.          * @return      string
  174.          */
  175.         function _version()
  176.         {
  177.                 return $this->conn_id->getAttribute(PDO::ATTR_CLIENT_VERSION);
  178.         }
  179.  
  180.         // --------------------------------------------------------------------
  181.  
  182.         /**
  183.          * Execute the query
  184.          *
  185.          * @access      private called by the base class
  186.          * @param       string  an SQL query
  187.          * @return      object
  188.          */
  189.         function _execute($sql)
  190.         {
  191.                 $sql = $this->_prep_query($sql);
  192.                 $result_id = $this->conn_id->query($sql);
  193.                
  194.                 if (is_object($result_id))
  195.                 {
  196.                         $this->affect_rows = $result_id->rowCount();
  197.                 }
  198.                 else
  199.                 {
  200.                         $this->affect_rows = 0;
  201.                 }
  202.                
  203.                 return $result_id;
  204.         }
  205.  
  206.         // --------------------------------------------------------------------
  207.  
  208.         /**
  209.          * Prep the query
  210.          *
  211.          * If needed, each database adapter can prep the query string
  212.          *
  213.          * @access      private called by execute()
  214.          * @param       string  an SQL query
  215.          * @return      string
  216.          */
  217.         function _prep_query($sql)
  218.         {
  219.                 return $sql;
  220.         }
  221.  
  222.         // --------------------------------------------------------------------
  223.  
  224.         /**
  225.          * Begin Transaction
  226.          *
  227.          * @access      public
  228.          * @return      bool
  229.          */
  230.         function trans_begin($test_mode = FALSE)
  231.         {
  232.                 if ( ! $this->trans_enabled)
  233.                 {
  234.                         return TRUE;
  235.                 }
  236.  
  237.                 // When transactions are nested we only begin/commit/rollback the outermost ones
  238.                 if ($this->_trans_depth > 0)
  239.                 {
  240.                         return TRUE;
  241.                 }
  242.  
  243.                 // Reset the transaction failure flag.
  244.                 // If the $test_mode flag is set to TRUE transactions will be rolled back
  245.                 // even if the queries produce a successful result.
  246.                 $this->_trans_failure = (bool) ($test_mode === TRUE);
  247.  
  248.                 return $this->conn_id->beginTransaction();
  249.         }
  250.  
  251.         // --------------------------------------------------------------------
  252.  
  253.         /**
  254.          * Commit Transaction
  255.          *
  256.          * @access      public
  257.          * @return      bool
  258.          */
  259.         function trans_commit()
  260.         {
  261.                 if ( ! $this->trans_enabled)
  262.                 {
  263.                         return TRUE;
  264.                 }
  265.  
  266.                 // When transactions are nested we only begin/commit/rollback the outermost ones
  267.                 if ($this->_trans_depth > 0)
  268.                 {
  269.                         return TRUE;
  270.                 }
  271.  
  272.                 $ret = $this->conn->commit();
  273.                 return $ret;
  274.         }
  275.  
  276.         // --------------------------------------------------------------------
  277.  
  278.         /**
  279.          * Rollback Transaction
  280.          *
  281.          * @access      public
  282.          * @return      bool
  283.          */
  284.         function trans_rollback()
  285.         {
  286.                 if ( ! $this->trans_enabled)
  287.                 {
  288.                         return TRUE;
  289.                 }
  290.  
  291.                 // When transactions are nested we only begin/commit/rollback the outermost ones
  292.                 if ($this->_trans_depth > 0)
  293.                 {
  294.                         return TRUE;
  295.                 }
  296.  
  297.                 $ret = $this->conn_id->rollBack();
  298.                 return $ret;
  299.         }
  300.  
  301.         // --------------------------------------------------------------------
  302.  
  303.         /**
  304.          * Escape String
  305.          *
  306.          * @access      public
  307.          * @param       string
  308.          * @param       bool    whether or not the string will be used in a LIKE condition
  309.          * @return      string
  310.          */
  311.         function escape_str($str, $like = FALSE)
  312.         {
  313.                 if (is_array($str))
  314.                 {
  315.                         foreach ($str as $key => $val)
  316.                         {
  317.                                 $str[$key] = $this->escape_str($val, $like);
  318.                         }
  319.  
  320.                         return $str;
  321.                 }
  322.                
  323.                 //Escape the string
  324.                 $str = $this->conn_id->quote($str);
  325.                
  326.                 //If there are duplicated quotes, trim them away
  327.                 if (strpos($str, "'") === 0)
  328.                 {
  329.                         $str = substr($str, 1, -1);
  330.                 }
  331.                
  332.                 // escape LIKE condition wildcards
  333.                 if ($like === TRUE)
  334.                 {
  335.                         $str = str_replace(     array('%', '_', $this->_like_escape_chr),
  336.                                                                 array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
  337.                                                                 $str);
  338.                 }
  339.  
  340.                 return $str;
  341.         }
  342.  
  343.         // --------------------------------------------------------------------
  344.  
  345.         /**
  346.          * Affected Rows
  347.          *
  348.          * @access      public
  349.          * @return      integer
  350.          */
  351.         function affected_rows()
  352.         {
  353.                 return $this->affect_rows;
  354.         }
  355.  
  356.         // --------------------------------------------------------------------
  357.  
  358.         /**
  359.          * Insert ID
  360.          *
  361.          * @access      public
  362.          * @return      integer
  363.          */
  364.         function insert_id($name=NULL)
  365.         {
  366.                 //Convenience method for postgres insertid
  367.                 if (strpos($this->hostname, 'pgsql') !== FALSE)
  368.                 {
  369.                         $v = $this->_version();
  370.  
  371.                         $table  = func_num_args() > 0 ? func_get_arg(0) : NULL;
  372.  
  373.                         if ($table == NULL && $v >= '8.1')
  374.                         {
  375.                                 $sql='SELECT LASTVAL() as ins_id';
  376.                         }
  377.                         $query = $this->query($sql);
  378.                         $row = $query->row();
  379.                         return $row->ins_id;
  380.                 }
  381.                 else
  382.                 {
  383.                         return $this->conn_id->lastInsertId($name);
  384.                 }
  385.         }
  386.  
  387.         // --------------------------------------------------------------------
  388.  
  389.         /**
  390.          * "Count All" query
  391.          *
  392.          * Generates a platform-specific query string that counts all records in
  393.          * the specified database
  394.          *
  395.          * @access      public
  396.          * @param       string
  397.          * @return      string
  398.          */
  399.         function count_all($table = '')
  400.         {
  401.                 if ($table == '')
  402.                 {
  403.                         return 0;
  404.                 }
  405.  
  406.                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
  407.  
  408.                 if ($query->num_rows() == 0)
  409.                 {
  410.                         return 0;
  411.                 }
  412.  
  413.                 $row = $query->row();
  414.                 $this->_reset_select();
  415.                 return (int) $row->numrows;
  416.         }
  417.  
  418.         // --------------------------------------------------------------------
  419.  
  420.         /**
  421.          * Show table query
  422.          *
  423.          * Generates a platform-specific query string so that the table names can be fetched
  424.          *
  425.          * @access      private
  426.          * @param       boolean
  427.          * @return      string
  428.          */
  429.         function _list_tables($prefix_limit = FALSE)
  430.         {
  431.                 $sql = "SHOW TABLES FROM `".$this->database."`";
  432.  
  433.                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
  434.                 {
  435.                         //$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
  436.                         return FALSE; // not currently supported
  437.                 }
  438.  
  439.                 return $sql;
  440.         }
  441.  
  442.         // --------------------------------------------------------------------
  443.  
  444.         /**
  445.          * Show column query
  446.          *
  447.          * Generates a platform-specific query string so that the column names can be fetched
  448.          *
  449.          * @access      public
  450.          * @param       string  the table name
  451.          * @return      string
  452.          */
  453.         function _list_columns($table = '')
  454.         {
  455.                 return "SHOW COLUMNS FROM ".$table;
  456.         }
  457.  
  458.         // --------------------------------------------------------------------
  459.  
  460.         /**
  461.          * Field data query
  462.          *
  463.          * Generates a platform-specific query so that the column data can be retrieved
  464.          *
  465.          * @access      public
  466.          * @param       string  the table name
  467.          * @return      object
  468.          */
  469.         function _field_data($table)
  470.         {
  471.                 return "SELECT TOP 1 FROM ".$table;
  472.         }
  473.  
  474.         // --------------------------------------------------------------------
  475.  
  476.         /**
  477.          * The error message string
  478.          *
  479.          * @access      private
  480.          * @return      string
  481.          */
  482.         function _error_message()
  483.         {
  484.                 $error_array = $this->conn_id->errorInfo();
  485.                 return $error_array[2];
  486.         }
  487.  
  488.         // --------------------------------------------------------------------
  489.  
  490.         /**
  491.          * The error message number
  492.          *
  493.          * @access      private
  494.          * @return      integer
  495.          */
  496.         function _error_number()
  497.         {
  498.                 return $this->conn_id->errorCode();
  499.         }
  500.  
  501.         // --------------------------------------------------------------------
  502.  
  503.         /**
  504.          * Escape the SQL Identifiers
  505.          *
  506.          * This function escapes column and table names
  507.          *
  508.          * @access      private
  509.          * @param       string
  510.          * @return      string
  511.          */
  512.         function _escape_identifiers($item)
  513.         {
  514.                 if ($this->_escape_char == '')
  515.                 {
  516.                         return $item;
  517.                 }
  518.  
  519.                 foreach ($this->_reserved_identifiers as $id)
  520.                 {
  521.                         if (strpos($item, '.'.$id) !== FALSE)
  522.                         {
  523.                                 $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
  524.  
  525.                                 // remove duplicates if the user already included the escape
  526.                                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  527.                         }
  528.                 }
  529.  
  530.                 if (strpos($item, '.') !== FALSE)
  531.                 {
  532.                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
  533.                        
  534.                 }
  535.                 else
  536.                 {
  537.                         $str = $this->_escape_char.$item.$this->_escape_char;
  538.                 }
  539.  
  540.                 // remove duplicates if the user already included the escape
  541.                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  542.         }
  543.  
  544.         // --------------------------------------------------------------------
  545.  
  546.         /**
  547.          * From Tables
  548.          *
  549.          * This function implicitly groups FROM tables so there is no confusion
  550.          * about operator precedence in harmony with SQL standards
  551.          *
  552.          * @access      public
  553.          * @param       type
  554.          * @return      type
  555.          */
  556.         function _from_tables($tables)
  557.         {
  558.                 if ( ! is_array($tables))
  559.                 {
  560.                         $tables = array($tables);
  561.                 }
  562.  
  563.                 return (count($tables) == 1) ? $tables[0] : '('.implode(', ', $tables).')';
  564.         }
  565.  
  566.         // --------------------------------------------------------------------
  567.  
  568.         /**
  569.          * Insert statement
  570.          *
  571.          * Generates a platform-specific insert string from the supplied data
  572.          *
  573.          * @access      public
  574.          * @param       string  the table name
  575.          * @param       array   the insert keys
  576.          * @param       array   the insert values
  577.          * @return      string
  578.          */
  579.         function _insert($table, $keys, $values)
  580.         {
  581.                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
  582.         }
  583.        
  584.         // --------------------------------------------------------------------
  585.  
  586.         /**
  587.          * Insert_batch statement
  588.          *
  589.          * Generates a platform-specific insert string from the supplied data
  590.          *
  591.          * @access  public
  592.          * @param   string  the table name
  593.          * @param   array   the insert keys
  594.          * @param   array   the insert values
  595.          * @return  string
  596.          */
  597.         function _insert_batch($table, $keys, $values)
  598.         {
  599.                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
  600.         }
  601.  
  602.         // --------------------------------------------------------------------
  603.  
  604.         /**
  605.          * Update statement
  606.          *
  607.          * Generates a platform-specific update string from the supplied data
  608.          *
  609.          * @access      public
  610.          * @param       string  the table name
  611.          * @param       array   the update data
  612.          * @param       array   the where clause
  613.          * @param       array   the orderby clause
  614.          * @param       array   the limit clause
  615.          * @return      string
  616.          */
  617.         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
  618.         {
  619.                 foreach ($values as $key => $val)
  620.                 {
  621.                         $valstr[] = $key." = ".$val;
  622.                 }
  623.  
  624.                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  625.  
  626.                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
  627.  
  628.                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
  629.  
  630.                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
  631.  
  632.                 $sql .= $orderby.$limit;
  633.  
  634.                 return $sql;
  635.         }
  636.        
  637.         // --------------------------------------------------------------------
  638.  
  639.         /**
  640.          * Update_Batch statement
  641.          *
  642.          * Generates a platform-specific batch update string from the supplied data
  643.          *
  644.          * @access      public
  645.          * @param       string  the table name
  646.          * @param       array   the update data
  647.          * @param       array   the where clause
  648.          * @return      string
  649.          */
  650.         function _update_batch($table, $values, $index, $where = NULL)
  651.         {
  652.                 $ids = array();
  653.                 $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
  654.  
  655.                 foreach ($values as $key => $val)
  656.                 {
  657.                         $ids[] = $val[$index];
  658.  
  659.                         foreach (array_keys($val) as $field)
  660.                         {
  661.                                 if ($field != $index)
  662.                                 {
  663.                                         $final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
  664.                                 }
  665.                         }
  666.                 }
  667.  
  668.                 $sql = "UPDATE ".$table." SET ";
  669.                 $cases = '';
  670.  
  671.                 foreach ($final as $k => $v)
  672.                 {
  673.                         $cases .= $k.' = CASE '."\n";
  674.                         foreach ($v as $row)
  675.                         {
  676.                                 $cases .= $row."\n";
  677.                         }
  678.  
  679.                         $cases .= 'ELSE '.$k.' END, ';
  680.                 }
  681.  
  682.                 $sql .= substr($cases, 0, -2);
  683.  
  684.                 $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
  685.  
  686.                 return $sql;
  687.         }
  688.  
  689.  
  690.         // --------------------------------------------------------------------
  691.  
  692.         /**
  693.          * Truncate statement
  694.          *
  695.          * Generates a platform-specific truncate string from the supplied data
  696.          * If the database does not support the truncate() command
  697.          * This function maps to "DELETE FROM table"
  698.          *
  699.          * @access      public
  700.          * @param       string  the table name
  701.          * @return      string
  702.          */
  703.         function _truncate($table)
  704.         {
  705.                 return $this->_delete($table);
  706.         }
  707.  
  708.         // --------------------------------------------------------------------
  709.  
  710.         /**
  711.          * Delete statement
  712.          *
  713.          * Generates a platform-specific delete string from the supplied data
  714.          *
  715.          * @access      public
  716.          * @param       string  the table name
  717.          * @param       array   the where clause
  718.          * @param       string  the limit clause
  719.          * @return      string
  720.          */
  721.         function _delete($table, $where = array(), $like = array(), $limit = FALSE)
  722.         {
  723.                 $conditions = '';
  724.  
  725.                 if (count($where) > 0 OR count($like) > 0)
  726.                 {
  727.                         $conditions = "\nWHERE ";
  728.                         $conditions .= implode("\n", $this->ar_where);
  729.  
  730.                         if (count($where) > 0 && count($like) > 0)
  731.                         {
  732.                                 $conditions .= " AND ";
  733.                         }
  734.                         $conditions .= implode("\n", $like);
  735.                 }
  736.  
  737.                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  738.  
  739.                 return "DELETE FROM ".$table.$conditions.$limit;
  740.         }
  741.  
  742.         // --------------------------------------------------------------------
  743.  
  744.         /**
  745.          * Limit string
  746.          *
  747.          * Generates a platform-specific LIMIT clause
  748.          *
  749.          * @access      public
  750.          * @param       string  the sql query string
  751.          * @param       integer the number of rows to limit the query to
  752.          * @param       integer the offset value
  753.          * @return      string
  754.          */
  755.         function _limit($sql, $limit, $offset)
  756.         {
  757.                 if (strpos($this->hostname, 'cubrid') !== FALSE || strpos($this->hostname, 'sqlite') !== FALSE)
  758.                 {
  759.                         if ($offset == 0)
  760.                         {
  761.                                 $offset = '';
  762.                         }
  763.                         else
  764.                         {
  765.                                 $offset .= ", ";
  766.                         }
  767.  
  768.                         return $sql."LIMIT ".$offset.$limit;
  769.                 }
  770.                 else
  771.                 {
  772.                         $sql .= "LIMIT ".$limit;
  773.  
  774.                         if ($offset > 0)
  775.                         {
  776.                                 $sql .= " OFFSET ".$offset;
  777.                         }
  778.                        
  779.                         return $sql;
  780.                 }
  781.         }
  782.  
  783.         // --------------------------------------------------------------------
  784.  
  785.         /**
  786.          * Close DB Connection
  787.          *
  788.          * @access      public
  789.          * @param       resource
  790.          * @return      void
  791.          */
  792.         function _close($conn_id)
  793.         {
  794.                 $this->conn_id = null;
  795.         }
  796.  
  797.  
  798. }
  799.  
  800.  
  801.  
  802. /* End of file pdo_driver.php */
  803. /* Location: ./system/database/drivers/pdo/pdo_driver.php */
clone this paste RAW Paste Data