00001 <?php
00002 class Varien_Db_Select extends Zend_Db_Select
00003 {
00004
00005
00006
00007
00008
00009 public function __construct(Zend_Db_Adapter_Abstract $adapter)
00010 {
00011 parent::__construct($adapter);
00012 }
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 public function where($cond, $value = null, $type = null)
00047 {
00048 if (is_null($value) && is_null($type)) {
00049 $value = '';
00050 }
00051 if (is_array($value)) {
00052 $cond = $this->_adapter->quoteInto($cond, $value);
00053 $value = null;
00054 }
00055 return parent::where($cond, $value, $type);
00056 }
00057
00058
00059
00060
00061
00062
00063 public function resetJoinLeft()
00064 {
00065 foreach ($this->_parts[self::FROM] as $tableId => $tableProp) {
00066 if ($tableProp['joinType'] == self::LEFT_JOIN) {
00067 $useJoin = false;
00068 foreach ($this->_parts[self::COLUMNS] as $columnEntry) {
00069 list($correlationName, $column) = $columnEntry;
00070 if ($column instanceof Zend_Db_Expr) {
00071 if ($this->_findTableInCond($tableId, $column)
00072 || $this->_findTableInCond($tableProp['tableName'], $column)) {
00073 $useJoin = true;
00074 }
00075 }
00076 else {
00077 if ($correlationName == $tableId) {
00078 $useJoin = true;
00079 }
00080 }
00081 }
00082 foreach ($this->_parts[self::WHERE] as $where) {
00083 if ($this->_findTableInCond($tableId, $where)
00084 || $this->_findTableInCond($tableProp['tableName'], $where)) {
00085 $useJoin = true;
00086 }
00087 }
00088
00089 $joinUseInCond = $useJoin;
00090 $joinInTables = array();
00091
00092 foreach ($this->_parts[self::FROM] as $tableCorrelationName => $table) {
00093 if ($tableCorrelationName == $tableId) {
00094 continue;
00095 }
00096 if (!empty($table['joinCondition'])) {
00097 if ($this->_findTableInCond($tableId, $table['joinCondition'])
00098 || $this->_findTableInCond($tableProp['tableName'], $table['joinCondition'])) {
00099 $useJoin = true;
00100 $joinInTables[] = $tableCorrelationName;
00101 }
00102 }
00103 }
00104
00105 if (!$useJoin) {
00106 unset($this->_parts[self::FROM][$tableId]);
00107 }
00108 else {
00109 $this->_parts[self::FROM][$tableId]['useInCond'] = $joinUseInCond;
00110 $this->_parts[self::FROM][$tableId]['joinInTables'] = $joinInTables;
00111 }
00112 }
00113 }
00114
00115 $this->_resetJoinLeft();
00116
00117 return $this;
00118 }
00119
00120 protected function _resetJoinLeft()
00121 {
00122 foreach ($this->_parts[self::FROM] as $tableId => $tableProp) {
00123 if ($tableProp['joinType'] == self::LEFT_JOIN) {
00124 if ($tableProp['useInCond']) {
00125 continue;
00126 }
00127
00128 $used = false;
00129 foreach ($tableProp['joinInTables'] as $table) {
00130 if (isset($this->_parts[self::FROM][$table])) {
00131 $used = true;
00132 }
00133 }
00134
00135 if (!$used) {
00136 unset($this->_parts[self::FROM][$tableId]);
00137 return $this->_resetJoinLeft();
00138 }
00139 }
00140 }
00141
00142 return $this;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152 protected function _findTableInCond($table, $cond)
00153 {
00154 $quote = $this->_adapter->getQuoteIdentifierSymbol();
00155
00156 if (strpos($cond, $quote . $table . $quote . '.') !== false) {
00157 return true;
00158 }
00159
00160 $position = 0;
00161 $result = 0;
00162 $needle = array();
00163 while (is_integer($result)) {
00164 $result = strpos($cond, $table . '.', $position);
00165
00166 if (is_integer($result)) {
00167 $needle[] = $result;
00168 $position = ($result + strlen($table) + 1);
00169 }
00170 }
00171
00172 if (!$needle) {
00173 return false;
00174 }
00175
00176 foreach ($needle as $position) {
00177 if ($position == 0) {
00178 return true;
00179 }
00180 if (!preg_match('#[a-z0-9_]#is', substr($cond, $position - 1, 1))) {
00181 return true;
00182 }
00183 }
00184
00185 return false;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 public function crossUpdateFromSelect($table) {
00195 if (!is_array($table)) {
00196 $table = array($table => $table);
00197 }
00198 $keys = array_keys($table);
00199 $tableAlias = $keys[0];
00200 $tableName = $table[$keys[0]];
00201
00202 $sql = "UPDATE `{$tableName}`";
00203 if ($tableAlias != $tableName) {
00204 $sql .= " AS `{$tableAlias}`";
00205 }
00206
00207
00208 $from = array();
00209
00210 foreach ($this->_parts[self::FROM] as $correlationName => $table) {
00211 $tmp = '';
00212 $tmp .= ' ' . strtoupper($table['joinType']) . ' ';
00213
00214 $tmp .= $this->_getQuotedSchema($table['schema']);
00215 $tmp .= $this->_getQuotedTable($table['tableName'], $correlationName);
00216
00217
00218 if (! empty($table['joinCondition'])) {
00219 $tmp .= ' ' . self::SQL_ON . ' ' . $table['joinCondition'];
00220 }
00221
00222
00223 $from[] = $tmp;
00224 }
00225
00226
00227 if (!empty($from)) {
00228 $sql .= implode("\n", $from);
00229 }
00230
00231
00232 $columns = array();
00233 foreach ($this->_parts[self::COLUMNS] as $columnEntry) {
00234 list($correlationName, $column, $alias) = $columnEntry;
00235 if (empty($alias)) {
00236 $alias = $column;
00237 }
00238 if (!$column instanceof Zend_Db_Expr && !empty($correlationName)) {
00239 $column = $this->_adapter->quoteIdentifier(array($correlationName, $column));
00240 }
00241 $columns[] = $this->_adapter->quoteIdentifier(array($tableAlias, $alias))
00242 . " = {$column}";
00243 }
00244
00245 $sql .= "\n SET " . implode(', ', $columns) . "\n";
00246
00247
00248 $sql = $this->_renderWhere($sql);
00249
00250 return $sql;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 public function insertFromSelect($tableName, $fields = array(), $onDuplicate = true) {
00262 $sql = "INSERT INTO `{$tableName}` ";
00263 if ($fields) {
00264 $sql .= "(`".join('`,`', $fields) . "`) ";
00265 }
00266
00267 $sql .= $this->assemble();
00268
00269 if ($onDuplicate && $fields) {
00270 $sql .= " ON DUPLICATE KEY UPDATE";
00271 $updateFields = array();
00272 foreach ($fields as $field) {
00273 $field = $this->_adapter->quoteIdentifier($field);
00274 $updateFields[] = "{$field}=VALUES({$field})";
00275 }
00276 $sql .= " " . join(', ', $updateFields);
00277 }
00278
00279 return $sql;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 public function deleteFromSelect($table) {
00289 $partsInit = self::$_partsInit;
00290 unset($partsInit[self::DISTINCT]);
00291 unset($partsInit[self::COLUMNS]);
00292
00293 $sql = 'DELETE ' . $table;
00294 foreach (array_keys($partsInit) as $part) {
00295 $method = '_render' . ucfirst($part);
00296 if (method_exists($this, $method)) {
00297 $sql = $this->$method($sql);
00298 }
00299 }
00300 return $sql;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310 public function setPart($part, $value)
00311 {
00312 $part = strtolower($part);
00313 if (!array_key_exists($part, $this->_parts)) {
00314 throw new Zend_Db_Select_Exception("Invalid Select part '$part'");
00315 }
00316 $this->_parts[$part] = $value;
00317 return $this;
00318 }
00319 }