Page MenuHomePhabricator

No OneTemporary

diff --git a/db/drivers/mysqlPDOQuery.php b/db/drivers/mysqlPDOQuery.php
index 91f725b..585cabc 100644
--- a/db/drivers/mysqlPDOQuery.php
+++ b/db/drivers/mysqlPDOQuery.php
@@ -1,196 +1,196 @@
<?php namespace spitfire\storage\database\drivers;
use spitfire\exceptions\PrivateException;
use spitfire\model\Field;
use spitfire\storage\database\Relation;
use spitfire\storage\database\Table;
use spitfire\storage\database\Query;
use spitfire\storage\database\QueryField;
use spitfire\storage\database\QueryTable;
class MysqlPDOQuery extends Query
{
public function execute($fields = null) {
$this->setAliased(false);
#Declare vars
$rpp = $this->getResultsPerPage();
$offset = ($this->getPage() - 1) * $rpp;
$selectstt = 'SELECT';
$fromstt = 'FROM';
$tablename = $this->getTable()->getLayout();
$wherestt = 'WHERE';
/** @link http://www.spitfirephp.com/wiki/index.php/Database/subqueries Information about the filter*/
$restrictions = $this->getRestrictions();
$orderstt = 'ORDER BY';
$order = $this->getOrder();
$groupbystt = 'GROUP BY';
$groupby = $this->groupby;
$limitstt = 'LIMIT';
$limit = $offset . ', ' . $rpp;
#Import tables for restrictions from remote queries
$subqueries = $this->getPhysicalSubqueries();
$joins = Array();
foreach ($subqueries as $q) {
$joins[] = sprintf('LEFT JOIN %s ON (%s)', $q->getQueryTable()->definition(), implode(' AND ', $q->getRestrictions()));
}
if ($fields === null) {
- $fields = $this->table->getTable()->getFields();
+ $fields = $this->table->getTable()->getLayout()->getFields();
/*
* If there is subqueries we default to grouping data in a way that will
* give us unique records and the amount of times they appear instead
* of repeating them.
*
* Example: The users followed by users I follow. Even though I cannot
* follow a user twice, two different users I follow can again follow
* the same user. A regular join would produce a dataset where the user
* is included twice, by adding the grouping mechanism we're excluding
* that behavior.
*/
if (!empty($subqueries)) {
$groupby = $fields;
$fields[] = 'COUNT(*) AS __META__count';
}
}
$join = implode(' ', $joins);
#Restrictions
if (empty($restrictions)) {
$restrictions = '1';
}
else {
$restrictions = implode(' AND ', $restrictions);
}
if ($rpp < 0) {
$limitstt = '';
$limit = '';
}
if (empty($order)) {
$orderstt = '';
$order = '';
}
else {
$order = "{$order['field']} {$order['mode']}";
}
if (empty($groupby)) {
$groupbystt = '';
$groupby = '';
}
else {
$groupby = implode(', ', $groupby);
}
$stt = array_filter(Array( $selectstt, implode(', ', $fields), $fromstt, $tablename, $join,
$wherestt, $restrictions, $groupbystt, $groupby, $orderstt, $order, $limitstt, $limit));
return new mysqlPDOResultSet($this->getTable(), $this->getTable()->getDb()->execute(implode(' ', $stt)));
}
/**
*
* @deprecated since version 0.1-dev 20171110
* @param type $parent
* @return \spitfire\storage\database\drivers\MysqlPDORestrictionGroup
*/
public function restrictionGroupInstance($parent = null) {
return new MysqlPDORestrictionGroup($parent? : $this);
}
/**
*
* @deprecated since version 0.1-dev 20171110
* @param QueryField $field
* @param type $value
* @param type $operator
* @return \spitfire\storage\database\drivers\MysqlPDORestriction
*/
public function restrictionInstance(QueryField$field, $value, $operator) {
return new MysqlPDORestriction($this, $field, $value, $operator);
}
/**
*
* @deprecated since version 0.1-dev 20171110
* @param QueryField $field
* @return \spitfire\storage\database\drivers\MysqlPDOQueryField|QueryField
*/
public function queryFieldInstance($field) {
if ($field instanceof QueryField) {return $field; }
return new MysqlPDOQueryField($this, $field);
}
/**
*
* @deprecated since version 0.1-dev 20171110
* @param type $table
* @return \spitfire\storage\database\drivers\MysqlPDOQueryTable
* @throws PrivateException
*/
public function queryTableInstance($table) {
if ($table instanceof Relation) { $table = $table->getTable(); }
if ($table instanceof QueryTable) { $table = $table->getTable(); }
if (!$table instanceof Table) { throw new PrivateException('Did not receive a table as parameter'); }
return new MysqlPDOQueryTable($this, $table);
}
/**
*
* @deprecated since version 0.1-dev 20171110
*/
public function compositeRestrictionInstance(Field $field = null, $value, $operator) {
return new MysqlPDOCompositeRestriction($this, $field, $value, $operator);
}
public function delete() {
$this->setAliased(false);
#Declare vars
$selectstt = 'DELETE';
$fromstt = 'FROM';
$tablename = $this->getTable();
$wherestt = 'WHERE';
/** @link http://www.spitfirephp.com/wiki/index.php/Database/subqueries Information about the filter*/
$restrictions = array_filter($this->getRestrictions(), Array('spitfire\storage\database\Query', 'restrictionFilter'));
#Import tables for restrictions from remote queries
$subqueries = $this->getPhysicalSubqueries();
$joins = Array();
foreach ($subqueries as $q) {
$joins[] = sprintf('LEFT JOIN %s ON (%s)', $q->getQueryTable()->definition(), implode(' AND ', $q->getRestrictions()));
}
$join = implode(' ', $joins);
#Restrictions
if (empty($restrictions)) {
$restrictions = '1';
}
else {
$restrictions = implode(' AND ', $restrictions);
}
$stt = array_filter(Array( $selectstt, $fromstt, $tablename, $join,
$wherestt, $restrictions));
$this->getTable()->getDb()->execute(implode(' ', $stt));
}
}
\ No newline at end of file
diff --git a/db/drivers/mysqlPDORes.php b/db/drivers/mysqlPDORes.php
index 34c618c..4ed45c5 100644
--- a/db/drivers/mysqlPDORes.php
+++ b/db/drivers/mysqlPDORes.php
@@ -1,67 +1,67 @@
<?php namespace spitfire\storage\database\drivers;
use PDO;
/**
* This class works as a traditional resultset. It acts as an adapter between the
* driver's raw data retrieving and the logical record classes.
*
* @author César de la Cal <cesar@magic3w.com>
*/
class mysqlPDOResultSet implements \spitfire\storage\database\ResultSetInterface
{
/**
* Contains the raw pointer that PDO has created when executing the query.
* This allows spitfire to retrieve all the data needed to create a complete
* database record.
*
* @var PDOStatement
*/
private $result;
/**
* This is a reference to the table this resultset belongs to. This allows
* Spitfire to retrieve data about the model and the fields the datatype has.
*
* @var \spitfire\storage\database\Table
*/
private $table;
public function __construct(\spitfire\storage\database\Table$table, $stt) {
$this->result = $stt;
$this->table = $table;
}
public function fetch() {
$data = $this->result->fetch(PDO::FETCH_ASSOC);
#If the data does not contain anything we return a null object
if (!$data) { return null; }
$_record = array_map( Array($this->table->getDB()->getEncoder(), 'decode'), $data);
- $record = $this->table->getDb()->table($this->table->getModel()->getName())->newRecord($_record);
+ $record = $this->table->newRecord($_record);
return $record;
}
public function fetchAll() {
$data = $this->result->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as &$record) {
$record = $this->table->getDb()->table($this->table->getModel()->getName())->newRecord(
array_map( Array($this->table->getDB()->getEncoder(), 'decode'), $record)
);
}
return $data;
}
/**
* Returns the data the way any associative adapter would return it. This allows
* your app to withdraw raw data without it being treated by the framework.
*
* @return mixed
*/
public function fetchArray() {
return $this->result->fetch(PDO::FETCH_ASSOC);
}
}
diff --git a/storage/database/ObjectFactoryInterface.php b/storage/database/ObjectFactoryInterface.php
index 034e10e..1681f0d 100644
--- a/storage/database/ObjectFactoryInterface.php
+++ b/storage/database/ObjectFactoryInterface.php
@@ -1,170 +1,170 @@
<?php namespace spitfire\storage\database;
use spitfire\model\Field as LogicalField;
/*
* The MIT License
*
* Copyright 2016 César de la Cal Bretschneider <cesar@magic3w.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* The database object factory is a class that allows a driver to provide SF's
* ORM with all the required bits and pieces to operate. Usually a driver needs
* to provide it's own Table, Query, Field... objects that implement / extend
* the behavior required for the ORM to work.
*
* Historically, a query would provide only the pieces it needed, as well as the
* table would. But for consistency, and to avoid generating classes that only
* need to extend in order to provide factories we're merging those behaviors
* in this single factory.
*/
interface ObjectFactoryInterface
{
/**
* Returns an instance of the class the child tables of this class have
* this is used to create them when requested by the table() method.
*
* @deprecated since version 0.1-dev 20170801
*
* @param DB $db
* @param string $tablename
*
* @return Table Instance of the table class the driver wants the system to use
*/
function getTableInstance(DB$db, $tablename);
/**
* Creates a relation. These wrap the typical record operations on a table
* into a separate layer.
*
* @param Table $table
*
* @return Relation
*/
function makeRelation(Table$table);
/**
* Creates a table layout to generate an appropriate schema for the DBMS to
* store the data.
*
* @param Table $table
*
* @return LayoutInterface The layout for the table
*/
function makeLayout(Table$table);
/**
* Creates a new On The Fly Schema. These allow the system to interact with a
* database that was not modeled after Spitfire's models or that was not
* reverse engineered previously.
*
* @param string $modelname
*
* @return Table Instance of the table class the driver wants the system to use
* @todo Rename to generateSchema
*/
function getOTFSchema($modelname);
/**
* Creates an instance of the Database field compatible with the current
* DBMS. As opposed to the Logical fields, physical fields do not accept
* complex values, just basic types that any DBMS can handle.
*
* @param Field $field
* @param string $name
* @param Field $references
*
* @return Field Field
* @todo Rename to makeField
*/
function getFieldInstance(LogicalField$field, $name, Field$references = null);
/**
* Creates a new restriction. This combines a query with a field and a value
* which allows to create the queries that we need to construct in order to
* retrieve data.
*
* @param string $query
- * @param Field $field
+ * @param QueryField $field
* @param mixed $value
* @param string|null $operator
*
* @return Restriction|CompositeRestriction
* @todo Rename to makeRestriction
*/
- function restrictionInstance($query, Field$field, $value, $operator = null);
+ function restrictionInstance($query, QueryField$field, $value, $operator = null);
/**
*
* @todo This is supposed to take a RestrictionGroup
* @param Query $query
* @param LogicalField $field
* @param mixed $value
* @param string $operator
*/
function restrictionCompositeInstance(Query$query, LogicalField$field = null, $value, $operator);
/**
* Creates a restriction group. This allows to associate several restrictions
* with each other to create more complicated queries when writing.
*
* @param RestrictionGroup $parent
* @param int $type
* @return RestrictionGroup A restriction group
*/
function restrictionGroupInstance(RestrictionGroup$parent = null, $type = RestrictionGroup::TYPE_OR);
/**
* Creates a new query. A query is created with a table to provide information
* where the data should be retrieved some and some information on the fields
* that we want it to provide.
*
* @param Table|Relation $table
*
* @return Query
* @todo Rename to makeQuery
*/
function queryInstance($table);
/**
* These objects connect a field with a query, providing an aliased name for
* the field when necessary.
*
* @param Query $query
* @param QueryField $field
* @return QueryField
*/
function queryFieldInstance($query, $field);
/**
* These objects connect a field with a query, providing an aliased name for
* the field when necessary.
*
* @param Query $query
* @param QueryTable|Table $table
* @return QueryTable
*/
function queryTableInstance($query, $table);
}
diff --git a/storage/database/drivers/mysqlpdo/ObjectFactory.php b/storage/database/drivers/mysqlpdo/ObjectFactory.php
index 2215e15..a8746b3 100644
--- a/storage/database/drivers/mysqlpdo/ObjectFactory.php
+++ b/storage/database/drivers/mysqlpdo/ObjectFactory.php
@@ -1,181 +1,181 @@
<?php namespace spitfire\storage\database\drivers\mysqlpdo;
use BadMethodCallException;
use spitfire\exceptions\PrivateException;
use spitfire\model\Field as LogicalField;
use spitfire\storage\database\DB;
use spitfire\storage\database\drivers\MysqlPDOCompositeRestriction;
use spitfire\storage\database\drivers\mysqlPDOField;
use spitfire\storage\database\drivers\MysqlPDOQuery;
use spitfire\storage\database\drivers\MysqlPDOQueryField;
use spitfire\storage\database\drivers\MysqlPDOQueryTable;
use spitfire\storage\database\drivers\MysqlPDORestriction;
use spitfire\storage\database\drivers\MysqlPDORestrictionGroup;
use spitfire\storage\database\drivers\MysqlPDOTable;
use spitfire\storage\database\Field;
use spitfire\storage\database\LayoutInterface;
use spitfire\storage\database\ObjectFactoryInterface;
use spitfire\storage\database\Query;
use spitfire\storage\database\QueryField;
use spitfire\storage\database\QueryTable;
use spitfire\storage\database\RestrictionGroup;
use spitfire\storage\database\Schema;
use spitfire\storage\database\Table;
use TextField;
use function db;
/*
* The MIT License
*
* Copyright 2016 César de la Cal Bretschneider <cesar@magic3w.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* The object factory class allows a Database to centralize a point where the
* database objects can retrieve certain items from. As opposed to having this
* algorithms in every class, as some classes would just be overriding one factory
* method they needed in a completely standard class.
*
* This allows Spitfire to define certain behaviors it expects from DB objects
* and then have the driver provide this to not disturb Spitfire's logic.
*
* @author César de la Cal Bretschneider <cesar@magic3w.com>
*/
class ObjectFactory implements ObjectFactoryInterface
{
/**
* Creates a new on the fly model. This means that the model is created during
* runtime, and by reverse engineering the tables that the database already
* has.
*
* Please note, that this model would not perfectly replicate a model you could
* build with a proper definition yourself.
*
* @todo At the time of writing this, the method does not use adequate types.
* @param string $modelname
* @return Table
*/
public function getOTFSchema($modelname) {
#Create a Schema we can feed the data into.
$schema = new Schema($modelname);
#Make the SQL required to read in the data
$sql = sprintf('DESCRIBE `%s%s`', $schema->getTableName(), $modelname);
/** @var $fields Query */
$fields = db()->execute($sql, false);
while ($row = $fields->fetch()) {
$schema->{$row['Field']} = new TextField();
}
return $schema->getTable();
}
/**
* Creates a new driver specific table. The table is in charge of providing
* the necessary tools for records to be updated, inserted, deleted, etc.
*
* @param DB $db
* @param string $tablename
* @deprecated since version 0.1-dev 20170807
* @return MysqlPDOTable
*/
public function getTableInstance(DB $db, $tablename) {
return new MysqlPDOTable($db, $tablename);
}
/**
* Creates a new MySQL PDO Field object. This receives the fields 'prototype',
* name and reference (in case it references an externa field).
*
* This represents an actual field in the DBMS as opposed to the ones in the
* model. That's why here we talk of "physical" fields
*
* @todo This should be moved over to a DBMS specific object factory.
* @param Field $field
* @param string $name
* @param Field $references
* @return mysqlPDOField
*/
public function getFieldInstance(LogicalField$field, $name, Field$references = null) {
return new mysqlPDOField($field, $name, $references);
}
- public function restrictionInstance($query, Field$field, $value, $operator = null) {
+ public function restrictionInstance($query, QueryField$field, $value, $operator = null) {
return new MysqlPDORestriction($query, $field, $value, $operator);
}
/**
* Makes a new query on a certain table.
*
* @param Table $table
*
* @return MysqlPDOQuery
* @throws PrivateException
*/
public function queryInstance($table) {
if ($table instanceof Relation){ $table = $table->getTable(); }
if (!$table instanceof Table) { throw new PrivateException('Need a table object'); }
return new MysqlPDOQuery($table);
}
public function makeRelation(Table $table) {
return new Relation($table);
}
public function __call($name, $args) {
throw new BadMethodCallException("Called ObjectFactory::$name. Method does not exist");
}
public function makeLayout(Table $table): LayoutInterface {
return new Layout($table);
}
public function restrictionGroupInstance(RestrictionGroup $parent = null, $type = RestrictionGroup::TYPE_OR): RestrictionGroup {
$g = new MysqlPDORestrictionGroup($parent);
$g->setType($type);
return $g;
}
public function queryFieldInstance($query, $field) {
if ($field instanceof QueryField) {return $field; }
- return new MysqlPDOQueryField($this, $field);
+ return new MysqlPDOQueryField($query, $field);
}
public function queryTableInstance($query, $table) {
if ($table instanceof Relation) { $table = $table->getTable(); }
if ($table instanceof QueryTable) { $table = $table->getTable(); }
if (!$table instanceof Table) { throw new PrivateException('Did not receive a table as parameter'); }
return new MysqlPDOQueryTable($query, $table);
}
public function restrictionCompositeInstance(Query $query, LogicalField$field = null, $value, $operator) {
return new MysqlPDOCompositeRestriction($query, $field, $value, $operator);
}
}
diff --git a/tests/storage/database/drivers/mysqlpdo/QueryTest.php b/tests/storage/database/drivers/mysqlpdo/QueryTest.php
index c4e0eb8..29eb137 100644
--- a/tests/storage/database/drivers/mysqlpdo/QueryTest.php
+++ b/tests/storage/database/drivers/mysqlpdo/QueryTest.php
@@ -1,54 +1,60 @@
<?php namespace tests\spitfire\storage\database\drivers\mysqlpdo;
use IntegerField;
use PHPUnit\Framework\TestCase;
use spitfire\exceptions\PrivateException;
use spitfire\storage\database\drivers\mysqlpdo\Driver;
use spitfire\storage\database\Schema;
use spitfire\storage\database\Settings;
use spitfire\storage\database\Table;
use StringField;
class QueryTest extends TestCase
{
private $db;
/**
* The table we're testing.
*
* @var Table
*/
private $table;
private $schema;
public function setUp() {
//Just in case Mr. Bergmann decides to add code to the setUp
parent::setUp();
try {
$this->db = new Driver(Settings::fromArray([]));
$this->db->create();
$this->schema = new Schema('test');
$this->schema->field1 = new IntegerField(true);
$this->schema->field2 = new StringField(255);
$this->table = new Table($this->db, $this->schema);
+ $this->table->getLayout()->create();
}
catch (PrivateException$e) {
$this->markTestSkipped('MySQL PDO driver is not available.');
}
}
public function tearDown() {
$this->db->destroy();
}
public function testQuery() {
+ $record = $this->table->newRecord();
+ $record->field1 = 1;
+ $record->field2 = 'Test';
+ $record->store();
+
$result = $this->table->get('field1', 1)->fetch();
$this->assertNotEquals(null, $result);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Apr 14, 6:48 PM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2034
Default Alt Text
(22 KB)

Event Timeline