00001 <?php
00003
00004
00005
00006
00007
00008
00010
00020
00021 FLEA::loadClass('FLEA_Db_Driver_Abstract');
00022
00023
00031 class FLEA_Db_Driver_Mysql extends FLEA_Db_Driver_Abstract
00032 {
00033 var $NEXT_ID_SQL = 'UPDATE %s SET id = LAST_INSERT_ID(id + 1)';
00034 var $CREATE_SEQ_SQL = 'CREATE TABLE %s (id INT NOT NULL)';
00035 var $INIT_SEQ_SQL = 'INSERT INTO %s VALUES (%s)';
00036 var $DROP_SEQ_SQL = 'DROP TABLE %s';
00037 var $META_COLUMNS_SQL = 'SHOW FULL COLUMNS FROM %s';
00038 var $PARAM_STYLE = DBO_PARAM_QM;
00039 var $HAS_INSERT_ID = true;
00040 var $HAS_AFFECTED_ROWS = true;
00041 var $_mysqlVersion = null;
00042
00043 function connect($dsn = false)
00044 {
00045 $this->lasterr = null;
00046 $this->lasterrcode = null;
00047
00048 if ($this->conn && $dsn == false) { return true; }
00049 if (!$dsn) {
00050 $dsn = $this->dsn;
00051 } else {
00052 $this->dsn = $dsn;
00053 }
00054 if (isset($dsn['port']) && $dsn['port'] != '') {
00055 $host = $dsn['host'] . ':' . $dsn['port'];
00056 } else {
00057 $host = $dsn['host'];
00058 }
00059 if (!isset($dsn['login'])) { $dsn['login'] = ''; }
00060 if (!isset($dsn['password'])) { $dsn['password'] = ''; }
00061 if (isset($dsn['options'])) {
00062 $this->conn = mysql_connect($host, $dsn['login'], $dsn['password'], false, $dsn['options']);
00063 } else {
00064 $this->conn = mysql_connect($host, $dsn['login'], $dsn['password']);
00065 }
00066
00067 if (!$this->conn) {
00068 FLEA::loadClass('FLEA_Db_Exception_SqlQuery');
00069 return __THROW(new FLEA_Db_Exception_SqlQuery("mysql_connect('{$host}', '{$dsn['login']}') failed!", mysql_error(), mysql_errno()));
00070 }
00071
00072 if (!empty($dsn['database'])) {
00073 if (!$this->selectDb($dsn['database'])) { return false; }
00074 }
00075
00076 $this->_mysqlVersion = $this->getOne('SELECT VERSION()');
00077 if (isset($dsn['charset']) && $dsn['charset'] != '') {
00078 $charset = $dsn['charset'];
00079 } else {
00080 $charset = FLEA::getAppInf('databaseCharset');
00081 }
00082 if ($this->_mysqlVersion >= '4.1' && $charset != '') {
00083 if (!$this->execute("SET NAMES '" . $charset . "'")) { return false; }
00084 }
00085
00086 return true;
00087 }
00088
00089 function close()
00090 {
00091 if ($this->conn) { mysql_close($this->conn); }
00092 parent::close();
00093 }
00094
00095 function selectDb($database)
00096 {
00097 if (!mysql_select_db($database, $this->conn)) {
00098 FLEA::loadClass('FLEA_Db_Exception_SqlQuery');
00099 return __THROW(new FLEA_Db_Exception_SqlQuery("SELECT DATABASE: '{$database}' FAILED!", mysql_error($this->conn), mysql_errno($this->conn)));
00100 }
00101 return true;
00102 }
00103
00104 function execute($sql, $inputarr = null, $throw = true)
00105 {
00106 if (is_array($inputarr)) {
00107 $sql = $this->bind($sql, $inputarr);
00108 }
00109 if ($this->enableLog) {
00110 $this->log[] = $sql;
00111 log_message("sql: {$sql}", 'debug');
00112 }
00113
00114 $this->querycount++;
00115 $result = mysql_query($sql, $this->conn);
00116 if ($result !== false) {
00117 $this->lasterr = null;
00118 $this->lasterrcode = null;
00119 return $result;
00120 }
00121 $this->lasterr = mysql_error($this->conn);
00122 $this->lasterrcode = mysql_errno($this->conn);
00123
00124 if ($throw) {
00125 FLEA::loadClass('FLEA_Db_Exception_SqlQuery');
00126 __THROW(new FLEA_Db_Exception_SqlQuery($sql, $this->lasterr, $this->lasterrcode));
00127 }
00128 return false;
00129 }
00130
00131 function qstr($value)
00132 {
00133 if (is_int($value) || is_float($value)) { return $value; }
00134 if (is_bool($value)) { return $value ? $this->TRUE_VALUE : $this->FALSE_VALUE; }
00135 if (is_null($value)) { return $this->NULL_VALUE; }
00136 return "'" . mysql_real_escape_string($value, $this->conn) . "'";
00137 }
00138
00139 function qtable($tableName, $schema = null)
00140 {
00141 return $schema != '' ? "`{$schema}`.`{$tableName}`" : "`{$tableName}`";
00142 }
00143
00144 function qfield($fieldName, $tableName = null, $schema = null)
00145 {
00146 $fieldName = ($fieldName == '*') ? '*' : "`{$fieldName}`";
00147 return $tableName != '' ? $this->qtable($tableName, $schema) . '.' . $fieldName : $fieldName;
00148 }
00149
00150 function _insertId()
00151 {
00152 return mysql_insert_id($this->conn);
00153 }
00154
00155 function _affectedRows()
00156 {
00157 return mysql_affected_rows($this->conn);
00158 }
00159
00160 function fetchRow($res)
00161 {
00162 return mysql_fetch_row($res);
00163 }
00164
00165 function fetchAssoc($res)
00166 {
00167 return mysql_fetch_assoc($res);
00168 }
00169
00170 function freeRes($res)
00171 {
00172 return mysql_free_result($res);
00173 }
00174
00175 function selectLimit($sql, $length = null, $offset = null)
00176 {
00177 if (!is_null($offset)) {
00178 $sql .= " LIMIT " . (int)$offset;
00179 if (!is_null($length)) {
00180 $sql .= ', ' . (int)$length;
00181 } else {
00182 $sql .= ', 4294967294';
00183 }
00184 } elseif (!is_null($length)) {
00185 $sql .= " LIMIT " . (int)$length;
00186 }
00187 return $this->execute($sql);
00188 }
00189
00190 function metaColumns($table)
00191 {
00203 static $typeMap = array(
00204 'BIT' => 'I',
00205 'TINYINT' => 'I',
00206 'BOOL' => 'L',
00207 'BOOLEAN' => 'L',
00208 'SMALLINT' => 'I',
00209 'MEDIUMINT' => 'I',
00210 'INT' => 'I',
00211 'INTEGER' => 'I',
00212 'BIGINT' => 'I',
00213 'FLOAT' => 'N',
00214 'DOUBLE' => 'N',
00215 'DOUBLEPRECISION' => 'N',
00216 'FLOAT' => 'N',
00217 'DECIMAL' => 'N',
00218 'DEC' => 'N',
00219
00220 'DATE' => 'D',
00221 'DATETIME' => 'T',
00222 'TIMESTAMP' => 'T',
00223 'TIME' => 'T',
00224 'YEAR' => 'I',
00225
00226 'CHAR' => 'C',
00227 'NCHAR' => 'C',
00228 'VARCHAR' => 'C',
00229 'NVARCHAR' => 'C',
00230 'BINARY' => 'B',
00231 'VARBINARY' => 'B',
00232 'TINYBLOB' => 'X',
00233 'TINYTEXT' => 'X',
00234 'BLOB' => 'X',
00235 'TEXT' => 'X',
00236 'MEDIUMBLOB' => 'X',
00237 'MEDIUMTEXT' => 'X',
00238 'LONGBLOB' => 'X',
00239 'LONGTEXT' => 'X',
00240 'ENUM' => 'C',
00241 'SET' => 'C',
00242 );
00243
00244 $rs = $this->execute(sprintf($this->META_COLUMNS_SQL, $table));
00245 if (!$rs) { return false; }
00246 $retarr = array();
00247 while (($row = mysql_fetch_assoc($rs))) {
00248 $field = array();
00249 $field['name'] = $row['Field'];
00250 $type = $row['Type'];
00251
00252 $field['scale'] = null;
00253 $queryArray = false;
00254 if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $queryArray)) {
00255 $field['type'] = $queryArray[1];
00256 $field['maxLength'] = is_numeric($queryArray[2]) ? $queryArray[2] : -1;
00257 $field['scale'] = is_numeric($queryArray[3]) ? $queryArray[3] : -1;
00258 } elseif (preg_match('/^(.+)\((\d+)/', $type, $queryArray)) {
00259 $field['type'] = $queryArray[1];
00260 $field['maxLength'] = is_numeric($queryArray[2]) ? $queryArray[2] : -1;
00261 } elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $queryArray)) {
00262 $field['type'] = $queryArray[1];
00263 $arr = explode(",",$queryArray[2]);
00264 $field['enums'] = $arr;
00265 $zlen = max(array_map("strlen",$arr)) - 2;
00266 $field['maxLength'] = ($zlen > 0) ? $zlen : 1;
00267 } else {
00268 $field['type'] = $type;
00269 $field['maxLength'] = -1;
00270 }
00271 $field['simpleType'] = $typeMap[strtoupper($field['type'])];
00272
00273
00274
00275 $field['notNull'] = ($row['Null'] != 'YES');
00276 $field['primaryKey'] = ($row['Key'] == 'PRI');
00277 $field['autoIncrement'] = (strpos($row['Extra'], 'auto_increment') !== false);
00278 if ($field['autoIncrement']) { $field['simpleType'] = 'R'; }
00279 $field['binary'] = (strpos($type,'blob') !== false);
00280 $field['unsigned'] = (strpos($type,'unsigned') !== false);
00281
00282 if ($field['type'] == 'tinyint' && $field['maxLength'] == 1) {
00283 $field['simpleType'] = 'L';
00284 }
00285
00286 if (!$field['binary']) {
00287 $d = $row['Default'];
00288 if ($d != '' && $d != 'NULL') {
00289 $field['hasDefault'] = true;
00290 $field['defaultValue'] = $this->setValueByType($d, $field['simpleType']);
00291 } else {
00292 $field['hasDefault'] = false;
00293 }
00294 }
00295
00296 $field['description'] = isset($row['Comment']) ? $row['Comment'] : '';
00297
00298 $retarr[strtoupper($field['name'])] = $field;
00299 }
00300 mysql_free_result($rs);
00301 return $retarr;
00302 }
00303
00304 function metaTables($pattern = null, $schema = null)
00305 {
00306 $sql = 'SHOW TABLES';
00307 if (!empty($schema)) {
00308 $sql .= " FROM {$schema}";
00309 }
00310 if (!empty($pattern)) {
00311 $sql .= ' LIKE ' . $this->qstr($schema);
00312 }
00313 $res = $this->execute($sql, null, false);
00314 $tables = array();
00315 while (($row = $this->fetchRow($res))) {
00316 $tables[] = reset($row);
00317 }
00318 $this->freeRes($res);
00319 return $tables;
00320 }
00321
00322 }
00323
00333 class FLEA_Db_Driver_Mysqlt extends FLEA_Db_Driver_Mysql
00334 {
00335 var $HAS_TRANSACTION = true;
00336
00337 function connect($dsn = false)
00338 {
00339 parent::connect($dsn);
00340 if ($this->_mysqlVersion >= '5.0') {
00341 $this->HAS_SAVEPOINT = true;
00342 }
00343 }
00344
00345 function _startTrans()
00346 {
00347 $this->execute('START TRANSACTION');
00348 }
00349
00350 function _completeTrans($commitOnNoErrors = true)
00351 {
00352 if ($this->_hasFailedQuery == false && $commitOnNoErrors) {
00353 $this->execute('COMMIT');
00354 } else {
00355 $this->execute('ROLLBACK');
00356 }
00357 }
00358 }