00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 class Varien_Db_Adapter_Mysqli extends Zend_Db_Adapter_Mysqli
00029 {
00030 const ISO_DATE_FORMAT = 'yyyy-MM-dd';
00031 const ISO_DATETIME_FORMAT = 'yyyy-MM-dd HH-mm-ss';
00032
00033
00034
00035
00036
00037
00038
00039 protected function _connect()
00040 {
00041 if ($this->_connection) {
00042 return;
00043 }
00044 if (!extension_loaded('mysqli')) {
00045 throw new Zend_Db_Adapter_Exception('mysqli extension is not installed');
00046 }
00047
00048
00049 @$conn = new mysqli();
00050 if (false===$conn || mysqli_connect_errno()) {
00051 throw new Zend_Db_Adapter_Mysqli_Exception(mysqli_connect_errno());
00052 }
00053
00054 $conn->init();
00055 $conn->options(MYSQLI_OPT_LOCAL_INFILE, true);
00056 #$conn->options(MYSQLI_CLIENT_MULTI_QUERIES, true);
00057
00058 $port = !empty($this->_config['port']) ? $this->_config['port'] : null;
00059 $socket = !empty($this->_config['unix_socket']) ? $this->_config['unix_socket'] : null;
00060
00061 if (strpos($this->_config['host'], '/')!==false) {
00062 $socket = $this->_config['host'];
00063 $this->_config['host'] = null;
00064 } elseif (strpos($this->_config['host'], ':')!==false) {
00065 list($this->_config['host'], $port) = explode(':', $this->_config['host']);
00066 }
00067
00068 #echo "<pre>".print_r($this->_config,1)."</pre>"; die;
00069 @$conn->real_connect(
00070 $this->_config['host'],
00071 $this->_config['username'],
00072 $this->_config['password'],
00073 $this->_config['dbname'],
00074 $port,
00075 $socket
00076 );
00077 if (mysqli_connect_errno()) {
00078 throw new Zend_Db_Adapter_Mysqli_Exception(mysqli_connect_error());
00079 }
00080
00081 $this->_connection = $conn;
00082
00083
00084 $this->_connection->query("SET SQL_MODE=''");
00085 }
00086
00087 public function raw_query($sql)
00088 {
00089 do {
00090 $retry = false;
00091 $tries = 0;
00092 try {
00093 $this->clear_result();
00094 $result = $this->getConnection()->query($sql);
00095 $this->clear_result();
00096 }
00097 catch (Exception $e) {
00098 if ($e->getMessage()=='SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction') {
00099 $retry = true;
00100 } else {
00101 throw $e;
00102 }
00103 $tries++;
00104 }
00105 } while ($retry && $tries<10);
00106
00107 return $result;
00108 }
00109
00110
00111 public function convertDate($date)
00112 {
00113 if ($date instanceof Zend_Date) {
00114 return $date->toString(self::ISO_DATE_FORMAT);
00115 }
00116 return strftime('%Y-%m-%d', strtotime($date));
00117 }
00118
00119 public function convertDateTime($datetime)
00120 {
00121 if ($datetime instanceof Zend_Date) {
00122 return $datetime->toString(self::ISO_DATETIME_FORMAT);
00123 }
00124 return strftime('%Y-%m-%d %H:%M:%S', strtotime($datetime));
00125 }
00126
00127
00128
00129 public function raw_fetchRow($sql, $field=null)
00130 {
00131 if (!$result = $this->raw_query($sql)) {
00132 return false;
00133 }
00134 if (!$row = $result->fetch_assoc()) {
00135 return false;
00136 }
00137 if (empty($field)) {
00138 return $row;
00139 } else {
00140 return isset($row[$field]) ? $row[$field] : false;
00141 }
00142 }
00143
00144 public function multi_query($sql)
00145 {
00146 $this->beginTransaction();
00147 try {
00148 $this->clear_result();
00149 if ($this->getConnection()->multi_query($sql)) {
00150 $this->clear_result();
00151 $this->commit();
00152 } else {
00153 throw new Zend_Db_Adapter_Mysqli_Exception('multi_query: '.$this->getConnection()->error);
00154 }
00155 } catch (Exception $e) {
00156 $this->rollback();
00157 throw $e;
00158 }
00159
00160 return true;
00161 }
00162
00163 public function clear_result()
00164 {
00165 while ($this->getConnection()->next_result()) {
00166 if ($result = $this->getConnection()->store_result()) {
00167 $result->free_result();
00168 }
00169 elseif($this->getConnection()->error) {
00170 throw new Zend_Db_Adapter_Mysqli_Exception('clear_result: '.$this->getConnection()->error);
00171 }
00172 }
00173
00174 }
00175
00176 public function dropForeignKey($table, $fk)
00177 {
00178 $create = $this->raw_fetchRow("show create table `$table`", 'Create Table');
00179 if (strpos($create, "CONSTRAINT `$fk` FOREIGN KEY (")!==false) {
00180 return $this->raw_query("ALTER TABLE `$table` DROP FOREIGN KEY `$fk`");
00181 }
00182 return true;
00183 }
00184
00185 public function dropKey($table, $key)
00186 {
00187 $create = $this->raw_fetchRow("show create table `$table`", 'Create Table');
00188 if (strpos($create, "KEY `$key` (")!==false) {
00189 return $this->raw_query("ALTER TABLE `$table` DROP KEY `$key`");
00190 }
00191 return true;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 public function addConstraint($fkName, $tableName, $keyName, $refTableName, $refKeyName, $onDelete = 'cascade', $onUpdate = 'cascade')
00207 {
00208 if (substr($fkName, 0, 3) != 'FK_') {
00209 $fkName = 'FK_' . $fkName;
00210 }
00211
00212 $sql = 'ALTER TABLE `'.$tableName.'` ADD CONSTRAINT `'.$fkName.'`'
00213 . 'FOREIGN KEY (`'.$keyName.'`) REFERENCES `'.$refTableName.'` (`'.$refKeyName.'`)';
00214 if (!is_null($onDelete)) {
00215 $sql .= ' ON DELETE ' . strtoupper($onDelete);
00216 }
00217 if (!is_null($onUpdate)) {
00218 $sql .= ' ON UPDATE ' . strtoupper($onUpdate);
00219 }
00220
00221 return $this->raw_query($sql);
00222 }
00223
00224 public function tableColumnExists($tableName, $columnName)
00225 {
00226 foreach ($this->fetchAll('DESCRIBE `'.$tableName.'`') as $row) {
00227 if ($row['Field'] == $columnName) {
00228 return true;
00229 }
00230 }
00231 return false;
00232 }
00233
00234 public function addColumn($tableName, $columnName, $definition)
00235 {
00236 if ($this->tableColumnExists($tableName, $columnName)) {
00237 return true;
00238 }
00239 $result = $this->raw_query("alter table `$tableName` add column `$columnName` ".$definition);
00240 return $result;
00241 }
00242
00243 public function dropColumn($tableName, $columnName)
00244 {
00245 if (!$this->tableColumnExists($tableName, $columnName)) {
00246 return true;
00247 }
00248
00249 $create = $this->raw_fetchRow('SHOW CREATE TABLE `'.$tableName.'`', 'Create Table');
00250
00251 $alterDrop = array();
00252 $alterDrop[] = 'DROP COLUMN `'.$columnName.'`';
00253
00254
00255
00256
00257 $matches = array();
00258 preg_match_all('/CONSTRAINT `([^`]*)` FOREIGN KEY \(`([^`]*)`\)/', $create, $matches, PREG_SET_ORDER);
00259 foreach ($matches as $match) {
00260 if ($match[2] == $columnName) {
00261 $alterDrop[] = 'DROP FOREIGN KEY `'.$match[1].'`';
00262 }
00263 }
00264
00265 return $this->raw_query('ALTER TABLE `'.$tableName.'` ' . join(', ', $alterDrop));
00266 }
00267
00268
00269
00270
00271
00272
00273 public function select()
00274 {
00275 return new Varien_Db_Select($this);
00276 }
00277 }