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_Index
23: * @copyright Copyright (c) 2012 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: /**
28: * Abstract resource model. Can be used as base for indexer resources
29: *
30: * @category Mage
31: * @package Mage_Index
32: * @author Magento Core Team <core@magentocommerce.com>
33: */
34: abstract class Mage_Index_Model_Resource_Abstract extends Mage_Core_Model_Resource_Db_Abstract
35: {
36: const IDX_SUFFIX= '_idx';
37: const TMP_SUFFIX= '_tmp';
38:
39: /**
40: * Flag that defines if need to use "_idx" index table suffix instead of "_tmp"
41: *
42: * @var bool
43: */
44: protected $_isNeedUseIdxTable = false;
45:
46: /**
47: * Flag that defines if need to disable keys during data inserting
48: *
49: * @var bool
50: */
51: protected $_isDisableKeys = true;
52:
53: /**
54: * Whether table changes are allowed
55: *
56: * @deprecated after 1.6.1.0
57: * @var bool
58: */
59: protected $_allowTableChanges = true;
60:
61: /**
62: * Reindex all
63: *
64: * @return Mage_Index_Model_Resource_Abstract
65: */
66: public function reindexAll()
67: {
68: $this->useIdxTable(true);
69: return $this;
70: }
71:
72: /**
73: * Get DB adapter for index data processing
74: *
75: * @return Varien_Db_Adapter_Interface
76: */
77: protected function _getIndexAdapter()
78: {
79: return $this->_getWriteAdapter();
80: }
81:
82: /**
83: * Get index table name with additional suffix
84: *
85: * @param string $table
86: * @return string
87: */
88: public function getIdxTable($table = null)
89: {
90: $suffix = self::TMP_SUFFIX;
91: if ($this->_isNeedUseIdxTable) {
92: $suffix = self::IDX_SUFFIX;
93: }
94: if ($table) {
95: return $table . $suffix;
96: }
97: return $this->getMainTable() . $suffix;
98: }
99:
100: /**
101: * Synchronize data between index storage and original storage
102: *
103: * @return Mage_Index_Model_Resource_Abstract
104: */
105: public function syncData()
106: {
107: $this->beginTransaction();
108: try {
109: /**
110: * Can't use truncate because of transaction
111: */
112: $this->_getWriteAdapter()->delete($this->getMainTable());
113: $this->insertFromTable($this->getIdxTable(), $this->getMainTable(), false);
114: $this->commit();
115: } catch (Exception $e) {
116: $this->rollBack();
117: throw $e;
118: }
119: return $this;
120: }
121:
122: /**
123: * Create temporary table for index data pregeneration
124: *
125: * @deprecated since 1.5.0.0
126: * @param bool $asOriginal
127: * @return Mage_Index_Model_Resource_Abstract
128: */
129: public function cloneIndexTable($asOriginal = false)
130: {
131: return $this;
132: }
133:
134: /**
135: * Copy data from source table of read adapter to destination table of index adapter
136: *
137: * @param string $sourceTable
138: * @param string $destTable
139: * @param bool $readToIndex data migration direction (true - read=>index, false - index=>read)
140: * @return Mage_Index_Model_Resource_Abstract
141: */
142: public function insertFromTable($sourceTable, $destTable, $readToIndex = true)
143: {
144: if ($readToIndex) {
145: $sourceColumns = array_keys($this->_getWriteAdapter()->describeTable($sourceTable));
146: $targetColumns = array_keys($this->_getWriteAdapter()->describeTable($destTable));
147: } else {
148: $sourceColumns = array_keys($this->_getIndexAdapter()->describeTable($sourceTable));
149: $targetColumns = array_keys($this->_getWriteAdapter()->describeTable($destTable));
150: }
151: $select = $this->_getIndexAdapter()->select()->from($sourceTable, $sourceColumns);
152:
153: Mage::getResourceHelper('index')->insertData($this, $select, $destTable, $targetColumns, $readToIndex);
154: return $this;
155: }
156:
157: /**
158: * Insert data from select statement of read adapter to
159: * destination table related with index adapter
160: *
161: * @param Varien_Db_Select $select
162: * @param string $destTable
163: * @param array $columns
164: * @param bool $readToIndex data migration direction (true - read=>index, false - index=>read)
165: * @return Mage_Index_Model_Resource_Abstract
166: */
167: public function insertFromSelect($select, $destTable, array $columns, $readToIndex = true)
168: {
169: if ($readToIndex) {
170: $from = $this->_getWriteAdapter();
171: $to = $this->_getIndexAdapter();
172: } else {
173: $from = $this->_getIndexAdapter();
174: $to = $this->_getWriteAdapter();
175: }
176:
177: if ($from === $to) {
178: $query = $select->insertFromSelect($destTable, $columns);
179: $to->query($query);
180: } else {
181: $stmt = $from->query($select);
182: $data = array();
183: $counter = 0;
184: while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
185: $data[] = $row;
186: $counter++;
187: if ($counter>2000) {
188: $to->insertArray($destTable, $columns, $data);
189: $data = array();
190: $counter = 0;
191: }
192: }
193: if (!empty($data)) {
194: $to->insertArray($destTable, $columns, $data);
195: }
196: }
197:
198: return $this;
199: }
200:
201: /**
202: * Set or get what either "_idx" or "_tmp" suffixed temporary index table need to use
203: *
204: * @param bool $value
205: * @return bool
206: */
207: public function useIdxTable($value = null)
208: {
209: if (!is_null($value)) {
210: $this->_isNeedUseIdxTable = (bool)$value;
211: }
212: return $this->_isNeedUseIdxTable;
213: }
214:
215: /**
216: * Set or get flag that defines if need to disable keys during data inserting
217: *
218: * @param bool $value
219: * @return bool
220: */
221: public function useDisableKeys($value = null)
222: {
223: if (!is_null($value)) {
224: $this->_isDisableKeys = (bool)$value;
225: }
226: return $this->_isDisableKeys;
227: }
228:
229: /**
230: * Clean up temporary index table
231: *
232: */
233: public function clearTemporaryIndexTable()
234: {
235: $this->_getWriteAdapter()->delete($this->getIdxTable());
236: }
237:
238: /**
239: * Set whether table changes are allowed
240: *
241: * @deprecated after 1.6.1.0
242: * @param bool $value
243: * @return Mage_Index_Model_Resource_Abstract
244: */
245: public function setAllowTableChanges($value = true)
246: {
247: $this->_allowTableChanges = $value;
248: return $this;
249: }
250:
251: /**
252: * Disable Main Table keys
253: *
254: * @return Mage_Index_Model_Resource_Abstract
255: */
256: public function disableTableKeys()
257: {
258: if ($this->useDisableKeys()) {
259: $this->_getWriteAdapter()->disableTableKeys($this->getMainTable());
260: }
261: return $this;
262: }
263:
264: /**
265: * Enable Main Table keys
266: *
267: * @return Mage_Index_Model_Resource_Abstract
268: */
269: public function enableTableKeys()
270: {
271: if ($this->useDisableKeys()) {
272: $this->_getWriteAdapter()->enableTableKeys($this->getMainTable());
273: }
274: return $this;
275: }
276: }
277: