Update Search Manipulater
This commit is contained in:
parent
9d5ea9393d
commit
6066af5841
|
@ -1,3 +1,6 @@
|
||||||
DataObject:
|
DataObject:
|
||||||
extensions:
|
extensions:
|
||||||
- 'SearchUpdater_ObjectHandler'
|
- 'SearchUpdater_ObjectHandler'
|
||||||
|
Database:
|
||||||
|
extensions:
|
||||||
|
- 'SearchManipulateCaptureExtension'
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Captures;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\Connect\MySQLDatabase;
|
||||||
|
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
||||||
|
|
||||||
|
class SearchManipulateCapture_MySQLDatabase extends MySQLDatabase {
|
||||||
|
|
||||||
|
public $isManipulationCapture = true;
|
||||||
|
|
||||||
|
public function manipulate($manipulation) {
|
||||||
|
$res = parent::manipulate($manipulation);
|
||||||
|
SearchUpdater::handle_manipulation($manipulation);
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace SilverStripe\FullTextSearch\Search\Processors;
|
namespace SilverStripe\FullTextSearch\Search\Processors;
|
||||||
|
|
||||||
class SearchUpdateImmediateProcessor extends SearchUpdateProcessor
|
class SearchUpdateImmediateProcessor extends SearchUpdateProcessor
|
||||||
{
|
{
|
||||||
public function triggerProcessing()
|
public function triggerProcessing()
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace SilverStripe\FullTextSearch\Search\Processors;
|
namespace SilverStripe\FullTextSearch\Search\Processors;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant;
|
||||||
|
use SilverStripe\FullTextSearch\Search\FullTextSearch;
|
||||||
|
|
||||||
abstract class SearchUpdateProcessor
|
abstract class SearchUpdateProcessor
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +39,7 @@ abstract class SearchUpdateProcessor
|
||||||
|
|
||||||
public function addDirtyIDs($class, $statefulids, $index)
|
public function addDirtyIDs($class, $statefulids, $index)
|
||||||
{
|
{
|
||||||
$base = ClassInfo::baseDataClass($class);
|
$base = DataObject::getSchema()->baseDataClass($class);
|
||||||
$forclass = isset($this->dirty[$base]) ? $this->dirty[$base] : array();
|
$forclass = isset($this->dirty[$base]) ? $this->dirty[$base] : array();
|
||||||
|
|
||||||
foreach ($statefulids as $statefulid) {
|
foreach ($statefulids as $statefulid) {
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
namespace SilverStripe\FullTextSearch\Search\Updaters;
|
namespace SilverStripe\FullTextSearch\Search\Updaters;
|
||||||
|
|
||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\Core\Object;
|
||||||
|
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Search\FullTextSearch;
|
||||||
|
use SilverStripe\FullTextSearch\Search\SearchIntrospection;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
use SilverStripe\FullTextSearch\Search\Processors\SearchUpdateImmediateProcessor;
|
||||||
|
use SilverStripe\FullTextSearch\Captures\SearchManipulateCapture_MySQLDatabase;
|
||||||
/**
|
/**
|
||||||
* This class is responsible for capturing changes to DataObjects and triggering index updates of the resulting dirty index
|
* This class is responsible for capturing changes to DataObjects and triggering index updates of the resulting dirty index
|
||||||
* items.
|
* items.
|
||||||
|
@ -15,8 +23,6 @@ use SilverStripe\ORM\DB;
|
||||||
*
|
*
|
||||||
* TODO: The way we bind in is awful hacky.
|
* TODO: The way we bind in is awful hacky.
|
||||||
*/
|
*/
|
||||||
use SilverStripe\Core\Object;
|
|
||||||
use SilverStripe\ORM\DataExtension;
|
|
||||||
|
|
||||||
class SearchUpdater extends Object
|
class SearchUpdater extends Object
|
||||||
{
|
{
|
||||||
|
@ -27,31 +33,13 @@ class SearchUpdater extends Object
|
||||||
{
|
{
|
||||||
global $databaseConfig;
|
global $databaseConfig;
|
||||||
|
|
||||||
$current = DB::getConn();
|
$current = DB::get_conn();
|
||||||
if (!$current || !$current->currentDatabase() || @$current->isManipulationCapture) {
|
if (!$current || !$current->getSelectedDatabase() || @$current->isManipulationCapture) {
|
||||||
return;
|
return;
|
||||||
} // If not yet set, or its already captured, just return
|
} // If not yet set, or its already captured, just return
|
||||||
|
|
||||||
$type = get_class($current);
|
|
||||||
$file = TEMP_FOLDER."/.cache.SMC.$type";
|
|
||||||
|
|
||||||
if (!is_file($file)) {
|
|
||||||
file_put_contents($file, "<?php
|
|
||||||
class SearchManipulateCapture_$type extends $type {
|
|
||||||
public \$isManipulationCapture = true;
|
|
||||||
|
|
||||||
function manipulate(\$manipulation) {
|
|
||||||
\$res = parent::manipulate(\$manipulation);
|
|
||||||
SearchUpdater::handle_manipulation(\$manipulation);
|
|
||||||
return \$res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
");
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once($file);
|
|
||||||
$dbClass = 'SearchManipulateCapture_'.$type;
|
|
||||||
|
|
||||||
|
$dbClass = SearchManipulateCapture_MySQLDatabase::class;
|
||||||
/** @var SS_Database $captured */
|
/** @var SS_Database $captured */
|
||||||
$captured = new $dbClass($databaseConfig);
|
$captured = new $dbClass($databaseConfig);
|
||||||
|
|
||||||
|
@ -63,8 +51,8 @@ class SearchUpdater extends Object
|
||||||
}
|
}
|
||||||
|
|
||||||
// The connection might have had it's name changed (like if we're currently in a test)
|
// The connection might have had it's name changed (like if we're currently in a test)
|
||||||
$captured->selectDatabase($current->currentDatabase());
|
$captured->selectDatabase($current->getSelectedDatabase());
|
||||||
DB::setConn($captured);
|
DB::set_conn($captured);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static $registered = false;
|
public static $registered = false;
|
||||||
|
@ -85,7 +73,9 @@ class SearchUpdater extends Object
|
||||||
{
|
{
|
||||||
// First, extract any state that is in the manipulation itself
|
// First, extract any state that is in the manipulation itself
|
||||||
foreach ($manipulation as $table => $details) {
|
foreach ($manipulation as $table => $details) {
|
||||||
$manipulation[$table]['class'] = $table;
|
if (!isset($manipulation[$table]['class'])) {
|
||||||
|
$manipulation[$table]['class'] = DataObject::getSchema()->tableClass($table);
|
||||||
|
}
|
||||||
$manipulation[$table]['state'] = array();
|
$manipulation[$table]['state'] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +95,7 @@ class SearchUpdater extends Object
|
||||||
$class = $details['class'];
|
$class = $details['class'];
|
||||||
$fields = isset($details['fields']) ? $details['fields'] : array();
|
$fields = isset($details['fields']) ? $details['fields'] : array();
|
||||||
|
|
||||||
$base = ClassInfo::baseDataClass($class);
|
$base = DataObject::getSchema()->baseDataClass($class);
|
||||||
$key = "$id:$base:".serialize($state);
|
$key = "$id:$base:".serialize($state);
|
||||||
|
|
||||||
$statefulids = array(array('id' => $id, 'state' => $state));
|
$statefulids = array(array('id' => $id, 'state' => $state));
|
||||||
|
@ -166,7 +156,7 @@ class SearchUpdater extends Object
|
||||||
foreach ($dirtyids as $dirtyclass => $ids) {
|
foreach ($dirtyids as $dirtyclass => $ids) {
|
||||||
if ($ids) {
|
if ($ids) {
|
||||||
if (!self::$processor) {
|
if (!self::$processor) {
|
||||||
self::$processor = Injector::inst()->create('SearchUpdateProcessor');
|
self::$processor = Injector::inst()->create(SearchUpdateImmediateProcessor::class);
|
||||||
}
|
}
|
||||||
self::$processor->addDirtyIDs($dirtyclass, $ids, $index);
|
self::$processor->addDirtyIDs($dirtyclass, $ids, $index);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +172,7 @@ class SearchUpdater extends Object
|
||||||
$runningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
|
$runningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
|
||||||
|
|
||||||
if (self::$processor && !self::$registered && !$runningTests) {
|
if (self::$processor && !self::$registered && !$runningTests) {
|
||||||
register_shutdown_function(array("SearchUpdater", "flush_dirty_indexes"));
|
register_shutdown_function(array(SearchUpdater::class, "flush_dirty_indexes"));
|
||||||
self::$registered = true;
|
self::$registered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\FullTextSearch\Search\Indexes\SearchIndex_Recording;
|
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
class SearchUpdaterTest_Container extends DataObject
|
use SilverStripe\FullTextSearch\Search\FullTextSearch;
|
||||||
{
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||||
private static $db = array(
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasOne;
|
||||||
'Field1' => 'Varchar',
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasMany;
|
||||||
'Field2' => 'Varchar',
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Index;
|
||||||
'MyDate' => 'Date',
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $has_one = array(
|
|
||||||
'HasOneObject' => 'SearchUpdaterTest_HasOne'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $has_many = array(
|
|
||||||
'HasManyObjects' => 'SearchUpdaterTest_HasMany'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $many_many = array(
|
|
||||||
'ManyManyObjects' => 'SearchUpdaterTest_ManyMany'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchUpdaterTest_HasOne extends DataObject
|
|
||||||
{
|
|
||||||
private static $db = array(
|
|
||||||
'Field1' => 'Varchar',
|
|
||||||
'Field2' => 'Varchar'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $has_many = array(
|
|
||||||
'HasManyContainers' => 'SearchUpdaterTest_Container'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchUpdaterTest_HasMany extends DataObject
|
|
||||||
{
|
|
||||||
private static $db = array(
|
|
||||||
'Field1' => 'Varchar',
|
|
||||||
'Field2' => 'Varchar'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $has_one = array(
|
|
||||||
'HasManyContainer' => 'SearchUpdaterTest_Container'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchUpdaterTest_ManyMany extends DataObject
|
|
||||||
{
|
|
||||||
private static $db = array(
|
|
||||||
'Field1' => 'Varchar',
|
|
||||||
'Field2' => 'Varchar'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $belongs_many_many = array(
|
|
||||||
'ManyManyContainer' => 'SearchUpdaterTest_Container'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchUpdaterTest_Index extends SearchIndex_Recording
|
|
||||||
{
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
$this->addClass('SearchUpdaterTest_Container');
|
|
||||||
|
|
||||||
$this->addFilterField('Field1');
|
|
||||||
$this->addFilterField('HasOneObject.Field1');
|
|
||||||
$this->addFilterField('HasManyObjects.Field1');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchUpdaterTest extends SapphireTest
|
class SearchUpdaterTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
@ -85,7 +20,7 @@ class SearchUpdaterTest extends SapphireTest
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
if (self::$index === null) {
|
if (self::$index === null) {
|
||||||
self::$index = singleton(get_class($this).'_Index');
|
self::$index = SearchUpdaterTest_Index::singleton();
|
||||||
} else {
|
} else {
|
||||||
self::$index->reset();
|
self::$index->reset();
|
||||||
}
|
}
|
||||||
|
@ -132,7 +67,6 @@ class SearchUpdaterTest extends SapphireTest
|
||||||
// Check the default "writing a document updates the document"
|
// Check the default "writing a document updates the document"
|
||||||
SearchUpdater::flush_dirty_indexes();
|
SearchUpdater::flush_dirty_indexes();
|
||||||
|
|
||||||
|
|
||||||
$added = self::$index->getAdded(array('ID'));
|
$added = self::$index->getAdded(array('ID'));
|
||||||
// Some databases don't output $added in a consistent order; that's okay
|
// Some databases don't output $added in a consistent order; that's okay
|
||||||
usort($added, function ($a, $b) {return $a['ID']-$b['ID']; });
|
usort($added, function ($a, $b) {return $a['ID']-$b['ID']; });
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasOne;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasMany;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_ManyMany;
|
||||||
|
|
||||||
|
class SearchUpdaterTest_Container extends DataObject
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Field1' => 'Varchar',
|
||||||
|
'Field2' => 'Varchar',
|
||||||
|
'MyDate' => 'Date',
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'SearchUpdaterTest_Container';
|
||||||
|
|
||||||
|
private static $has_one = array(
|
||||||
|
'HasOneObject' => SearchUpdaterTest_HasOne::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $has_many = array(
|
||||||
|
'HasManyObjects' => SearchUpdaterTest_HasMany::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $many_many = array(
|
||||||
|
'ManyManyObjects' => SearchUpdaterTest_ManyMany::class
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||||
|
|
||||||
|
class SearchUpdaterTest_HasMany extends DataObject
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Field1' => 'Varchar',
|
||||||
|
'Field2' => 'Varchar'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'SearchUpdaterTest_HasMany';
|
||||||
|
|
||||||
|
private static $has_one = array(
|
||||||
|
'HasManyContainer' => SearchUpdaterTest_Container::class
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||||
|
|
||||||
|
class SearchUpdaterTest_HasOne extends DataObject
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Field1' => 'Varchar',
|
||||||
|
'Field2' => 'Varchar'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'SearchUpdaterTest_HasOne';
|
||||||
|
|
||||||
|
private static $has_many = array(
|
||||||
|
'HasManyContainers' => SearchUpdaterTest_Container::class
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||||
|
|
||||||
|
use SilverStripe\FullTextSearch\Search\Indexes\SearchIndex_Recording;
|
||||||
|
|
||||||
|
class SearchUpdaterTest_Index extends SearchIndex_Recording
|
||||||
|
{
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->addClass('SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container');
|
||||||
|
|
||||||
|
$this->addFilterField('Field1');
|
||||||
|
$this->addFilterField('HasOneObject.Field1');
|
||||||
|
$this->addFilterField('HasManyObjects.Field1');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FullTextSearch\Tests\SearchUpdaterTest;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
|
||||||
|
|
||||||
|
class SearchUpdaterTest_ManyMany extends DataObject
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Field1' => 'Varchar',
|
||||||
|
'Field2' => 'Varchar'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'SearchUpdaterTest_ManyMany';
|
||||||
|
|
||||||
|
private static $belongs_many_many = array(
|
||||||
|
'ManyManyContainer' => SearchUpdaterTest_Container::class
|
||||||
|
);
|
||||||
|
}
|
|
@ -187,7 +187,7 @@ class SolrIndexTest extends SapphireTest
|
||||||
$serviceMock = $this->getServiceMock();
|
$serviceMock = $this->getServiceMock();
|
||||||
$index = new SolrIndexTest_FakeIndex();
|
$index = new SolrIndexTest_FakeIndex();
|
||||||
$index->setService($serviceMock);
|
$index->setService($serviceMock);
|
||||||
$obj = new SearchUpdaterTest_Container();
|
$obj = new Container();
|
||||||
|
|
||||||
$obj->Field1 = 'Field1 val';
|
$obj->Field1 = 'Field1 val';
|
||||||
$obj->Field2 = null;
|
$obj->Field2 = null;
|
||||||
|
|
Loading…
Reference in New Issue