Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sean Crystal
committed
Aug 23, 2011
1 parent
370ab5d
commit da4c4ce
Showing
13 changed files
with
484 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
namespace Tracks\EventStore; | ||
use Tracks\Model\Guid; | ||
use Tracks\Model\AggregateRoot; | ||
|
||
interface IRepository | ||
{ | ||
public function load(Guid $guid); | ||
public function save(AggregateRoot $aggregateRoot); | ||
public function setSnapshotFrequency($numEvents); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,6 @@ | |
*/ | ||
abstract class Entity | ||
{ | ||
|
||
/** | ||
* Load an array of events onto this entity | ||
* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?php | ||
namespace Tracks\Replay; | ||
|
||
interface IEventStream extends \Iterator | ||
{ | ||
public function getDryRunInfo(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<?php | ||
namespace Tracks\Replay\EventStream; | ||
|
||
class ZendDb implements IEventStream | ||
{ | ||
/** @staticvar int */ | ||
const BUFFER_SIZE = 100; | ||
|
||
/** @var Zend_Db_Select */ | ||
private $_query; | ||
|
||
/** @var array */ | ||
private $_rowBuffer = array(); | ||
|
||
/** @var int */ | ||
private $_cursor = 0; | ||
|
||
/** @var int */ | ||
private $_offset = 0; | ||
|
||
/** @var int */ | ||
private $_bufferSize; | ||
|
||
/** | ||
* Constructor | ||
*/ | ||
public function __construct(Zend_Db_Select $query, $bufferSize = self::BUFFER_SIZE) | ||
{ | ||
assert('is_int($bufferSize)'); | ||
|
||
$this->_query = $query; | ||
$this->_bufferSize = $bufferSize; | ||
} | ||
|
||
/** | ||
* Get the current element | ||
* @see Iterator::current() | ||
*/ | ||
public function current() | ||
{ | ||
if (empty($this->_rowBuffer)) { | ||
$this->loadMore(); | ||
} | ||
|
||
return unserialize($this->_rowBuffer[$this->_cursor]['data']); | ||
} | ||
|
||
/** | ||
* Get the key for the current element | ||
* @see Iterator::key() | ||
*/ | ||
public function key() | ||
{ | ||
return $this->_cursor; | ||
} | ||
|
||
/** | ||
* Move the cursor to the next element | ||
* @see Iterator::next() | ||
*/ | ||
public function next() | ||
{ | ||
if (++$this->_cursor >= $this->_bufferSize) { | ||
$this->loadMore(); | ||
$this->_cursor = 0; | ||
} | ||
} | ||
|
||
/** | ||
* Rewind the cursor to the first element | ||
* @see Iterator::rewind() | ||
*/ | ||
public function rewind() | ||
{ | ||
$this->_cursor = 0; | ||
|
||
if (empty($this->_rowBuffer)) { | ||
$this->loadMore(); | ||
} | ||
} | ||
|
||
/** | ||
* Is the current key valid? | ||
* @see Iterator::valid() | ||
*/ | ||
public function valid() | ||
{ | ||
return $this->_cursor < count($this->_rowBuffer); | ||
} | ||
|
||
/** | ||
* Get the SQL string for the current query | ||
* | ||
* @return string | ||
*/ | ||
public function getQueryAsString() | ||
{ | ||
return $this->_query->assemble(); | ||
} | ||
|
||
/** | ||
* Load more rows from the database and put them in the buffer | ||
*/ | ||
private function loadMore() | ||
{ | ||
$eventTable = new Zend_Db_Table('event'); | ||
$this->_rowBuffer = $eventTable | ||
->fetchAll( | ||
$this->_query | ||
->limit(self::BUFFER_SIZE, $this->_offset) | ||
)->toArray(); | ||
|
||
$this->_offset += self::BUFFER_SIZE; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
<?php | ||
namespace Tracks\Replay\EventStream; | ||
|
||
class ZendDbBuilder | ||
{ | ||
/** @var Zend_Db_Select */ | ||
private $_query; | ||
|
||
/** @var array */ | ||
private $_eventClasses = array(); | ||
|
||
/** @var array */ | ||
private $_entities = array(); | ||
|
||
/** @var Zend_Date */ | ||
private $_startDate; | ||
|
||
/** @var Zend_Date */ | ||
private $_endDate; | ||
|
||
/** | ||
* Start building an event stream | ||
* | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public static function start() | ||
{ | ||
return new self; | ||
} | ||
|
||
/** | ||
* Stream all events | ||
* | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function withAllEvents() | ||
{ | ||
$this->_eventClasses = array(); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Stream a specific event class | ||
* | ||
* @param string $eventClass | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function withEvent($eventClass) | ||
{ | ||
assert('is_string($eventClass)'); | ||
|
||
$this->_eventClasses[] = $eventClass; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Stream from all entities | ||
* | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function fromAllEntities() | ||
{ | ||
$this->_entities = array(); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Get events that belong to an entity | ||
* | ||
* @param string $guid | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function fromEntity($guid) | ||
{ | ||
assert('is_string($guid)'); | ||
|
||
$this->_entities[] = $guid; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Stream events for all time | ||
* | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function forAllTime() | ||
{ | ||
$this->_startDate = null; | ||
$this->_endDate = null; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Specify a date range from which to select events | ||
* Only one date range may be specified | ||
* | ||
* @param Zend_Date $startDate | ||
* @param Zend_Date $endDate | ||
* @return Replay_EventStreamBuilder | ||
*/ | ||
public function inDateRange(Zend_Date $startDate, Zend_Date $endDate) | ||
{ | ||
$this->_startDate = $startDate; | ||
$this->_endDate = $endDate; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Get the Replay_EventStream object | ||
* | ||
* @return Replay_EventStream | ||
*/ | ||
public function build() | ||
{ | ||
$this->buildBaseQuery(); | ||
$this->buildEventsQuery(); | ||
$this->buildDateRangeQuery(); | ||
$this->buildEntitiesQuery(); | ||
|
||
return new Replay_EventStream($this->_query); | ||
} | ||
|
||
/** | ||
* Build the base query to load events | ||
*/ | ||
private function buildBaseQuery() | ||
{ | ||
$eventTable = new Table_Event; | ||
$this->_query = $eventTable | ||
->select() | ||
->from('event', '*') | ||
->setIntegrityCheck(false) | ||
->order('date_created ASC') | ||
->order('event.id'); | ||
} | ||
|
||
/** | ||
* Build the event class filter part of the query | ||
*/ | ||
private function buildEventsQuery() | ||
{ | ||
if (count($this->_eventClasses) > 0) { | ||
$this->_query->where(implode('OR', array_map(function($x) { return " data LIKE '%{$x}%' "; }, $this->_eventClasses))); | ||
} | ||
} | ||
|
||
/** | ||
* Build the entity guid filter part of the query | ||
*/ | ||
private function buildEntitiesQuery() | ||
{ | ||
if (count($this->_entities) > 0) { | ||
$this->_query | ||
->join('event_provider', 'event.event_provider_id = event_provider.id') | ||
->where(new Zend_Db_Expr("event_provider.guid IN (". implode(',', array_map(function($x) { return "'{$x}'"; }, $this->_entities)) .")")); | ||
} | ||
} | ||
|
||
/** | ||
* Build the date range filter part of the query | ||
*/ | ||
private function buildDateRangeQuery() | ||
{ | ||
if ($this->_startDate) { | ||
$this->_query->where('date_created >= ?', $this->_startDate->toString('Y-m-d')); | ||
} | ||
|
||
if ($this->_endDate) { | ||
$this->_query->where('date_created <= ?', $this->_endDate->toString('Y-m-d')); | ||
} | ||
} | ||
} |
Oops, something went wrong.