PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/CatalogIndex/Model/Mysql4/Indexer.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 669 lines | 443 code | 62 blank | 164 comment | 70 complexity | cee83688d2fd34b89de056407984eb4e MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_CatalogIndex
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Reindexer resource model
  28. *
  29. * @author Magento Core Team <core@magentocommerce.com>
  30. */
  31. class Mage_CatalogIndex_Model_Mysql4_Indexer extends Mage_Core_Model_Mysql4_Abstract
  32. {
  33. protected $_insertData = array();
  34. protected $_tableFields = array();
  35. protected $_attributeCache = array();
  36. protected function _construct()
  37. {
  38. $this->_init('catalog/product', 'entity_id');
  39. }
  40. protected function _loadAttribute($id)
  41. {
  42. if (!isset($this->_attributeCache[$id])) {
  43. $this->_attributeCache[$id] = Mage::getModel('eav/entity_attribute')->load($id);
  44. }
  45. return $this->_attributeCache[$id];
  46. }
  47. /**
  48. * Delete index data by specific conditions
  49. *
  50. * @param bool $eav clear eav index data flag
  51. * @param bool $price clear price index data flag
  52. * @param bool $minimal clear minimal price index data flag
  53. * @param bool $finalPrice clear final price index data flag
  54. * @param bool $tierPrice clear tier price index data flag
  55. * @param mixed $products applicable products
  56. * @param mixed $store applicable stores
  57. */
  58. public function clear($eav = true, $price = true, $minimal = true, $finalPrice = true, $tierPrice = true, $products = null, $store = null)
  59. {
  60. $suffix = '';
  61. $priceSuffix = '';
  62. $tables = array('eav'=>'catalogindex/eav', 'price'=>'catalogindex/price');
  63. if (!is_null($products)) {
  64. if ($products instanceof Mage_Catalog_Model_Product) {
  65. $products = $products->getId();
  66. } elseif ($products instanceof Mage_Catalog_Model_Product_Condition_Interface) {
  67. $suffix = 'entity_id IN ('.$products->getIdsSelect($this->_getWriteAdapter())->__toString().')';
  68. }
  69. else if (!is_numeric($products) && !is_array($products)) {
  70. Mage::throwException('Invalid products supplied for indexing');
  71. }
  72. if (empty($suffix)) {
  73. $suffix = $this->_getWriteAdapter()->quoteInto('entity_id in (?)', $products);
  74. }
  75. }
  76. if (!is_null($store)) {
  77. $websiteIds = array();
  78. if ($store instanceof Mage_Core_Model_Store) {
  79. $store = $store->getId();
  80. $websiteIds[] = Mage::app()->getStore($store)->getWebsiteId();
  81. } else if ($store instanceof Mage_Core_Model_Mysql4_Store_Collection) {
  82. $store = $store->getAllIds();
  83. foreach ($store as $one) {
  84. $websiteIds[] = Mage::app()->getStore($one)->getWebsiteId();
  85. }
  86. } else if (is_array($store)) {
  87. $resultStores = array();
  88. foreach ($store as $s) {
  89. if ($s instanceof Mage_Core_Model_Store) {
  90. $resultStores[] = $s->getId();
  91. $websiteIds[] = $s->getWebsiteId();
  92. } elseif (is_numeric($s)) {
  93. $websiteIds[] = Mage::app()->getStore($s)->getWebsiteId();
  94. $resultStores[] = $s;
  95. }
  96. }
  97. $store = $resultStores;
  98. }
  99. if ($suffix) {
  100. $suffix .= ' AND ';
  101. }
  102. $priceSuffix = $suffix . $this->_getWriteAdapter()->quoteInto('website_id in (?)', $websiteIds);
  103. $suffix .= $this->_getWriteAdapter()->quoteInto('store_id in (?)', $store);
  104. }
  105. if ($tierPrice) {
  106. $tables['tierPrice'] = 'catalogindex/price';
  107. $tierPrice = array(Mage::getSingleton('eav/entity_attribute')->getIdByCode('catalog_product', 'tier_price'));
  108. }
  109. if ($finalPrice) {
  110. $tables['finalPrice'] = 'catalogindex/price';
  111. $tierPrice = array(Mage::getSingleton('eav/entity_attribute')->getIdByCode('catalog_product', 'price'));
  112. }
  113. if ($minimal) {
  114. $tables['minimal'] = 'catalogindex/minimal_price';
  115. }
  116. foreach ($tables as $variable=>$table) {
  117. $variable = $$variable;
  118. $suffixToInsert = $suffix;
  119. if (in_array($table, $this->_getPriceTables())) {
  120. $suffixToInsert = $priceSuffix;
  121. }
  122. if ($variable === true) {
  123. $query = "DELETE FROM {$this->getTable($table)} ";
  124. if ($suffixToInsert) {
  125. $query .= "WHERE {$suffixToInsert}";
  126. }
  127. $this->_getWriteAdapter()->query($query);
  128. } else if (is_array($variable) && count($variable)) {
  129. $query = "DELETE FROM {$this->getTable($table)} WHERE ";
  130. $query .= $this->_getWriteAdapter()->quoteInto("attribute_id in (?)", $variable);
  131. if ($suffixToInsert) {
  132. $query .= " AND {$suffixToInsert}";
  133. }
  134. $this->_getWriteAdapter()->query($query);
  135. }
  136. }
  137. }
  138. /**
  139. * Get tables which are used for index related with price
  140. *
  141. * @return array
  142. */
  143. protected function _getPriceTables()
  144. {
  145. return array('catalogindex/price', 'catalogindex/minimal_price');
  146. }
  147. /**
  148. * Reindex data for tier prices
  149. *
  150. * @param array $products array of product ids
  151. * @param Mage_Core_Model_Store $store
  152. * @param int | null $forcedId identifier of "parent" product
  153. *
  154. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  155. */
  156. public function reindexTiers($products, $store, $forcedId = null)
  157. {
  158. $websiteId = $store->getWebsiteId();
  159. $attribute = Mage::getSingleton('eav/entity_attribute')->getIdByCode('catalog_product', 'tier_price');
  160. $this->_beginInsert(
  161. 'catalogindex/price',
  162. array('entity_id', 'attribute_id', 'value', 'website_id', 'customer_group_id', 'qty')
  163. );
  164. /**
  165. * Get information about product types
  166. * array (
  167. * $productType => array()
  168. * )
  169. */
  170. $products = Mage::getSingleton('catalogindex/retreiver')->assignProductTypes($products);
  171. if (is_null($forcedId)) {
  172. foreach ($products as $type=>$typeIds) {
  173. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  174. if ($retreiver->areChildrenIndexable(Mage_CatalogIndex_Model_Retreiver::CHILDREN_FOR_TIERS)) {
  175. foreach ($typeIds as $id) {
  176. $children = $retreiver->getChildProductIds($store, $id);
  177. if ($children) {
  178. $this->reindexTiers($children, $store, $id);
  179. }
  180. }
  181. }
  182. }
  183. }
  184. $attributeIndex = $this->getTierData($products, $store);
  185. foreach ($attributeIndex as $index) {
  186. $type = $index['type_id'];
  187. $id = (is_null($forcedId) ? $index['entity_id'] : $forcedId);
  188. if ($id && $index['value']) {
  189. if ($index['all_groups'] == 1) {
  190. foreach (Mage::getSingleton('catalogindex/retreiver')->getCustomerGroups() as $group) {
  191. $this->_insert('catalogindex/price', array(
  192. $id,
  193. $attribute,
  194. $index['value'],
  195. $websiteId,
  196. (int) $group->getId(),
  197. (int) $index['qty']
  198. ));
  199. }
  200. } else {
  201. $this->_insert('catalogindex/price', array(
  202. $id,
  203. $attribute,
  204. $index['value'],
  205. $websiteId,
  206. (int) $index['customer_group_id'],
  207. (int) $index['qty']
  208. ));
  209. }
  210. }
  211. }
  212. $this->_commitInsert('catalogindex/price');
  213. return $this;
  214. }
  215. /**
  216. * Reindex product prices
  217. *
  218. * @param array | int $products product ids
  219. * @param array $attributeIds
  220. * @param Mage_Core_Model_Store $store
  221. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  222. */
  223. public function reindexPrices($products, $attributeIds, $store)
  224. {
  225. $this->reindexAttributes($products, $attributeIds, $store, null, 'catalogindex/price', true);
  226. return $this;
  227. }
  228. /**
  229. * Reindex product final prices
  230. *
  231. * @param array $products array of product ids
  232. * @param Mage_Core_Model_Store $store
  233. * @param int | null $forcedId identifier of "parent" product
  234. *
  235. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  236. */
  237. public function reindexFinalPrices($products, $store, $forcedId = null)
  238. {
  239. $priceAttribute = Mage::getSingleton('eav/entity_attribute')->getIdByCode('catalog_product', 'price');
  240. $this->_beginInsert('catalogindex/price', array(
  241. 'entity_id',
  242. 'website_id',
  243. 'customer_group_id',
  244. 'value',
  245. 'attribute_id',
  246. 'tax_class_id'
  247. ));
  248. $productTypes = Mage::getSingleton('catalogindex/retreiver')->assignProductTypes($products);
  249. foreach ($productTypes as $type=>$products) {
  250. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  251. foreach ($products as $product) {
  252. if (is_null($forcedId)) {
  253. if ($retreiver->areChildrenIndexable(Mage_CatalogIndex_Model_Retreiver::CHILDREN_FOR_PRICES)) {
  254. $children = $retreiver->getChildProductIds($store, $product);
  255. if ($children) {
  256. $this->reindexFinalPrices($children, $store, $product);
  257. }
  258. }
  259. }
  260. foreach (Mage::getSingleton('catalogindex/retreiver')->getCustomerGroups() as $group) {
  261. $finalPrice = $retreiver->getFinalPrice($product, $store, $group);
  262. $taxClassId = $retreiver->getTaxClassId($product, $store);
  263. $id = $product;
  264. if (!is_null($forcedId)) {
  265. $id = $forcedId;
  266. }
  267. if (false !== $finalPrice && false !== $id && false !== $priceAttribute) {
  268. $this->_insert('catalogindex/price', array(
  269. $id,
  270. $store->getWebsiteId(),
  271. $group->getId(),
  272. $finalPrice,
  273. $priceAttribute,
  274. $taxClassId
  275. ));
  276. }
  277. }
  278. }
  279. }
  280. $this->_commitInsert('catalogindex/price');
  281. return $this;
  282. }
  283. /**
  284. * Reindex product minimal prices
  285. *
  286. * @param array $products array of product ids
  287. * @param Mage_Core_Model_Store $store
  288. *
  289. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  290. */
  291. public function reindexMinimalPrices($products, $store)
  292. {
  293. $this->_beginInsert('catalogindex/minimal_price', array(
  294. 'website_id',
  295. 'entity_id',
  296. 'customer_group_id',
  297. 'value',
  298. 'tax_class_id'
  299. ));
  300. $this->clear(false, false, true, false, false, $products, $store);
  301. $products = Mage::getSingleton('catalogindex/retreiver')->assignProductTypes($products);
  302. foreach ($products as $type=>$typeIds) {
  303. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  304. foreach ($typeIds as $id) {
  305. $minimal = array();
  306. if ($retreiver->areChildrenIndexable(Mage_CatalogIndex_Model_Retreiver::CHILDREN_FOR_PRICES)) {
  307. $children = $retreiver->getChildProductIds($store, $id);
  308. if ($children) {
  309. $minimal = $this->getMinimalPrice(array($type=>$children), $store);
  310. }
  311. } else {
  312. $minimal = $this->getMinimalPrice(array($type=>array($id)), $store);
  313. }
  314. if (is_array($minimal)) {
  315. foreach ($minimal as $price) {
  316. if (!isset($price['tax_class_id'])) {
  317. $price['tax_class_id'] = 0;
  318. }
  319. $this->_insert('catalogindex/minimal_price', array(
  320. $store->getWebsiteId(),
  321. $id,
  322. $price['customer_group_id'],
  323. $price['minimal_value'],
  324. $price['tax_class_id']
  325. ));
  326. }
  327. }
  328. }
  329. }
  330. $this->_commitInsert('catalogindex/minimal_price');
  331. return $this;
  332. }
  333. /**
  334. * Reindex attributes data
  335. *
  336. * @param array $products
  337. * @param array $attributeIds
  338. * @param mixed $store
  339. * @param int|null $forcedId
  340. * @param string $table
  341. * @param bool $storeIsWebsite
  342. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  343. */
  344. public function reindexAttributes($products, $attributeIds, $store, $forcedId = null, $table = 'catalogindex/eav', $storeIsWebsite = false)
  345. {
  346. $storeField = 'store_id';
  347. $websiteId = null;
  348. if ($storeIsWebsite) {
  349. $storeField = 'website_id';
  350. if ($store instanceof Mage_Core_Model_Store) {
  351. $websiteId = $store->getWebsiteId();
  352. } else {
  353. $websiteId = Mage::app()->getStore($store)->getWebsiteId();
  354. }
  355. }
  356. $this->_beginInsert($table, array('entity_id', 'attribute_id', 'value', $storeField));
  357. $products = Mage::getSingleton('catalogindex/retreiver')->assignProductTypes($products);
  358. if (is_null($forcedId)) {
  359. foreach ($products as $type=>$typeIds) {
  360. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  361. if ($retreiver->areChildrenIndexable(Mage_CatalogIndex_Model_Retreiver::CHILDREN_FOR_ATTRIBUTES)) {
  362. foreach ($typeIds as $id) {
  363. $children = $retreiver->getChildProductIds($store, $id);
  364. if ($children) {
  365. $this->reindexAttributes($children, $attributeIds, $store, $id, $table, $storeIsWebsite);
  366. }
  367. }
  368. }
  369. }
  370. }
  371. $attributeIndex = $this->getProductData($products, $attributeIds, $store);
  372. foreach ($attributeIndex as $index) {
  373. $type = $index['type_id'];
  374. $id = (is_null($forcedId) ? $index['entity_id'] : $forcedId);
  375. if ($id && $index['attribute_id'] && isset($index['value'])) {
  376. $attribute = $this->_loadAttribute($index['attribute_id']);
  377. if ($attribute->getFrontendInput() == 'multiselect') {
  378. $index['value'] = explode(',', $index['value']);
  379. }
  380. if (is_array($index['value'])) {
  381. foreach ($index['value'] as $value) {
  382. $this->_insert($table, array(
  383. $id,
  384. $index['attribute_id'],
  385. $value,
  386. (is_null($websiteId) ? $store->getId() : $websiteId)
  387. ));
  388. }
  389. } else {
  390. $this->_insert($table, array(
  391. $id,
  392. $index['attribute_id'],
  393. $index['value'],
  394. (is_null($websiteId) ? $store->getId() : $websiteId)
  395. ));
  396. }
  397. }
  398. }
  399. $this->_commitInsert($table);
  400. return $this;
  401. }
  402. /**
  403. * Get tier prices data by set of products
  404. *
  405. * @param array $products
  406. * @param Mage_Core_Model_Store $store
  407. * @return array
  408. */
  409. public function getTierData($products, $store){
  410. $result = array();
  411. foreach ($products as $type=>$typeIds) {
  412. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  413. $byType = $retreiver->getTierPrices($typeIds, $store);
  414. if ($byType) {
  415. $result = array_merge($result, $byType);
  416. }
  417. }
  418. return $result;
  419. }
  420. /**
  421. * Get minimal prices by set of the products
  422. *
  423. * @param arary $products
  424. * @param Mage_Core_Model_Store $store
  425. * @return array
  426. */
  427. public function getMinimalPrice($products, $store)
  428. {
  429. $result = array();
  430. foreach ($products as $type=>$typeIds) {
  431. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  432. $byType = $retreiver->getMinimalPrice($typeIds, $store);
  433. if ($byType) {
  434. $result = array_merge($result, $byType);
  435. }
  436. }
  437. return $result;
  438. }
  439. /**
  440. * Get data for products
  441. *
  442. * @param array $products
  443. * @param array $attributeIds
  444. * @param Mage_Core_Model_Store $store
  445. * @return array
  446. */
  447. public function getProductData($products, $attributeIds, $store){
  448. $result = array();
  449. foreach ($products as $type=>$typeIds) {
  450. $retreiver = Mage::getSingleton('catalogindex/retreiver')->getRetreiver($type);
  451. $byType = $retreiver->getAttributeData($typeIds, $attributeIds, $store);
  452. if ($byType) {
  453. $result = array_merge($result, $byType);
  454. }
  455. }
  456. return $result;
  457. }
  458. /**
  459. * Prepare base information for data insert
  460. *
  461. * @param string $table
  462. * @param array $fields
  463. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  464. */
  465. protected function _beginInsert($table, $fields){
  466. $this->_tableFields[$table] = $fields;
  467. return $this;
  468. }
  469. /**
  470. * Put data into table
  471. *
  472. * @param string $table
  473. * @param bool $forced
  474. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  475. */
  476. protected function _commitInsert($table, $forced = true){
  477. if (isset($this->_insertData[$table]) && count($this->_insertData[$table]) && ($forced || count($this->_insertData[$table]) >= 100)) {
  478. $query = 'REPLACE INTO ' . $this->getTable($table) . ' (' . implode(', ', $this->_tableFields[$table]) . ') VALUES ';
  479. $separator = '';
  480. foreach ($this->_insertData[$table] as $row) {
  481. $rowString = $this->_getWriteAdapter()->quoteInto('(?)', $row);
  482. $query .= $separator . $rowString;
  483. $separator = ', ';
  484. }
  485. $this->_getWriteAdapter()->query($query);
  486. $this->_insertData[$table] = array();
  487. }
  488. return $this;
  489. }
  490. /**
  491. * Insert data to table
  492. *
  493. * @param string $table
  494. * @param array $data
  495. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  496. */
  497. protected function _insert($table, $data) {
  498. $this->_insertData[$table][] = $data;
  499. $this->_commitInsert($table, false);
  500. return $this;
  501. }
  502. /**
  503. * Add price columns for catalog product flat table
  504. *
  505. * @param Varien_Object $object
  506. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  507. */
  508. public function prepareCatalogProductFlatColumns(Varien_Object $object)
  509. {
  510. $columns = $object->getColumns();
  511. foreach (Mage::getSingleton('catalogindex/retreiver')->getCustomerGroups() as $group) {
  512. $columnName = 'display_price_group_' . $group->getId();
  513. $columns[$columnName] = array(
  514. 'type' => 'decimal(12,4)',
  515. 'unsigned' => false,
  516. 'is_null' => true,
  517. 'default' => null,
  518. 'extra' => null
  519. );
  520. }
  521. $object->setColumns($columns);
  522. return $this;
  523. }
  524. /**
  525. * Add price indexes for catalog product flat table
  526. *
  527. * @param Varien_Object $object
  528. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  529. */
  530. public function prepareCatalogProductFlatIndexes(Varien_Object $object)
  531. {
  532. $indexes = $object->getIndexes();
  533. foreach (Mage::getSingleton('catalogindex/retreiver')->getCustomerGroups() as $group) {
  534. $columnName = 'display_price_group_' . $group->getId();
  535. $indexName = 'IDX_DISPLAY_PRICE_GROUP_' . $group->getId();
  536. $indexes[$indexName] = array(
  537. 'type' => 'index',
  538. 'fields' => array($columnName)
  539. );
  540. }
  541. $object->setIndexes($indexes);
  542. return $this;
  543. }
  544. /**
  545. * Update prices for Catalog Product flat
  546. *
  547. * @param int $storeId
  548. * @param string $tableName
  549. * @return Mage_CatalogIndex_Model_Mysql4_Indexer
  550. */
  551. public function updateCatalogProductFlat($storeId, $productIds = null, $tableName = null)
  552. {
  553. if (is_null($tableName)) {
  554. $tableName = $this->getTable('catalog/product_flat') . '_' . $storeId;
  555. }
  556. $addChildData = Mage::helper('catalog/product_flat')->isAddChildData();
  557. $priceAttribute = Mage::getSingleton('eav/entity_attribute')
  558. ->getIdByCode('catalog_product', 'price');
  559. $websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
  560. foreach (Mage::getSingleton('catalogindex/retreiver')->getCustomerGroups() as $group) {
  561. $columnName = 'display_price_group_' . $group->getId();
  562. /**
  563. * Update prices of main products in flat table
  564. */
  565. $select = $this->_getWriteAdapter()->select()
  566. ->join(
  567. array('p' => $this->getTable('catalogindex/price')),
  568. "`e`.`entity_id`=`p`.`entity_id`"
  569. . " AND `p`.`attribute_id`={$priceAttribute}"
  570. . " AND `p`.`customer_group_id`={$group->getId()}"
  571. . " AND `p`.`website_id`={$websiteId}",
  572. array($columnName => 'value'));
  573. if ($addChildData) {
  574. $select->where('e.is_child=?', 0);
  575. }
  576. if ($productIds instanceof Mage_Catalog_Model_Product_Condition_Interface) {
  577. $select->where('e.entity_id IN ('.$productIds->getIdsSelect($this->_getWriteAdapter())->__toString().')');
  578. } elseif (!is_null($productIds)) {
  579. $select->where("e.entity_id IN(?)", $productIds);
  580. }
  581. $sql = $select->crossUpdateFromSelect(array('e' => $tableName));
  582. $this->_getWriteAdapter()->query($sql);
  583. if ($addChildData) {
  584. /**
  585. * Update prices for children products in flat table
  586. */
  587. $select = $this->_getWriteAdapter()->select()
  588. ->join(
  589. array('p' => $this->getTable('catalogindex/price')),
  590. "`e`.`child_id`=`p`.`entity_id`"
  591. . " AND `p`.`attribute_id`={$priceAttribute}"
  592. . " AND `p`.`customer_group_id`={$group->getId()}"
  593. . " AND `p`.`website_id`={$websiteId}",
  594. array($columnName => 'value'))
  595. ->where('e.is_child=?', 1);
  596. if ($productIds instanceof Mage_Catalog_Model_Product_Condition_Interface) {
  597. $select->where('e.child_id IN ('.$productIds->getIdsSelect($this->_getWriteAdapter())->__toString().')');
  598. } elseif (!is_null($productIds)) {
  599. $select->where("e.child_id IN(?)", $productIds);
  600. }
  601. $sql = $select->crossUpdateFromSelect(array('e' => $tableName));
  602. $this->_getWriteAdapter()->query($sql);
  603. }
  604. }
  605. return $this;
  606. }
  607. }