MySQL.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2004-2009 by Sveta A. Smirnova                          *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00020     final class MySQL extends Sequenceless
00021     {
00025         public static function getDialect()
00026         {
00027             return MyDialect::me();
00028         }
00029         
00033         public function setDbEncoding()
00034         {
00035             mysql_query("SET NAMES '{$this->encoding}'", $this->link);
00036             
00037             return $this;
00038         }
00039 
00043         public function connect()
00044         {
00045             $hostname =
00046                 $this->port
00047                     ? $this->hostname.':'.$this->port
00048                     : $this->hostname;
00049             
00050             $this->link =
00051                 $this->persistent
00052                     ?
00053                         mysql_pconnect(
00054                             $hostname,
00055                             $this->username,
00056                             $this->password,
00057                             // 2 == CLIENT_FOUND_ROWS
00058                             2
00059                         )
00060                     :
00061                         mysql_connect(
00062                             $hostname,
00063                             $this->username,
00064                             $this->password,
00065                             true,
00066                             // 2 == CLIENT_FOUND_ROWS
00067                             2
00068                         );
00069             
00070             if (
00071                 !$this->link
00072                 || (
00073                     $this->basename
00074                     && !mysql_select_db($this->basename, $this->link)
00075                 )
00076             )
00077                 throw new DatabaseException(
00078                     'can not connect to MySQL server: '.mysql_error($this->link),
00079                     mysql_errno($this->link)
00080                 );
00081             
00082             if ($this->encoding)
00083                 $this->setDbEncoding();
00084             
00085             return $this;
00086         }
00087         
00091         public function disconnect()
00092         {
00093             if ($this->isConnected())
00094                 mysql_close($this->link);
00095 
00096             return $this;
00097         }
00098         
00103         public function queryCount(Query $query)
00104         {
00105             $this->queryNull($query);
00106             
00107             return mysql_affected_rows($this->link);
00108         }
00109         
00110         public function queryRow(Query $query)
00111         {
00112             $res = $this->query($query);
00113             
00114             if ($this->checkSingle($res))
00115                 return mysql_fetch_assoc($res);
00116             else
00117                 return null;
00118         }
00119         
00120         public function queryColumn(Query $query)
00121         {
00122             $res = $this->query($query);
00123             
00124             if ($res) {
00125                 $array = array();
00126 
00127                 while ($row = mysql_fetch_row($res))
00128                     $array[] = $row[0];
00129 
00130                 return $array;
00131             } else
00132                 return null;
00133         }
00134         
00135         public function querySet(Query $query)
00136         {
00137             $res = $this->query($query);
00138             
00139             if ($res) {
00140                 $array = array();
00141 
00142                 while ($row = mysql_fetch_assoc($res))
00143                     $array[] = $row;
00144 
00145                 return $array;
00146             } else
00147                 return null;
00148         }
00149         
00150         public function queryRaw($queryString)
00151         {
00152             if (!$result = mysql_query($queryString, $this->link)) {
00153                 
00154                 $code = mysql_errno($this->link);
00155                 
00156                 if ($code == 1062)
00157                     $e = 'DuplicateObjectException';
00158                 else
00159                     $e = 'DatabaseException';
00160 
00161                 throw new $e(
00162                     mysql_error($this->link).' - '.$queryString,
00163                     $code
00164                 );
00165             }
00166 
00167             return $result;
00168         }
00169         
00170         public function getTableInfo($table)
00171         {
00172             static $types = array(
00173                 'tinyint'   => DataType::SMALLINT,
00174                 'smallint'  => DataType::SMALLINT,
00175                 'int'       => DataType::INTEGER,
00176                 'mediumint' => DataType::INTEGER,
00177 
00178                 'bigint'    => DataType::BIGINT,
00179                 
00180                 'double'    => DataType::DOUBLE,
00181                 'decimal'   => DataType::NUMERIC,
00182 
00183                 'char'      => DataType::CHAR,
00184                 'varchar'   => DataType::VARCHAR,
00185                 'text'      => DataType::TEXT,
00186                 'tinytext'  => DataType::TEXT,
00187                 
00188                 'date'      => DataType::DATE,
00189                 'time'      => DataType::TIME,
00190                 'timestamp' => DataType::TIMESTAMP,
00191                 'datetime'  => DataType::TIMESTAMP,
00192 
00193                 // unhandled types
00194                 'set'       => null,
00195                 'enum'      => null,
00196                 'year'      => null
00197             );
00198             
00199             try {
00200                 $result = $this->queryRaw('SHOW COLUMNS FROM '.$table);
00201             } catch (BaseException $e) {
00202                 throw new ObjectNotFoundException(
00203                     "unknown table '{$table}'"
00204                 );
00205             }
00206             
00207             $table = new DBTable($table);
00208             
00209             while ($row = mysql_fetch_assoc($result)) {
00210                 $name = strtolower($row['Field']);
00211                 $matches = array();
00212                 $info = array('type' => null, 'extra' => null);
00213                 if (
00214                     preg_match(
00215                         '~(\w+)(\((\d+?)\)){0,1}\s*(\w*)~',
00216                         strtolower($row['Type']),
00217                         $matches
00218                     )
00219                 ) {
00220                     $info['type'] = $matches[1];
00221                     $info['size'] = $matches[3];
00222                     $info['extra'] = $matches[4];
00223                 }
00224                 
00225                 Assert::isTrue(
00226                     array_key_exists($info['type'], $types),
00227                     
00228                     'unknown type "'
00229                     .$types[$info['type']]
00230                     .'" found in column "'.$name.'"'
00231                 );
00232                 
00233                 if (empty($types[$info['type']]))
00234                     continue;
00235                 
00236                 $column = DBColumn::create(
00237                     DataType::create($types[$info['type']])->
00238                         setUnsigned(
00239                             strtolower($info['extra']) == 'unsigned'
00240                         )->
00241                         setNull(strtolower($row['Null']) == 'yes'),
00242                     
00243                     $name
00244                 )->
00245                 setAutoincrement(strtolower($row['Extra']) == 'auto_increment')->
00246                 setPrimaryKey(strtolower($row['Key']) == 'pri');
00247                 
00248                 if ($row['Default'])
00249                     $column->setDefault($row['Default']);
00250                 
00251                 $table->addColumn($column);
00252             }
00253             
00254             return $table;
00255         }
00256         
00257         public function hasQueue()
00258         {
00259             return false;
00260         }
00261         
00262         protected function getInsertId()
00263         {
00264             return mysql_insert_id($this->link);
00265         }
00266         
00267         private function checkSingle($result)
00268         {
00269             if (mysql_num_rows($result) > 1)
00270                 throw new TooManyRowsException(
00271                     'query returned too many rows (we need only one)'
00272                 );
00273             
00274             return $result;
00275         }
00276     }
00277 ?>