tangra logo
   
[ class tree: tangra_lib ] [ index: tangra_lib ] [ all elements ]
 

Source for file db_connection.class.php

Documentation is available at db_connection.class.php

  1. <?php
  2. // *** Tangra (Application Framework and Tools for PHP)
  3. //  $Id$
  4. //
  5.  
  6. /**
  7.  * Contains DB_Connection class
  8.  *
  9.  * @package tangra_lib
  10.  * @subpackage db
  11.  */
  12.  
  13. /**
  14.  * Requires parent class
  15.  */
  16. require_once(TANGRA_MAIN_DIR.'core/tangra_class.class.php');
  17.  
  18. /**
  19.  * Base class for DB_Connection class family.
  20.  *
  21.  * DB_Connection class contains connection to DB and methods to query that DB.
  22.  *
  23.  * @package tangra_lib
  24.  * @subpackage db
  25.  */
  26. abstract class DB_Connection extends Tangra_Class {
  27.     /**
  28.      * Is connected to DB?
  29.      *
  30.      * @var boolean 
  31.      */
  32.     private $connected = false;
  33.  
  34.  
  35.     /**
  36.      * DB DSN
  37.      *
  38.      * @var string 
  39.      */
  40.     private $dsn;
  41.  
  42.  
  43.     /**
  44.      * DB connection itself (resource)
  45.      *
  46.      * @var unknown_type 
  47.      */
  48.     protected $conn;
  49.  
  50.  
  51.     /**
  52.      * Autocommit mode
  53.      *
  54.      * @var integer 
  55.      */
  56.     private $autocommit;
  57.  
  58.  
  59.     /**
  60.      * Constructor
  61.      *
  62.      * Attempts to connect to database specified with {@link dsn}
  63.      *
  64.      * @param string $dsn Valid DSN
  65.      * @return boolean returns true on success, flase otherwise
  66.      */
  67.     function __construct($dsn{
  68.         $this->dsn = $dsn;
  69.  
  70.         $ret $this->connect();
  71.  
  72.         return $ret;
  73.     }
  74.  
  75.  
  76.     /**
  77.      * Tries to connect to DB
  78.      *
  79.      */
  80.     abstract public function connect();
  81.  
  82.  
  83.     /**
  84.      * Disconnects from the DB
  85.      *
  86.      */
  87.     abstract public function disconnect();
  88.  
  89.  
  90.     /**
  91.      * Sets $this->connected
  92.      *
  93.      * @param boolean $connected 
  94.      * @access private
  95.      */
  96.     final protected function set_connected($connected{
  97.         $this->connected = $connected;
  98.     }
  99.  
  100.  
  101.     /**
  102.      * Gets $this->connected
  103.      *
  104.      * @return boolean 
  105.      */
  106.     final public function is_connected({
  107.         return $this->connected;
  108.     }
  109.  
  110.  
  111.     /**
  112.      * Gets DB DSN
  113.      *
  114.      * @return unknown 
  115.      */
  116.     final public function get_dsn({
  117.         return $this->dsn;
  118.     }
  119.  
  120.  
  121.     /**
  122.      * Starting transaction
  123.      *
  124.      */
  125.     abstract public function start_trans();
  126.  
  127.  
  128.     /**
  129.      * Finishing transaction
  130.      *
  131.      */
  132.     abstract public function complete_trans();
  133.  
  134.  
  135.     /**
  136.      * Manually marking transaction as failed
  137.      *
  138.      */
  139.     abstract public function fail_trans();
  140.  
  141.  
  142.     /**
  143.      * Executes SQL statemnt
  144.      *
  145.      * @param string $sql 
  146.      */
  147.     abstract public function execute($sql$ignore_sql_injection_warning false);
  148.  
  149.  
  150.     /**
  151.      * Selects limited ammount of rows
  152.      *
  153.      * Useful for paginating the results.
  154.      *
  155.      * @param string $sql SQL statement
  156.      * @param integer $num_rows number of rows to select
  157.      * @param integer $offset offset to start
  158.      */
  159.     abstract public function select_limit($sql$num_rows$offset);
  160.  
  161.     /**
  162.      * Alias of {@link execute()}
  163.      *
  164.      * @param string $sql 
  165.      */
  166.     abstract public function query($sql);
  167.  
  168.  
  169.     /**
  170.      * Generates next id from sequence
  171.      *
  172.      * For RDBMS that does not support sequences this have to be emulated by DB abstraction layer
  173.      *
  174.      * @param string $table_id_is_for name of the sequence
  175.      * @param unknown_type $start if sequence is not existing $start will be used as initial value when sequence is automatically created
  176.      */
  177.     abstract public function generate_id($sequence_name$start 1);
  178.  
  179.  
  180.     /**
  181.      * Returns error message if any
  182.      *
  183.      */
  184.     abstract public function get_error_msg();
  185.  
  186.  
  187.     /**
  188.      * Destructor
  189.      *
  190.      * Here is the place to disconnect nicely from the database
  191.      *
  192.      */
  193.     abstract function __destruct();
  194.  
  195.  
  196.     /**
  197.      * Sets autocommit mode
  198.      *
  199.      * @param unknown_type $auto 
  200.      */
  201.     public function set_autocommit($auto{
  202.         $this->autocommit = $auto 0;
  203.     }
  204.  
  205.  
  206.     /**
  207.      * Gets autocommit mode
  208.      *
  209.      * @return unknown 
  210.      */
  211.     public function get_autocommit({
  212.         return $this->autocommit;
  213.     }
  214.  
  215.  
  216.     /**
  217.      * Executes sql statemnt(s) in transaction
  218.      *
  219.      * @param DB_Connection $dbc 
  220.      * @param mixed $sql 
  221.      */
  222.     public static function execute_in_trans(DB_Connection $dbc$sql{
  223.         $dbc->start_trans();
  224.         try {
  225.             if (is_array($sql)) {
  226.                 foreach($sql as $statement{
  227.                     $dbc->execute($statement);
  228.                 }
  229.             else {
  230.                 $dbc->execute($sql);
  231.             }
  232.  
  233.             $dbc->complete_trans();
  234.         catch (Exception $e{
  235.             $dbc->fail_trans();
  236.             $dbc->complete_trans();
  237.             throw $e;
  238.         }
  239.     }
  240.  
  241.  
  242.     /**
  243.      * Returns internal db connection object
  244.      *
  245.      * This function should be used only if you REALLY need to use DBAL (ADODB, PDO, etc...) specific calls.
  246.      *
  247.      * @return unknown 
  248.      */
  249.     public function get_conn({
  250.         return $this->conn;
  251.     }
  252.  
  253.  
  254.     /**
  255.      * Checks if $sql looks like SQL injection attempt
  256.      *
  257.      * This function will check if there are comments in the $sql and if found will return true.
  258.      * Don't overtrust this to keep you safe - allways check and escape data before sending it as SQL statement to the RDBMS.
  259.      * Please note that by default queries that use UNION are detected as sql inj attempt. Use $ignore_sql_injection_warning = true or comment this check bellow in the method body
  260.      *
  261.      * @param string $sql 
  262.      * @return boolean Returns true if $sql is suspicious
  263.      */
  264.     protected function is_like_sql_injection($sql{
  265.         $ret false;
  266.  
  267.         $sql strtolower($this->remove_quoted($sql));
  268.  
  269.  
  270.         if (strpos($sql';'!== false// multiple queries forbidden
  271.             $ret true;
  272.         }
  273.  
  274.  
  275.         // comments forbidden
  276.         if (strpos($sql' --'!== false{
  277.             $ret true;
  278.         }
  279.  
  280.         if (strpos($sql"\t--"!== false{
  281.             $ret true;
  282.         }
  283.  
  284.         if (strpos($sql"\n--"!== false{
  285.             $ret true;
  286.         }
  287.  
  288.         if (strpos($sql' /*'!== false{
  289.             $ret true;
  290.         }
  291.         
  292.         // If you use UNION you will have to either comment next 3 lines, or execute queries with $ignore_sql_injection_warning flag = true
  293.         if (strpos($sql' union '!== false{
  294.             $ret true;
  295.         }
  296.         
  297.  
  298.         return $ret;
  299.     }
  300.  
  301.  
  302.     /**
  303.      * Removes quoted content from $sql_str
  304.      *
  305.      * @param string $sql_str 
  306.      * @return string 
  307.      * @internal
  308.      */
  309.     private function remove_quoted($sql_str{
  310.         $sql_str str_replace("\\"''$sql_str);
  311.         $sql_str str_replace("\'"''$sql_str);
  312.         $sql_str str_replace("\`"''$sql_str);
  313.         $sql_str str_replace('\"'''$sql_str);
  314.  
  315.         while (strpos($sql_str"'"!== false{
  316.             $sql_str $this->_remove_quoted_with($sql_str"'");
  317.         }
  318.  
  319.         while (strpos($sql_str'"'!== false{
  320.             $sql_str $this->_remove_quoted_with($sql_str'"');
  321.         }
  322.  
  323.         return $sql_str;
  324.     }
  325.  
  326.  
  327.     /**
  328.      * Removes quoted with $q from $sql_str
  329.      *
  330.      * @param string $sql_str 
  331.      * @param string $q One character ' or "
  332.      * @return string 
  333.      */
  334.     private function _remove_quoted_with($sql_str$q{
  335.         $start strpos($sql_str$q);
  336.         if ($start !== false{
  337.             $end strpos($sql_str$q$start);
  338.             if ($end !== false{
  339.                 $tmp1 substr($sql_str0$start);
  340.                 $tmp2 substr($sql_str$end);
  341.                 $sql_str $tmp1.$tmp1;
  342.             else {
  343.                 $sql_str substr($sql_str0$start);
  344.             }
  345.         }
  346.  
  347.         return $sql_str;
  348.     }
  349. }