$queryConstraints = new SimfileQueryConstraints();
$queryConstraints->stepsHaveRating(15);
- $simfiles = $this->_simfileRepository->findByTitle('a', $queryConstraints);
+ $simfiles = $this->_simfileRepository->findByTitle('a');
foreach($simfiles as $simfile)
{
\r
use Domain\Entities\IDivineEntity;\r
use DataAccess\DataMapper\IDataMapper;\r
+use DataAccess\Queries\IQueryBuilder;\r
use DataAccess\DataMapper\Helpers\AbstractPopulationHelper;\r
use ReflectionClass;\r
use PDO;\r
$options = array(PDO::ATTR_EMULATE_PREPARES => false,\r
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);\r
\r
- $this->_db = new PDO($dsn, $username, null, $options); \r
+ $this->_db = new PDO($dsn, $username, $password, $options); \r
$this->_maps = include $maps;\r
}\r
\r
- public function map($entityName, $queryString = 'SELECT * FROM %s')\r
+ public function map($entityName, IQueryBuilder $queryBuilder)\r
{\r
+ $queryString = $queryBuilder->buildQuery();\r
+ \r
$statement = $this->_db->prepare(sprintf($queryString,\r
$this->_maps[$entityName]['table']\r
));\r
\r
namespace DataAccess\DataMapper;\r
\r
-use DataAccess\Queries\IQueryConstraints;\r
+use DataAccess\Queries\IQueryBuilder;\r
use Domain\Entities\IDivineEntity;\r
\r
interface IDataMapper\r
//TODO: Table is the wrong name. We actually give the implementation the entity name and it finds the table from the maps.\r
\r
//find in table based on constraints and return it as entity\r
- public function map($entityName, $queryString);\r
+ public function map($entityName, IQueryBuilder $queryBuilder);\r
//insert/update entity in table\r
public function save(IDivineEntity $entity);\r
//remove entity from table\r
--- /dev/null
+<?php
+
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+namespace DataAccess\Queries;
+
+interface IQueryBuilder
+{
+ public function setBaseQuery($query);
+ public function limit($start, $end);
+ public function where($column, $operator, $value);
+ public function join($type, $tableA, $columnA, $tableB, $columnB);
+ public function buildQuery();
+}
\ No newline at end of file
--- /dev/null
+<?php\r
+\r
+namespace DataAccess\Queries;\r
+\r
+interface IQueryBuilderFactory\r
+{\r
+ public function createInstance();\r
+}\r
-<?php
-
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-
-namespace DataAccess\Queries;
-
-interface IQueryConstraints
-{
- public function applyTo($queryString);
- public function limit($start, $end);
- public function where($column, $operator, $value);
- public function join($type, $tableA, $columnA, $tableB, $columnB);
+<?php\r
+\r
+namespace DataAccess\Queries;\r
+\r
+use DataAccess\Queries\IQueryBuilder;\r
+\r
+interface IQueryConstraints\r
+{\r
+ public function applyTo(IQueryBuilder $queryBuilder);\r
}
\ No newline at end of file
--- /dev/null
+<?php
+
+namespace DataAccess\Queries;
+
+use DataAccess\Queries\IQueryBuilder;
+
+class QueryBuilder implements IQueryBuilder
+{
+ private $_queryString = 'SELECT * FROM %s';
+
+ protected $_whereClauses = array();
+ protected $_limitClause;
+ protected $_joinClause;
+
+ public function buildQuery()
+ {
+ $this->applyJoinClause()
+ ->applyWhereClauses()
+ ->applyLimitClause();
+
+ return $this->_queryString;
+ }
+
+ public function setBaseQuery($baseQuery)
+ {
+ $this->_queryString = $baseQuery;
+ }
+
+ public function where($columnName, $operator, $value)
+ {
+ $this->_whereClauses[$columnName] = array('operator' => $operator, 'value' => $value);
+ return $this;
+ }
+
+ public function limit($start, $end = null)
+ {
+ if($end)
+ {
+ $this->_limitClause = sprintf(' LIMIT %u,%u', $start, $end);
+ return $this;
+ }
+
+ $this->_limitClause = sprintf(' LIMIT %u', $start);
+
+ return $this;
+ }
+
+ public function join($type, $tableA, $columnA, $tableB, $columnB)
+ {
+ $this->_joinClause = sprintf(' %s JOIN %s ON %s.%s = %s.%s', $type, $tableB, $tableA, $columnA, $tableB, $columnB);
+ return $this;
+ }
+
+ private function applyJoinClause()
+ {
+ $this->_queryString .= $this->_joinClause;
+ return $this;
+ }
+
+ private function applyWhereClauses()
+ {
+ $this->_queryString .= ' WHERE ';
+
+ foreach($this->_whereClauses as $columnName => $columnValue)
+ {
+ switch(gettype($columnValue['value']))
+ {
+ case 'integer':
+ $this->_queryString .= sprintf("%s%s%u", $columnName, $columnValue['operator'], $columnValue['value']) . ' AND ';
+ break;
+ case 'string':
+ $this->_queryString .= sprintf("%s %s '%s'", $columnName, $columnValue['operator'], $columnValue['value']) . ' AND ';
+ break;
+ }
+
+ }
+
+ $this->_queryString = rtrim($this->_queryString, ' AND ');
+ return $this;
+ }
+
+ private function applyLimitClause()
+ {
+ $this->_queryString .= $this->_limitClause;
+ return $this;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<?php\r
+\r
+namespace DataAccess\Queries;\r
+\r
+use DataAccess\Queries\QueryBuilder;\r
+use DataAccess\Queries\IQueryBuilderFactory;\r
+\r
+class QueryBuilderFactory implements IQueryBuilderFactory\r
+{\r
+ public function createInstance()\r
+ {\r
+ return new QueryBuilder();\r
+ }\r
+}
\ No newline at end of file
namespace DataAccess\Queries\StepMania;
-use DataAccess\Queries\QueryConstraints;
+use DataAccess\Queries\IQueryBuilder;
use DataAccess\Queries\StepMania\ISimfileQueryConstraints;
-class SimfileQueryConstraints extends QueryConstraints implements ISimfileQueryConstraints
+class SimfileQueryConstraints implements ISimfileQueryConstraints
{
+
+ private $_queryBuilder;
+ private $_fgChanges;
+ private $_bgChanges;
+ private $_stepRating;
+
+ public function applyTo(IQueryBuilder $queryBuilder)
+ {
+ $this->_queryBuilder = $queryBuilder;
+
+ $this->applyStepsRating()
+ ->applyBgChanges()
+ ->applyFgChanges();
+ }
+
public function hasFgChanges($bool)
{
- return $this->where('fg_changes', '=', (int)$bool);
+ $this->_fgChanges = (int)$bool;
+ return $this;
}
public function hasBgChanges($bool)
{
- return $this->where('bg_changes', '=', (int)$bool);
+ $this->_bgChanges = (int)$bool;
+ return $this;
}
public function stepsHaveRating($rating)
{
- return $this->join('INNER', 'simfiles', 'id', 'steps', 'simfile_id')
- ->where('steps.rating', '=', $rating);
+ $this->_stepRating = $rating;
+ return $this;
}
public function hasDifficulty($difficulty){}
{
return;
}
+
+ private function applyFgChanges()
+ {
+ if($this->_fgChanges) {
+ $this->_queryBuilder->where('fg_changes', '=', $this->_fgChanges);
+ }
+
+ return $this;
+ }
+
+ private function applyBgChanges()
+ {
+ if($this->_bgChanges) {
+ $this->_queryBuilder->where('bg_changes', '=', $this->_bgChanges);
+ }
+
+ return $this;
+ }
+
+ private function applyStepsRating()
+ {
+ if($this->_stepRating)
+ {
+ $this->_queryBuilder->join('INNER', 'simfiles', 'id', 'steps', 'simfile_id')
+ ->where('steps.rating', '=', $this->_stepRating);
+ }
+
+ return $this;
+ }
}
\r
use DataAccess\StepMania\ISimfileRepository;\r
use DataAccess\DataMapper\IDataMapper;\r
+use DataAccess\Queries\IQueryBuilderFactory;\r
use DataAccess\Queries\StepMania\ISimfileQueryConstraints;\r
use Domain\Entities\StepMania\ISimfile;\r
\r
class SimfileRepository implements ISimfileRepository\r
{\r
private $_dataMapper;\r
+ private $_queryBuilderFactory;\r
\r
- public function __construct(IDataMapper $dataMapper) {\r
+ public function __construct(IDataMapper $dataMapper, IQueryBuilderFactory $queryBuilderFactory) {\r
$this->_dataMapper = $dataMapper;\r
+ $this->_queryBuilderFactory = $queryBuilderFactory;\r
}\r
\r
public function findById($id) {\r
\r
public function findByTitle($title, ISimfileQueryConstraints $constraints = NULL)\r
{\r
- //TODO: Should I inject a factory, and then make $constraints if it isn't given?\r
+ $queryBuilder = $this->_queryBuilderFactory->createInstance();\r
+ $queryBuilder->where('title', 'LIKE', "%%$title%%");\r
+ \r
if($constraints)\r
{\r
- $queryString = $constraints->where('title', 'LIKE', "%%$title%%") //TODO: Should I make a like method that handles adding the %% ?\r
- ->applyTo('SELECT * from %s');\r
- } else {\r
- //It would avoid this, or rather I could put this in the constraints class\r
- $queryString = "SELECT * FROM %s WHERE title LIKE '%$title%'";\r
+ $constraints->applyTo($queryBuilder);\r
}\r
- \r
- //is it better to pass in constraints object?\r
- //could have a default "select * from %s" in the constraints object which could be overwritten via a method.\r
- //-no more need for applyTo, just go $constratints->getQuery\r
- //maybe it should no longer be constraints but instead queryBuilder\r
- \r
- /**\r
- * have this class contain a queryBuilderFactory and then have constraintsClass \r
- * go in through methods which act on the query, adding in constraints.\r
- */\r
- return $this->_dataMapper->map('Simfile', $queryString);\r
+\r
+ return $this->_dataMapper->map('Simfile', $queryBuilder);\r
}\r
\r
public function findByArtist($artist){}\r
'DataAccess\StepMania\ISimfileRepository' => DI\object('DataAccess\StepMania\SimfileRepository'),\r
'DataAccess\DataMapper\IDataMapper' => DI\object('DataAccess\DataMapper\DataMapper')\r
->constructor(DI\link('datamapper.maps')), \r
- \r
+ 'DataAccess\Queries\IQueryBuilderFactory' => DI\object('DataAccess\Queries\QueryBuilderFactory')\r
];\r