- public function addIndex(
- $tableName,
- $indexName,
- $fields,
- $indexType = AdapterInterface::INDEX_TYPE_INDEX,
- $schemaName = null
- ) {
- $columns = $this->describeTable($tableName, $schemaName);
- $keyList = $this->getIndexList($tableName, $schemaName);
-
- $query = sprintf('ALTER TABLE %s', $this->quoteIdentifier($this->_getTableName($tableName, $schemaName)));
- if (isset($keyList[strtoupper($indexName)])) {
- if ($keyList[strtoupper($indexName)]['INDEX_TYPE'] == AdapterInterface::INDEX_TYPE_PRIMARY) {
- $query .= ' DROP PRIMARY KEY,';
- } else {
- $query .= sprintf(' DROP INDEX %s,', $this->quoteIdentifier($indexName));
- }
- }
-
- if (!is_array($fields)) {
- $fields = [$fields];
- }
-
- $fieldSql = [];
- foreach ($fields as $field) {
- if (!isset($columns[$field])) {
- $msg = sprintf(
- 'There is no field "%s" that you are trying to create an index on "%s"',
- $field,
- $tableName
- );
- throw new \Zend_Db_Exception($msg);
- }
- $fieldSql[] = $this->quoteIdentifier($field);
- }
- $fieldSql = implode(',', $fieldSql);
-
- switch (strtolower($indexType)) {
- case AdapterInterface::INDEX_TYPE_PRIMARY:
- $condition = 'PRIMARY KEY';
- break;
- case AdapterInterface::INDEX_TYPE_UNIQUE:
- $condition = 'UNIQUE ' . $this->quoteIdentifier($indexName);
- break;
- case AdapterInterface::INDEX_TYPE_FULLTEXT:
- $condition = 'FULLTEXT ' . $this->quoteIdentifier($indexName);
- break;
- default:
- $condition = 'INDEX ' . $this->quoteIdentifier($indexName);
- break;
- }
-
- $query .= sprintf(' ADD %s (%s)', $condition, $fieldSql);
-
- $cycle = true;
- while ($cycle === true) {
- try {
- $result = $this->rawQuery($query);
- $cycle = false;
- } catch (\Exception $e) {
- if (in_array(strtolower($indexType), ['primary', 'unique'])) {
- $match = [];
- if (preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\']+\'([\d-\.]+)\'#', $e->getMessage(), $match)) {
- $ids = explode('-', $match[1]);
- $this->_removeDuplicateEntry($tableName, $fields, $ids);
- continue;
- }
- }
- throw $e;
- }
- }
-
- $this->resetDdlCache($tableName, $schemaName);
-
- return $result;
- }