Skip to content

Commit

Permalink
Merge pull request #88 from talis/event-hooks
Browse files Browse the repository at this point in the history
90% implement event hooks
  • Loading branch information
Chris Clarke committed Aug 25, 2015
2 parents 7cd9c7f + 9aa6d29 commit 49678b3
Show file tree
Hide file tree
Showing 14 changed files with 452 additions and 48 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"require": {
"semsol/arc2": "v2.2.4",
"chrisboulton/php-resque": "dev-master#98fde571db008a8b48e73022599d1d1c07d4a7b5",
"monolog/monolog" : "1.13.1"
"monolog/monolog" : "~1.13"
},
"require-dev": {
"phpunit/phpunit": "4.1.*"
Expand Down
159 changes: 146 additions & 13 deletions src/IDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,177 @@
*/
interface IDriver
{
// graph functions

public function graph($query,$includeProperties=array());

/**
* @deprecated
* @abstract
* @param $query
* Equivalent to CONSTRUCT
* @param array $filter conditions to filter by
* @param array $includeProperties only include these predicates, empty array means return all predicates
* @return mixed
*/
public function describe($query);
public function graph($filter,$includeProperties=array());

/**
* Return (DESCRIBE) the concise bound description of a resource
* @param string $resource uri resource you'd like to describe
* @param null|string $context string uri of the context, or named graph, you'd like to describe from
* @return ExtendedGraph
*/
public function describeResource($resource,$context=null);

/**
* Return (DESCRIBE) the concise bound descriptions of a bunch of resources
* @param array $resources uris of resources you'd like to describe
* @param null|string $context string uri of the context, or named graph, you'd like to describe from
* @return ExtendedGraph
*/
public function describeResources(Array $resources,$context=null);

/**
* Get a view of a given type for a given resource
* @param string $resource uri of the resource you'd like the view for
* @param string $viewType string type of view
* @return ExtendedGraph
*/
public function getViewForResource($resource,$viewType);

/**
* Get views for multiple resources in one graph
* @param array $resources uris of resources you'd like to describe
* @param string $viewType type of view
* @return ExtendedGraph
*/
public function getViewForResources(Array $resources,$viewType);

/**
* Get views based on a pattern-match $filter
* @param array $filter pattern to match to select views
* @param string $viewType type of view
* @return ExtendedGraph
*/
public function getViews(Array $filter,$viewType);

/**
* Returns the etag of a resource, useful for caching
* @param string $resource
* @param null|string $context
* @return string
*/
public function getETag($resource,$context=null);

// tabular functions

public function select($query,$fields,$sortBy=null,$limit=null,$context=null);
/**
* Select data in a tabular format
* @param array $filter pattern to match to select views
* @param $fields
* @param null $sortBy
* @param null $limit
* @param null $context
* @return array
*/
public function select($filter,$fields,$sortBy=null,$limit=null,$context=null);

/**
* Select data from a table
* @param $tableType
* @param array $filter
* @param array $sortBy
* @param int $offset
* @param int $limit
* @return array
*/
public function getTableRows($tableType,$filter=array(),$sortBy=array(),$offset=0,$limit=10);
public function generateTableRows($tableType,$resource=null,$context=null);

/**
* todo: work out what this does
* @param $tableType
* @param $fieldName
* @param array $filter
* @return array
*/
public function getDistinctTableColumnValues($tableType, $fieldName, array $filter = array());

// aggregate, save and search functions

/**
* Get a count of resources matching the pattern in $query. Optionally group counts by specifying a $groupBy predicate
* @param $query
* @param null|string $groupBy
* @return array|int multidimensional array with int values if grouped by, otherwise int
*/
public function getCount($query,$groupBy=null);

/**
* Save the changes between $oldGraph -> $newGraph
* @param ExtendedGraph $oldGraph
* @param ExtendedGraph $newGraph
* @param null|string $context
* @param null|string $description
* @return bool true or throws exception on error
*/
public function saveChanges(ExtendedGraph $oldGraph, ExtendedGraph $newGraph,$context=null,$description=null);

/**
* Register an event hook, which will be executed when the event fires.
* @param $eventType
* @param IEventHook $hook
*/
public function registerHook($eventType,IEventHook $hook);

/* START Deprecated methods that will be removed in 1.x.x */

/**
* Return (DESCRIBE) according to a filter
* @deprecated Use graph() instead
* @param array $filter conditions to filter by
* @return ExtendedGraph
*/
public function describe($filter);

/**
* Generates table rows
* @deprecated calling save will generate table rows - this method seems to be only used in tests and does not belong on the interface
* @param $tableType
* @param null|string $resource
* @param null|string $context
*/
public function generateTableRows($tableType,$resource=null,$context=null);

/**
* Submits search params to configured search provider
* the params array must contain the following keys
* -q the query string to search for
* -type the search document type to restrict results to, in other words _id.type
* -indices an array of indices (from spec) to match query terms against, must specify at least one
* -fields an array of the fields (from spec) you want included in the search results, must specify at least one
* -limit integer the number of results to return per page
* -offset the offset to skip to when returning results
*
* this method looks for the above keys in the params array and naively passes them to the search provider which will
* throw SearchException if any of the params are invalid
*
* @deprecated Search will be removed from a future version of Tripod as its functionality is equivalent to tables
* @param Array $params
* @throws \Tripod\Exceptions\Exception - if search provider cannot be found
* @throws \Tripod\Exceptions\SearchException - if something goes wrong
* @return Array results
*/
public function search(Array $params);

/**
* Get any documents that were left in a locked state
* @deprecated this is a feature of the mongo implementation - this method will move from the interface to the mongo-specific Driver class soon.
* @param null|string $fromDateTime strtotime compatible string
* @param null|string $tillDateTime strtotime compatible string
* @return array of locked documents
*/
public function getLockedDocuments($fromDateTime =null , $tillDateTime = null);

/**
* Remove any inert locks left by a given transaction
* @deprecated this is a feature of the mongo implementation - this method will move from the interface to the mongo-specific Driver class soon.
* @param string $transaction_id
* @param string $reason
* @return bool true or throws exception on error
*/
public function removeInertLocks($transaction_id, $reason);

/* END Deprecated methods that will be removed in 1.x.x */

}
49 changes: 49 additions & 0 deletions src/IEventHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/**
* Created by PhpStorm.
* User: chrisc
* Date: 05/08/2015
* Time: 13:36
*/

namespace Tripod;

/**
* Interface IEventHook
* @package Tripod
*/
interface IEventHook
{
/**
* Constant for save changes event.
* IEventHook::pre() will be passed the following parameters in a multidimensional array:
* - oldGraph - the graph state before the change
* - newGraph - the graph state after the change is successfully applied
*
* IEventHook::pre() will be passed the following parameters in a multidimensional array:
* - subjectsAndPredicatesOfChange - an array, keyed by subject, with the subjects and predicates changed during the save
*/
const EVENT_SAVE_CHANGES = "EVENT_SAVE_CHANGES";

/**
* This method gets called just before the event happens. The arguments passed depend on the event in question, see
* the documentation for that event type for details
* @param $args array of arguments
*/
public function pre(array $args);

/**
* This method gets called after the event has successfully completed. The arguments passed depend on the event in
* question, see the documentation for that event type for details
* If the event throws an exception or fatal error, this method will not be called.
* @param $args array of arguments
*/
public function success(array $args);

/**
* This method gets called if the event failed for any reason. The arguments passed should be the same as IEventHook::pre
* @param array $args
* @return mixed
*/
public function failure(array $args);
}
21 changes: 21 additions & 0 deletions src/mongo/Driver.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

/** @noinspection PhpIncludeInspection */

use Tripod\Exceptions\Exception;
use Tripod\IEventHook;

$TOTAL_TIME=0;

/**
Expand Down Expand Up @@ -598,6 +601,24 @@ public function replayTransactionLog($fromDate = null, $toDate = null)
return $this->getDataUpdater()->replayTransactionLog($fromDate, $toDate);
}

/**
* Register an event hook, which
* @param $eventType
* @param IEventHook $
* @return mixed
*/
public function registerHook($eventType, IEventHook $hook)
{
switch ($eventType) {
case IEventHook::EVENT_SAVE_CHANGES:
$this->getDataUpdater()->registerSaveChangesEventHook($hook);
break;
default:
throw new Exception("Unrecognised type $eventType whilst registering event hook");
}
}


/**
* For mocking
* @return Config
Expand Down
15 changes: 11 additions & 4 deletions src/mongo/MongoGraph.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,25 @@ private function add_tarray_to_index($tarray)
$predObjects = array();
foreach ($tarray as $key=>$value)
{
if($key[0] != '_')
if (empty($key))
{
throw new \Tripod\Exceptions\Exception("The predicate cannot be an empty string");
}
else if($key[0] != '_')
{
$predicate = $this->qname_to_uri($key);
$graphValueObject = $this->toGraphValueObject($value);
// Only add if valid values have been found
if (!empty($graphValueObject)) {
if (!empty($graphValueObject))
{
$predObjects[$predicate] = $graphValueObject;
}
}
else if($key == "_id"){
else if($key == "_id")
{
// If the subject is invalid then throw an exception
if(!isset($value['r']) || !$this->isValidResource($value['r'])){
if(!isset($value['r']) || !$this->isValidResource($value['r']))
{
throw new \Tripod\Exceptions\Exception("The subject cannot be an empty string");
}
}
Expand Down
34 changes: 34 additions & 0 deletions src/mongo/base/DriverBase.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@
$TOTAL_TIME=0;

use Monolog\Logger;
use Tripod\Exceptions\Exception;
use Tripod\IEventHook;

/**
* Class DriverBase
* @package Tripod\Mongo
*/
abstract class DriverBase
{
/**
* constants for the supported hook functions that can be applied
*/
const HOOK_FN_PRE = "pre";
const HOOK_FN_SUCCESS = "success";
const HOOK_FN_FAILURE = "failure";

/**
* @var \MongoCollection
*/
Expand Down Expand Up @@ -376,6 +385,31 @@ protected function getCollection()
return $this->collection;
}

protected function applyHooks($fn,$hooks,$args=array())
{
switch ($fn) {
case $this::HOOK_FN_PRE:
case $this::HOOK_FN_SUCCESS:
case $this::HOOK_FN_FAILURE:
break;
default:
throw new Exception("Invalid hook function $fn requested");
}
foreach ($hooks as $hook)
{
try
{
/* @var $hook IEventHook */
$hook->$fn($args);
}
catch (\Exception $e)
{
// don't let rabid hooks stop tripod
$this->getLogger()->error("Hook ".get_class($hook)." threw exception {$e->getMessage()}, continuing");
}
}
}

}

/**
Expand Down
Loading

0 comments on commit 49678b3

Please sign in to comment.