db.php

Go to the documentation of this file.
00001 <?php
00002   /**
00003    *  @file db.php
00004    *  Everything connected with accessing database.
00005    */
00006 
00007   /*
00008   Easy PHP Framework
00009 
00010   Copyright (c) 2005 Michal Molhanec
00011 
00012   This software is provided 'as-is', without any express or implied
00013   warranty. In no event will the authors be held liable for any damages
00014   arising from the use of this software.
00015 
00016   Permission is granted to anyone to use this software for any purpose,
00017   including commercial applications, and to alter it and redistribute
00018   it freely, subject to the following restrictions:
00019 
00020       1. The origin of this software must not be misrepresented;
00021          you must not claim that you wrote the original software.
00022          If you use this software in a product, an acknowledgment
00023          in the product documentation would be appreciated but
00024          is not required.
00025 
00026       2. Altered source versions must be plainly marked as such,
00027          and must not be misrepresented as being the original software.
00028 
00029       3. This notice may not be removed or altered from any
00030          source distribution.
00031   */
00032   
00033   /**
00034    *  See <a href='http://www.php.net/manual/en/ref.mysqli.php'>mysqli
00035    *  class documentation</a> for details.
00036    */
00037   class Db extends mysqli {
00038 
00039     /**
00040      *  Establishes database connection.
00041      *  All data has to be in <a href="http://dev.mysql.com/doc/mysql/en/charset-unicode.html">UTF-8</a>.
00042      *  @throw Exception If cannot connect.
00043      */
00044     function __construct() {
00045       global $mysql_host, $mysql_username, $mysql_password, $mysql_dbname;
00046       parent::__construct($mysql_host, $mysql_username, $mysql_password, $mysql_dbname);
00047       if (mysqli_connect_errno()):
00048         throw new Exception(sprintf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error()));
00049       endif;
00050       parent::query("SET NAMES 'utf8'"); // we work in UTF-8
00051     }
00052 
00053     /**
00054      *  @throws Exception On error.
00055      *  @return mysqli_result object.
00056      */
00057     function query($sql) {
00058       $result = parent::query($sql);
00059       if (!$result):
00060         throw new Exception(sprintf("Error in query %s. Error message: %s\n", $sql, $this->error));
00061       endif;
00062       return $result;
00063     }
00064 
00065   }
00066 
00067   /**
00068    *  This object represent result of a SQL query.
00069    *  You can use this object in foreach() construct.
00070    *  For details see
00071    *  <a href='http://www.php.net/~helly/php/ext/spl/interfaceIterator.html'>
00072    *  Iterator interface documentation</a>.
00073    */
00074   class DbQuery implements Iterator {
00075 
00076     private $sql;
00077     private $result = NULL;
00078     private $row;
00079 
00080     function __construct($sql) {
00081       $this->sql = $sql;
00082     }
00083 
00084     /**
00085      *  @throw Exception. On SQL error.
00086      */
00087     function rewind() {
00088       if (!is_null($this->result)):
00089         $this->result->close();
00090         $this->result = NULL;
00091       endif;
00092       $db = new Db();
00093       $this->result = $db->query($this->sql);
00094       $this->row = $this->result->fetch_object();
00095     }
00096 
00097     function current() {
00098       return $this->row;
00099     }
00100 
00101     /** Unimplemented. */
00102     function key() { return 0; }
00103 
00104     function next() {
00105       $this->row = $this->result->fetch_object();
00106     }
00107 
00108     function valid() {
00109       return $this->result and $this->row;
00110     }
00111     
00112   }
00113 
00114   /**
00115    *  @return DbQuery object.
00116    */
00117   function query($sql) {
00118     $q = new DbQuery($sql);
00119     return $q;
00120   }
00121 
00122   /**
00123    *  Executes INSERT or UPDATE SQL statement.
00124    *  @throw Exception($errormsg) If the SQL statement violates
00125    *    primary key or unique index uniqueness.
00126    *  @throw Exception If the SQL statement fails for some
00127    *    other reason.
00128    */
00129   function insert_unique($sql, $errormsg) {
00130     $db = new Db();
00131     try {
00132       $db->query($sql);
00133     }
00134     catch (Exception $e) {
00135       if ($db->errno == 1062):
00136         throw new Exception($errormsg);
00137       else:
00138         throw $e;
00139       endif;
00140     }
00141     $db->close();
00142   }
00143 
00144   /**
00145    *  @param[in] $sql SQL statement in a form of "SELECT COUNT(...) FROM ...".
00146    *  @return TRUE if statement executed succesfully and it returned
00147    *    value of 1, FALSE otherwise.
00148    *  @throw Exception On SQL error.
00149    */
00150   function exists($sql) {
00151     $db = new Db();
00152     $result = $db->query($sql);
00153 
00154     /*
00155       This clearly shows how is PHP badly designed language.
00156       You cannot simply write
00157       $count = $result->fetch_row()[0];
00158       You even cannot write
00159       $count = ($result->fetch_row())[0];
00160     */
00161     $count = $result->fetch_row();
00162     $count = $count[0];
00163     
00164     $db->close();
00165     if ($count == 1):
00166       return TRUE;
00167     endif;
00168     return FALSE;
00169   }
00170 
00171   /**
00172    *  Exception class used by one_line_query() function.
00173    */
00174   class RecordNotFound extends Exception {}
00175   
00176   /**
00177    *  Performs SQL query that return only one record.
00178    *  @return Fetched object.
00179    *  @throw RecordNotFound($errormsg) if the record does not exists.
00180    *  @throw Exception On SQL error.
00181    */
00182   function one_line_query($sql, $errormsg = 'Error.') {
00183     $db = new Db();
00184     $result = $db->query($sql);
00185     $obj = $result->fetch_object();
00186     if (!$obj):
00187       throw new RecordNotFound($errormsg);
00188     endif;
00189     return $obj;
00190   }
00191 
00192   /**
00193    *  For INSERT/UPDATE/DELETE.
00194    *  @throw Exception On SQL error.
00195    */
00196   function update($sql) {
00197     $db = new Db();
00198     $db->query($sql);
00199     $db->close();
00200   }
00201 
00202   /**
00203    *  For INSERT with autoincremented PK.
00204    *  @return New record PK value or 0 if it's not INSERT/UPDATE statement
00205    *    or the table does not have autoincremented column.
00206    *  @throw Exception On SQL error.
00207    */
00208   function insert($sql) {
00209     $db = new Db();
00210     $db->query($sql);
00211     $id = $db->insert_id;
00212     $db->close();
00213     return $id;
00214   }
00215 
00216   /**
00217    *  Helper for build_insert_sql_from_array().
00218    *  @return $obj
00219    */
00220   function get_identity_value($obj) {
00221     return $obj;
00222   }
00223   
00224   /**
00225    *  Helper for build_insert_sql_from_array().
00226    *  @return $obj->get_id().
00227    */
00228   function get_id_value($obj) {
00229     return $obj->get_id();
00230   }
00231   
00232   /**
00233    *  Creates string which you can pass to INSERT SQL command
00234    *  as VALUES based on an array. This is useful for adding multiple
00235    *  values in one SQL command.
00236    *  Example:
00237    *  @code
00238    *    $a = array('a', 'b', 'c');
00239    *    $s = build_insert_sql_from_array($a, '1', '2', TRUE);
00240    *  @endcode
00241    *  will generate:
00242    *  @code
00243    *    $s == "(1, 'a', 2),(1, 'b', 2),(1, 'c', 2)";
00244    *  @endcode
00245    *  and you can use it like this:
00246    *  @code
00247    *    db_query("INSERT INTO table VALUES $s");
00248    *  @endcode
00249    *  @param[in] $array Array containing e.g. strings or objects etc.
00250    *  @param[in] $pre String prepended for each value.
00251    *  @param[in] $post String appended for each value.
00252    *  @param[in] $quote Should be the value quoted?
00253    *  @param[in] $value_getter Function which for each element in the array
00254    *    returns its value. Default is identity.
00255    *  @return String usable in SQL command.
00256    */
00257   function build_insert_sql_from_array($array, $pre = '', $post = '', $quote = FALSE, $value_getter = 'get_identity_value') {
00258     if ($pre):
00259       $pre = "$pre,";
00260     endif;
00261     if ($post):
00262       $post = ",$post";
00263     endif;
00264     $sqllines = array();
00265     foreach ($array as $obj):
00266       $value = $value_getter($obj);
00267       if ($quote):
00268         $sqllines[] = "($pre '$value' $post)";
00269       else:
00270         $sqllines[] = "($pre $value $post)";
00271       endif;
00272     endforeach;
00273     return join(',', $sqllines);
00274   }
00275 
00276 ?>

Generated on Sat Sep 24 01:26:42 2005 for Easy PHP Framework by  doxygen 1.4.2