Skip to content

Commit b21033c

Browse files
committed
Merge pull request nova-framework#401 from tomvlk/3.0-db-orm
3.0 - ORM Continued..
2 parents 6598044 + 9995978 commit b21033c

File tree

7 files changed

+607
-896
lines changed

7 files changed

+607
-896
lines changed

system/DBAL/Connection.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class Connection extends BaseConnection
2828

2929
/**
3030
* Constructor
31+
*
32+
* @param array $params
33+
* @param Driver $driver
34+
* @param Configuration $config
35+
* @param EventManager $eventManager
3136
*/
3237
public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null)
3338
{
@@ -133,7 +138,20 @@ public function fetchObject($statement, array $params = array(), array $types =
133138
return $this->executeQuery($statement, $params, $types)->fetch(PDO::FETCH_OBJ);
134139
}
135140

136-
public function fetchClass($statement, array $params = array(), array $paramTypes = array(), $className = null)
141+
/**
142+
* Fetch class
143+
*
144+
* @param string $statement
145+
* @param array $params
146+
* @param array $paramTypes
147+
* @param null|string $className
148+
* @param bool $fetchAll
149+
*
150+
* @return array|mixed
151+
*
152+
* @throws \Exception
153+
*/
154+
public function fetchClass($statement, array $params = array(), array $paramTypes = array(), $className = null, $fetchAll = false)
137155
{
138156
if (($this->defaultFetchType != 'array') && ($this->defaultFetchType != 'object')) {
139157
$className = ($className !== null) ? $className : $this->defaultFetchType;
@@ -142,10 +160,9 @@ public function fetchClass($statement, array $params = array(), array $paramType
142160
throw new \Exception("No valid Entity Class is given");
143161
}
144162

145-
//
146163
$this->connect();
147164

148-
return $this->select($statement, $params, $paramTypes, $className);
165+
return $this->select($statement, $params, $paramTypes, $className, $fetchAll);
149166
}
150167

151168
/**

system/DBAL/Manager.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ class Manager
2424
private static $instances = array();
2525

2626

27+
/**
28+
* Get connection instance
29+
*
30+
* @param string $linkName Optional custom link name
31+
* @return Connection Connection instance
32+
*
33+
* @throws \Doctrine\DBAL\DBALException
34+
* @throws \Exception
35+
*/
2736
public static function getConnection($linkName = 'default')
2837
{
2938
$config = Config::get('database');
@@ -82,6 +91,7 @@ public static function getConnection($linkName = 'default')
8291
$linkConfig = new Configuration();
8392

8493
// Get a Connection instance
94+
/** @var Connection $connection */
8595
$connection = DriverManager::getConnection($linkParams, $linkConfig);
8696

8797
// Set the (default) FetchMode and FetchType

system/ORM/Entity.php

Lines changed: 41 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -140,156 +140,68 @@ public function getPrimaryKey($types = false)
140140
return $data;
141141
}
142142

143+
143144
/**
144-
* Prepare the where, return an array with the following details:
145-
* 'where' => 'SQL Where Clause'
146-
* 'bindValues' => array with values for binding.
147-
* 'bindTypes' => array with types for binding.
148-
*
149-
* @param array $criteria Should be either
150-
* 'column' => 'value'
151-
* or:
152-
* 'column' => array('LIKE' => 'value')
153-
* 'column' => array('=' => 'value')
154-
* 'column' => array('>=' => 'value')
155-
* 'column' => array('<=' => 'value')
156-
* 'column' => array('>' => 'value')
157-
* 'column' => array('<' => 'value')
158-
* 'column' => array('IN' => array('value', 'value'))
159-
*
160-
* @param string|null $singleOperator Operator when doing a single criteria inline
161-
* @param string|null $singleValue Single or array value(s) when doing a single criteria inline
162-
*
163-
* @return array Where and bind result
164-
*
165-
* @throws \Exception Exceptions on error in the where criteria
145+
* Start a query
146+
* @return Query
166147
*/
167-
private static function _prepareWhere($criteria, $singleOperator = null, $singleValue = null)
148+
public static function query()
168149
{
169-
// Check parameter
170-
if (! is_array($criteria) && ($singleOperator == null || $singleValue == null)) {
171-
return false;
172-
}
173-
174-
// Prepare returning result
175-
$result = array(
176-
'where' => '',
177-
'bindValues' => array(),
178-
'bindTypes' => array()
179-
);
150+
return new Query(static::class);
151+
}
180152

181-
// Map a single criteria to the normal array criteria.
182-
if (is_string($criteria) && $singleOperator !== null && $singleValue !== null) {
183-
$criteria = array($criteria => array($singleOperator => $singleValue));
153+
/**
154+
* Find multiple entities by searching on the primary key values given
155+
*
156+
* @param array $ids Array of primary key values possible to return
157+
* @return array<T>|Entity[]|false Array of entities or false on not found.
158+
* @throws \Exception Exceptions are thrown when errors occur.
159+
*/
160+
public static function findMany($ids)
161+
{
162+
if (! is_array($ids)) {
163+
throw new \UnexpectedValueException("IDs should be an array if primary key values!");
184164
}
185165

186-
// First we will loop through the criteria and prepare the where clause
187-
$where = "";
188-
$bindValues = array();
189-
$bindTypes = array();
190-
191-
$idx = 0;
192-
foreach ($criteria as $column => $value) {
193-
// Check for operators, if no operator, add it explicit
194-
if (!is_array($value)) {
195-
$value = array('=' => $value);
196-
}
197-
198-
// Will contain [operator] => value
199-
$operator = array_keys($value);
200-
201-
// Few checks
202-
if (count($operator) !== 1) {
203-
throw new \Exception("The operator => value should contain only one operator, " . count($operator) . " operators given for column " . $column);
204-
}
205-
206-
// Get the real operator and value
207-
$operator = $operator[0];
208-
$value = $value[$operator];
209-
210-
// More checks for value
211-
if (is_array($value) && $operator !== 'IN') {
212-
throw new \Exception("Value is an array in the criteria of column " . $column . ". Only IN operator allows arrays given as criteria value!");
213-
}
214-
if ($operator == 'IN' && !is_array($value)) {
215-
throw new \Exception("Value should be an array of values criteria of column " . $column . ". Because you are using the IN operator!");
216-
}
217-
218-
// Adding basic where
219-
$where .= "$column ";
220-
221-
// The IN magic:
222-
if ($operator == 'IN' && is_array($value)) {
223-
$where .= " IN (";
224-
225-
$subIdx = 0;
226-
227-
foreach ($value as $item => $subValue) {
228-
$where .= "?";
229-
if (($subIdx + 1) !== count($value)) {
230-
$where .= ",";
231-
}
232-
233-
$bindValues[] = $subValue;
234-
$bindTypes[] = is_int($subValue) ? PDO::PARAM_INT : PDO::PARAM_STR;
235-
236-
$subIdx++;
237-
}
238-
$where .= ")";
239-
} else {
240-
// None IN, just single where clause item.
241-
$where .= "$operator ?";
242-
$bindValues[] = $value;
243-
$bindTypes[] = is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR;
244-
}
245-
246-
// If not the end of the criteria, then add AND to it.
247-
if (($idx + 1) !== count($criteria)) {
248-
$where .= " AND ";
249-
}
250-
251-
252-
$idx++;
166+
$primaryKey = Structure::getTablePrimaryKey(static::class);
167+
if ($primaryKey === false) {
168+
throw new \Exception("Primary Key can't be detected!");
253169
}
170+
// Only get column name for the primary key
171+
$primaryKey = $primaryKey->name;
254172

255-
$result['where'] = $where;
256-
$result['bindValues'] = $bindValues;
257-
$result['bindTypes'] = $bindTypes;
173+
/** @var Entity[] $result */
174+
$result = static::query()->where(array($primaryKey => array("IN" => $ids)))->all();
258175

176+
// Return results
259177
return $result;
260178
}
261179

262180

263-
264-
265-
266181
/**
267-
* Find entity by searching for the exact ID key.
182+
* Find entity by searching for the exact ID key. Or create Query and return query.
268183
*
269-
* @param string|int $id Primary key value
270-
* @return Entity|false
184+
* @param string|int|null $id Primary key value, Ignore for query building.
185+
* @return Entity|Query|false
271186
*
272187
* @throws \Exception
273188
*/
274-
public static function find($id)
189+
public static function find($id = null)
275190
{
276-
$primaryKey = Structure::getTablePrimaryKey(static::class);
277-
278-
if ($primaryKey === false) {
279-
throw new \Exception("Primary Key can't be detected!");
191+
if ($id === null) {
192+
return static::query();
280193
}
281-
// Only get column name
282-
$primaryKey = $primaryKey->name;
283194

284-
/** @var Entity $result */
285-
$result = self::getLink()->fetchClass("SELECT * FROM " . Structure::getTable(static::class)->getFullTableName() . " WHERE $primaryKey = :pkvalue", array(':pkvalue' => $id), array(), static::class);
195+
$many = static::findMany(array($id));
286196

287-
if($result instanceof Entity) {
288-
$result->_state = 1;
197+
if (count($many) <> 1) {
198+
return false;
199+
}
200+
$result = $many[0];
289201

202+
if($result instanceof Entity) {
290203
return $result;
291204
}
292-
293205
return false;
294206
}
295207

@@ -314,29 +226,15 @@ public static function find($id)
314226
*/
315227
public static function findBy($criteria, $operator = null, $value = null)
316228
{
317-
if (! is_array($criteria) && ($operator == null || $value == null))
229+
if (! is_array($criteria) && ($operator == null && $value == null))
318230
{
319-
throw new \UnexpectedValueException("Criteria should be an array!");
231+
throw new \UnexpectedValueException("Criteria should be an array! Or use the shorthand syntax");
320232
}
321233

322-
// Prepare where statement
323-
$preparedWhere = self::_prepareWhere($criteria, $operator, $value);
324-
325-
$where = $preparedWhere['where'];
326-
327-
$sql = "SELECT * FROM " . Structure::getTable(static::class)->getFullTableName() . " WHERE $where";
328-
$result = self::getLink()->fetchClass($sql, $preparedWhere['bindValues'], $preparedWhere['bindTypes'], static::class);
329-
330-
if($result instanceof Entity) {
331-
$result->_state = 1;
332-
333-
return $result;
334-
}
335-
336-
return false;
234+
// Return result
235+
return static::query()->where($criteria, $operator, $value)->one();
337236
}
338237

339-
340238
/**
341239
* Insert or update the entity in the database
342240
*

0 commit comments

Comments
 (0)