Update Search Manipulater

This commit is contained in:
Brett Tasker 2017-04-21 16:34:04 +12:00
parent 9d5ea9393d
commit 6066af5841
12 changed files with 164 additions and 104 deletions

View File

@ -1,3 +1,6 @@
DataObject:
extensions:
- 'SearchUpdater_ObjectHandler'
Database:
extensions:
- 'SearchManipulateCaptureExtension'

View File

@ -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;
}
}

View File

@ -1,5 +1,7 @@
<?php
namespace SilverStripe\FullTextSearch\Search\Processors;
class SearchUpdateImmediateProcessor extends SearchUpdateProcessor
{
public function triggerProcessing()

View File

@ -1,5 +1,11 @@
<?php
namespace SilverStripe\FullTextSearch\Search\Processors;
use SilverStripe\ORM\DataObject;
use SilverStripe\FullTextSearch\Search\Variants\SearchVariant;
use SilverStripe\FullTextSearch\Search\FullTextSearch;
abstract class SearchUpdateProcessor
{
/**
@ -33,7 +39,7 @@ abstract class SearchUpdateProcessor
public function addDirtyIDs($class, $statefulids, $index)
{
$base = ClassInfo::baseDataClass($class);
$base = DataObject::getSchema()->baseDataClass($class);
$forclass = isset($this->dirty[$base]) ? $this->dirty[$base] : array();
foreach ($statefulids as $statefulid) {

View File

@ -3,6 +3,14 @@
namespace SilverStripe\FullTextSearch\Search\Updaters;
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
* items.
@ -15,8 +23,6 @@ use SilverStripe\ORM\DB;
*
* TODO: The way we bind in is awful hacky.
*/
use SilverStripe\Core\Object;
use SilverStripe\ORM\DataExtension;
class SearchUpdater extends Object
{
@ -27,31 +33,13 @@ class SearchUpdater extends Object
{
global $databaseConfig;
$current = DB::getConn();
if (!$current || !$current->currentDatabase() || @$current->isManipulationCapture) {
$current = DB::get_conn();
if (!$current || !$current->getSelectedDatabase() || @$current->isManipulationCapture) {
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 */
$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)
$captured->selectDatabase($current->currentDatabase());
DB::setConn($captured);
$captured->selectDatabase($current->getSelectedDatabase());
DB::set_conn($captured);
}
public static $registered = false;
@ -85,7 +73,9 @@ class SearchUpdater extends Object
{
// First, extract any state that is in the manipulation itself
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();
}
@ -105,7 +95,7 @@ class SearchUpdater extends Object
$class = $details['class'];
$fields = isset($details['fields']) ? $details['fields'] : array();
$base = ClassInfo::baseDataClass($class);
$base = DataObject::getSchema()->baseDataClass($class);
$key = "$id:$base:".serialize($state);
$statefulids = array(array('id' => $id, 'state' => $state));
@ -166,7 +156,7 @@ class SearchUpdater extends Object
foreach ($dirtyids as $dirtyclass => $ids) {
if ($ids) {
if (!self::$processor) {
self::$processor = Injector::inst()->create('SearchUpdateProcessor');
self::$processor = Injector::inst()->create(SearchUpdateImmediateProcessor::class);
}
self::$processor->addDirtyIDs($dirtyclass, $ids, $index);
}
@ -182,7 +172,7 @@ class SearchUpdater extends Object
$runningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
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;
}
}

View File

@ -1,78 +1,13 @@
<?php
use SilverStripe\ORM\DataObject;
use SilverStripe\FullTextSearch\Search\Indexes\SearchIndex_Recording;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
class SearchUpdaterTest_Container extends DataObject
{
private static $db = array(
'Field1' => 'Varchar',
'Field2' => 'Varchar',
'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');
}
}
use SilverStripe\Core\Config\Config;
use SilverStripe\FullTextSearch\Search\FullTextSearch;
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Container;
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasOne;
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_HasMany;
use SilverStripe\FullTextSearch\Tests\SearchUpdaterTest\SearchUpdaterTest_Index;
class SearchUpdaterTest extends SapphireTest
{
@ -85,7 +20,7 @@ class SearchUpdaterTest extends SapphireTest
parent::setUp();
if (self::$index === null) {
self::$index = singleton(get_class($this).'_Index');
self::$index = SearchUpdaterTest_Index::singleton();
} else {
self::$index->reset();
}
@ -132,7 +67,6 @@ class SearchUpdaterTest extends SapphireTest
// Check the default "writing a document updates the document"
SearchUpdater::flush_dirty_indexes();
$added = self::$index->getAdded(array('ID'));
// Some databases don't output $added in a consistent order; that's okay
usort($added, function ($a, $b) {return $a['ID']-$b['ID']; });

View File

@ -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
);
}

View File

@ -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
);
}

View File

@ -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
);
}

View File

@ -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');
}
}

View File

@ -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
);
}

View File

@ -187,7 +187,7 @@ class SolrIndexTest extends SapphireTest
$serviceMock = $this->getServiceMock();
$index = new SolrIndexTest_FakeIndex();
$index->setService($serviceMock);
$obj = new SearchUpdaterTest_Container();
$obj = new Container();
$obj->Field1 = 'Field1 val';
$obj->Field2 = null;