/** * Create new model * * <code> * $post = new BloPost; * * $post = new BloPost([ * 'title' => 'Hello', * 'body' => 'World!' * ]); * </code> * * **NOTE:** This method does not save anything to database * * - New model is not saved to the database and has $this->isNewRecord() == true * - If $attrs has **'id'** key then model with the same id will be loaded from * the database and its attributes will be overwritten (but not saved) * * @param array $attrs Associative array representing new model properies */ public function __construct($attrs = null) { parent::__construct(); $this->className = get_class($this); if (!$this->table) { $this->table = $this->classNameToTableName($this->className); } $this->makeReflection(); $this->isDeletedRecord = false; $this->checkAssociationClasses(); $this->associationsCache = []; if ($attrs) { if (array_key_exists('id', $attrs)) { $this->id = $attrs["id"]; $this->reload(); } foreach ($attrs as $name => $value) { if (!in_array($name, $this->attributes)) { throw new TipyModelException("Unknown property '" . $name . "' for " . $this->className); } $this->data[$name] = $value; } } }
/** * Rollback transaction * @throws TipyDaoException if there is no transaction in progress * @return mysqli_result */ private static function rollbackTransaction($kind = 'soft') { $app = TipyApp::getInstance(); if (self::$openTransactionsCount == 0) { throw new TipyDaoException('No transaction in progress'); } elseif ($kind == 'hard') { // rollback parent transaction with all nested savepoints $app->logger->debug('ROLLBACK'); $result = $app->db->query('ROLLBACK'); if ($result) { self::$openTransactionsCount = 0; } } elseif (self::$openTransactionsCount == 1) { $app->logger->debug('ROLLBACK'); $result = $app->db->query('ROLLBACK'); if ($result) { self::$openTransactionsCount = 0; } } elseif (self::$openTransactionsCount > 1) { $app->logger->debug('ROLLBACK TO SAVEPOINT ' . self::currentSavepointName()); $result = $app->db->query('ROLLBACK TO SAVEPOINT ' . self::currentSavepointName()); if ($result) { self::$openTransactionsCount--; } } else { // Just to be sure throw new TipyDaoException('Negative open transactions counter. Please contact tipy maintainers'); } return $result; }
public function testNestedTransaction() { $dao = new TipyDAO(); $this->assertEqual($dao->currentSavepointName(), null); $this->assertEqual(Record::count(), 0); TipyModel::transaction(function () use($dao) { $this->createRecord(1); $this->createRecord(2); $this->createRecord(3); $this->assertEqual(Record::count(), 3); $this->assertEqual($dao->currentSavepointName(), null); TipyModel::transaction(function () use($dao) { $this->createRecord(4); $this->createRecord(5); $this->assertEqual(Record::count(), 5); $this->assertEqual($dao->currentSavepointName(), 'tipy_savepoint_1'); TipyModel::rollback(); }); $this->assertEqual($dao->currentSavepointName(), null); $this->assertEqual(Record::count(), 3); $this->createRecord(4); $this->assertEqual(Record::count(), 4); TipyModel::transaction(function () use($dao) { $this->assertEqual($dao->currentSavepointName(), 'tipy_savepoint_1'); $this->createRecord(5); $this->createRecord(6); $this->assertEqual(Record::count(), 6); TipyModel::transaction(function () use($dao) { $this->assertEqual($dao->currentSavepointName(), 'tipy_savepoint_2'); $this->createRecord(7); $this->createRecord(8); $this->assertEqual(Record::count(), 8); TipyModel::rollback(); }); $this->assertEqual($dao->currentSavepointName(), 'tipy_savepoint_1'); }); $this->assertEqual(Record::count(), 6); $this->assertEqual($dao->currentSavepointName(), null); }); $this->assertEqual(Record::count(), 6); }
/** * Run test suite * * Execute all <b>test*</b> methods from test suite * and collect results */ public function run() { $className = get_class($this); $methods = get_class_methods($className); foreach ($methods as $testName) { if (!preg_match("/^test/", $testName)) { continue; } $this->tests++; $this->clearAppContext(); $this->setUp(); $testClosure = function () use($testName) { try { $this->{$testName}(); echo TipyCli::green('.'); } catch (AssertionFailedException $e) { $this->failures[] = $e; echo TipyCli::purple('F'); } catch (Exception $e) { $this->exceptions[] = $e; echo TipyCli::red('E'); } }; if ($this->transactionalFixtures) { TipyDAO::transaction(function () use($testName, $testClosure) { $testClosure(); TipyDAO::rollback(); }); } else { $testClosure(); } $this->tearDown(); } }