Fulltext bug fixes

This commit is contained in:
Taras Machyshyn
2018-07-13 16:52:02 +03:00
parent 2234678728
commit abc48ca76f
5 changed files with 267 additions and 6 deletions
@@ -25,16 +25,19 @@
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Driver\PDOMySql;
class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
{
public function getDatabasePlatform()
{
return new \Espo\Core\Utils\Database\DBAL\Platforms\MySqlPlatform();
}
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
{
return new \Espo\Core\Utils\Database\DBAL\Schema\MySqlSchemaManager($conn);
}
}
@@ -0,0 +1,82 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Schema;
use Doctrine\DBAL\Schema\Index as DBALIndex;
class Index extends \Doctrine\DBAL\Schema\Index
{
public function addFlag($flag)
{
$this->_flags[strtolower($flag)] = true;
return $this;
}
public function hasFlag($flag)
{
return isset($this->_flags[strtolower($flag)]);
}
public function removeFlag($flag)
{
unset($this->_flags[strtolower($flag)]);
}
public function isFullfilledBy(DBALIndex $other)
{
if (count($other->getColumns()) != count($this->getColumns())) {
return false;
}
$sameColumns = $this->spansColumns($other->getColumns());
if ($sameColumns) {
$flags = $this->getFlags();
$otherFlags = $other->getFlags();
if ( ! $this->isUnique() && !$this->isPrimary() && $flags === $otherFlags) {
return true;
} else if ($other->isPrimary() != $this->isPrimary()) {
return false;
} else if ($other->isUnique() != $this->isUnique()) {
return false;
}
if (count($flags) != count($otherFlags) || array_diff($flags, $otherFlags) !== array_diff($otherFlags, $flags)) {
return false;
}
return true;
}
return false;
}
}
@@ -0,0 +1,144 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Schema;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
class MySqlSchemaManager extends \Doctrine\DBAL\Schema\MySqlSchemaManager
{
public function createSchema()
{
$sequences = array();
if ($this->_platform->supportsSequences()) {
$sequences = $this->listSequences();
}
$tables = $this->listTables();
return new Schema($tables, $sequences, $this->createSchemaConfig());
}
public function listTables()
{
$tableNames = $this->listTableNames();
$tables = array();
foreach ($tableNames as $tableName) {
$tables[] = $this->listTableDetails($tableName);
}
return $tables;
}
public function listTableDetails($tableName)
{
$columns = $this->listTableColumns($tableName);
$foreignKeys = array();
if ($this->_platform->supportsForeignKeyConstraints()) {
$foreignKeys = $this->listTableForeignKeys($tableName);
}
$indexes = $this->listTableIndexes($tableName);
return new Table($tableName, $columns, $indexes, $foreignKeys, false, array());
}
public function listTableIndexes($table)
{
$sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
$tableIndexes = $this->_conn->fetchAll($sql);
return $this->_getPortableTableIndexesList($tableIndexes, $table);
}
protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
{
foreach($tableIndexes as $k => $v) {
$v = array_change_key_case($v, CASE_LOWER);
if($v['key_name'] == 'PRIMARY') {
$v['primary'] = true;
} else {
$v['primary'] = false;
}
if (strpos($v['index_type'], 'FULLTEXT') !== false) {
$v['flags'] = array('FULLTEXT');
}
$tableIndexes[$k] = $v;
}
$result = array();
foreach($tableIndexes as $tableIndex) {
$indexName = $keyName = $tableIndex['key_name'];
if ($tableIndex['primary']) {
$keyName = 'primary';
}
$keyName = strtolower($keyName);
if (!isset($result[$keyName])) {
$result[$keyName] = array(
'name' => $indexName,
'columns' => array($tableIndex['column_name']),
'unique' => $tableIndex['non_unique'] ? false : true,
'primary' => $tableIndex['primary'],
'flags' => isset($tableIndex['flags']) ? $tableIndex['flags'] : array(),
);
} else {
$result[$keyName]['columns'][] = $tableIndex['column_name'];
}
}
$eventManager = $this->_platform->getEventManager();
$indexes = array();
foreach($result as $indexKey => $data) {
$index = null;
$defaultPrevented = false;
if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
$eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn);
$eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs);
$defaultPrevented = $eventArgs->isDefaultPrevented();
$index = $eventArgs->getIndex();
}
if ( ! $defaultPrevented) {
$index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary'], $data['flags']);
}
if ($index) {
$indexes[$indexKey] = $index;
}
}
return $indexes;
}
}
@@ -28,9 +28,9 @@
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Schema;
class Schema extends \Doctrine\DBAL\Schema\Schema
{
/**
* Creates a new table.
*
@@ -28,11 +28,12 @@
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Schema\SchemaException;
class Table extends \Doctrine\DBAL\Schema\Table
{
/**
* @param string $columnName
* @param string $typeName
@@ -49,4 +50,35 @@ class Table extends \Doctrine\DBAL\Schema\Table
return $column;
}
public function addIndex(array $columnNames, $indexName = null, array $flags = array())
{
if($indexName == null) {
$indexName = $this->_generateIdentifierName(
array_merge(array($this->getName()), $columnNames), "idx", $this->_getMaxIdentifierLength()
);
}
return $this->_createIndex($columnNames, $indexName, false, false, $flags);
}
private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = array())
{
if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) {
throw SchemaException::indexNameInvalid($indexName);
}
foreach ($columnNames as $columnName => $indexColOptions) {
if (is_numeric($columnName) && is_string($indexColOptions)) {
$columnName = $indexColOptions;
}
if ( ! $this->hasColumn($columnName)) {
throw SchemaException::columnDoesNotExist($columnName, $this->_name);
}
}
$this->_addIndex(new Index($indexName, $columnNames, $isUnique, $isPrimary, $flags));
return $this;
}
}