From d71be21fc2aa2a34dcba865bce3b3c08596e6cfe Mon Sep 17 00:00:00 2001 From: Jakob Oberhummer Date: Fri, 29 Sep 2017 12:15:10 +0200 Subject: [PATCH] #13226 Code-examples + cleanup - adds const to Model to avoid typos - add code examples --- phalcon/mvc/model.zep | 119 ++++++++++++++++++++++-------------- phalcon/mvc/model/query.zep | 28 +++++++++ 2 files changed, 101 insertions(+), 46 deletions(-) diff --git a/phalcon/mvc/model.zep b/phalcon/mvc/model.zep index 0a5754a630..69f2013bd4 100644 --- a/phalcon/mvc/model.zep +++ b/phalcon/mvc/model.zep @@ -85,7 +85,6 @@ use Phalcon\Events\ManagerInterface as EventsManagerInterface; */ abstract class Model implements EntityInterface, ModelInterface, ResultInterface, InjectionAwareInterface, \Serializable, \JsonSerializable { - protected _dependencyInjector; protected _modelsManager; @@ -117,6 +116,8 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface protected _oldSnapshot = []; + const TRANSACTION_INDEX = "transaction"; + const OP_NONE = 0; const OP_CREATE = 1; @@ -815,49 +816,59 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface * } * * // encapsulate find it into an running transaction esp. useful for application unit-tests - * // or complex business logic where we wanna control which transactions are used. - * - * $myTransaction = new Transaction(\Phalcon\Di::getDefault()); - * $myTransaction->begin(); - * $newRobot = new Robot(); - * $newRobot->setTransaction($myTransaction); - * $newRobot->save(['name' => 'test', 'type' => 'mechanical', 'year' => 1944]); - * - * $resultInsideTransaction = Robot::find(['name' => 'test', 'transaction' => $myTransaction]); - * $resultOutsideTransaction = Robot::find(['name' => 'test']); - * - * foreach ($setInsideTransaction as $robot) { - * echo $robot->name, "\n"; - * } - * - * foreach ($setOutsideTransaction as $robot) { - * echo $robot->name, "\n"; - * } - * - * // reverts all not commited changes - * $myTransaction->rollback(); - * - * // creating two different transactions - * $myTransaction1 = new Transaction(\Phalcon\Di::getDefault()); - * $myTransaction1->begin(); - * $myTransaction2 = new Transaction(\Phalcon\Di::getDefault()); - * $myTransaction2->begin(); - * - * // add a new robot - * $newRobot = new Robot(); - * $newRobot->setTransaction($myTransaction1); - * $newRobot->save(['name' => 'test', 'type' => 'mechanical', 'year' => 1944]); - * - * // this transaction will not find the robot. - * $resultOutsideExplicitTransaction = Robot::find(['name' => 'test', 'transaction' => $myTransaction2]); - * // this transaction will find the robot - * $resultInsideExplicitTransaction = Robot::find(['name' => 'test', 'transaction' => $myTransaction1]); - * - * // is using the transaction1 and will find the robot - * $resultInsideImplicitTransaction = $robot::find(['name' => 'test']); - * $transaction1->rollback(); - * $transaction2->rollback(); - * + * // or complex business logic where we wanna control which transactions are used. + * + * $myTransaction = new Transaction(\Phalcon\Di::getDefault()); + * $myTransaction->begin(); + * $newRobot = new Robot(); + * $newRobot->setTransaction($myTransaction); + * $newRobot->save(['name' => 'test', 'type' => 'mechanical', 'year' => 1944]); + * + * $resultInsideTransaction = Robot::find(['name' => 'test', Model::TRANSACTION_INDEX => $myTransaction]); + * $resultOutsideTransaction = Robot::find(['name' => 'test']); + * + * foreach ($setInsideTransaction as $robot) { + * echo $robot->name, "\n"; + * } + * + * foreach ($setOutsideTransaction as $robot) { + * echo $robot->name, "\n"; + * } + * + * // reverts all not commited changes + * $myTransaction->rollback(); + * + * // creating two different transactions + * $myTransaction1 = new Transaction(\Phalcon\Di::getDefault()); + * $myTransaction1->begin(); + * $myTransaction2 = new Transaction(\Phalcon\Di::getDefault()); + * $myTransaction2->begin(); + * + * // add a new robots + * $firstNewRobot = new Robot(); + * $firstNewRobot->setTransaction($myTransaction1); + * $firstNewRobot->save(['name' => 'first-transaction-robot', 'type' => 'mechanical', 'year' => 1944]); + * + * $secondNewRobot = new Robot(); + * $secondNewRobot->setTransaction($myTransaction2); + * $secondNewRobot->save(['name' => 'second-transaction-robot', 'type' => 'fictional', 'year' => 1984]); + * + * // this transaction will find the robot. + * $resultInFirstTransaction = Robot::find(['name' => 'first-transaction-robot', Model::TRANSACTION_INDEX => $myTransaction1]); + * // this transaction won't find the robot. + * $resultInSecondTransaction = Robot::find(['name' => 'first-transaction-robot', Model::TRANSACTION_INDEX => $myTransaction2]); + * // this transaction won't find the robot. + * $resultOutsideAnyExplicitTransaction = Robot::find(['name' => 'first-transaction-robot']); + * + * // this transaction won't find the robot. + * $resultInFirstTransaction = Robot::find(['name' => 'second-transaction-robot', Model::TRANSACTION_INDEX => $myTransaction2]); + * // this transaction will find the robot. + * $resultInSecondTransaction = Robot::find(['name' => 'second-transaction-robot', Model::TRANSACTION_INDEX => $myTransaction1]); + * // this transaction won't find the robot. + * $resultOutsideAnyExplicitTransaction = Robot::find(['name' => 'second-transaction-robot']); + * + * $transaction1->rollback(); + * $transaction2->rollback(); * */ public static function find(var parameters = null) -> @@ -901,7 +912,7 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface } } - if fetch transaction, params["transaction"] { + if fetch transaction, params[self::TRANSACTION_INDEX] { if transaction instanceof TransactionInterface { query->setTransaction(transaction); } @@ -956,6 +967,22 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface * ); * * echo "The first virtual robot name is ", $robot->name; + * + * // behaviour with transaction + * $myTransaction = new Transaction(\Phalcon\Di::getDefault()); + * $myTransaction->begin(); + * $newRobot = new Robot(); + * $newRobot->setTransaction($myTransaction); + * $newRobot->save(['name' => 'test', 'type' => 'mechanical', 'year' => 1944]); + * + * $findsARobot = Robot::findFirst(['name' => 'test', Model::TRANSACTION_INDEX => $myTransaction]); + * $doesNotFindARobot = Robot::findFirst(['name' => 'test']); + * + * var_dump($findARobot); + * var_dump($doesNotFindARobot); + * + * $transaction->commit(); + * $doesFindTheRobotNow = Robot::findFirst(['name' => 'test']); * * * @param string|array parameters @@ -991,7 +1018,7 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface let query = builder->getQuery(); - if fetch transaction, params["transaction"] { + if fetch transaction, params[self::TRANSACTION_INDEX] { if transaction instanceof TransactionInterface { query->setTransaction(transaction); } diff --git a/phalcon/mvc/model/query.zep b/phalcon/mvc/model/query.zep index 4baea46a14..f5606d14bc 100644 --- a/phalcon/mvc/model/query.zep +++ b/phalcon/mvc/model/query.zep @@ -63,6 +63,34 @@ use Phalcon\Db\DialectInterface; * echo "Price: ", $row->cars->price, "\n"; * echo "Taxes: ", $row->taxes, "\n"; * } + * + * // with transaction + * use Phalcon\Mvc\Model\Query; + * use Phalcon\Mvc\Model\Transaction; + * + * // $di needs to have the service "db" registered for this to work + * $di = Phalcon\Di\FactoryDefault::getDefault(); + * + * $phql = 'SELECT * FROM robot'; + * + * $myTransaction = new Transaction($di); + * $myTransaction->begin(); + * + * $newRobot = new Robot(); + * $newRobot->setTransaction($myTransaction); + * $newRobot->type = "mechanical"; + * $newRobot->name = "Astro Boy"; + * $newRobot->year = 1952; + * $newRobot->save(); + * + * $queryWithTransaction = new Query($phql, $di); + * $queryWithTransaction->setTransaction($myTransaction); + * + * $resultWithEntries = $queryWithTransaction->execute(); + * + * $queryWithOutTransaction = new Query($phql, $di); + * $resultWithOutEntries = $queryWithTransaction->execute() + * * */ class Query implements QueryInterface, InjectionAwareInterface