PHP Classes

PHP Transactional Containers: Wrap editing objects with a transaction manager

Recommend this page to a friend!
  Info   View files Documentation   View files View files (25)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog (1)    
Last Updated Ratings Unique User Downloads Download Rankings
2023-11-30 (5 months ago) RSS 2.0 feedNot yet rated by the usersTotal: 33 All time: 11,002 This week: 560Up
Version License PHP version Categories
containers-transacti 1.0.0MIT/X Consortium ...7Language, Design Patterns, PHP 7
Description 

Author

This package can wrap editing objects with a transaction manager object.

It provides a transaction manager class for developers to add transaction support to objects that edit data.

Applications can use the wrapper object without changing the data objects or the application, besides changing the code to use the wrapper object instead of the data object and using the transaction functions like committing and rolling back transactions.

Innovation Award
PHP Programming Innovation award nominee
December 2023
Number 7
Transactions are a sequence of operations that must be executed in an atomic way. This means that if one of the operations of the sequence fails, all operations executed previously need to be reverted.

If you use a database server like MySQL or others, they support transactions.

Now, it may be hard to support transactions if you use a data object that may use a database server or not, and you have not anticipated the support for transactions since the beginning.

This package can help add transaction support to an application that uses data objects by adding minimal code to improve the application's robustness.

Manuel Lemos
Picture of Smoren  Freelight
  Performance   Level  
Name: Smoren Freelight <contact>
Classes: 38 packages by
Country: Russian Federation Russian Federation
Age: 34
All time rank: 284078 in Russian Federation Russian Federation
Week rank: 301 Up13 in Russian Federation Russian Federation Up
Innovation award
Innovation award
Nominee: 16x

Documentation

Transactional containers and data structures

Abstract wrapper structure for providing transactional interface for editing objects.

Includes implementations of transactional wrappers for some data containers and structures.

How to install as dependency to your project

composer require smoren/containers-transactional

Unit testing

composer install
./vendor/bin/codecept build
./vendor/bin/codecept run unit tests/unit

Using with your class

Class definitions

use Smoren\Containers\Transactional\Base\TransactionWrapper;
use Smoren\Containers\Transactional\Base\Validator;
use Smoren\Containers\Transactional\Interfaces\ValidationRuleInterface;

/
 * Your class that you want to wrap with transactional interface
 */
class YourClass {
    /
     * Example attribute
     * @var int 
     */
    public $someAttribute = 1;
    // ...
}

/
 * @see Smoren\Containers\Transactional\Structs\TLinkedList
 */
class TYourClass extends TransactionWrapper
{
    /
     * This overriding is needed only to specify method's return type
     * @inheritDoc
     */
    public function getWrapped(): YourClass
    {
        return parent::getWrapped();
    }

    /
     * Unnecessary override if there is not default value of YourClass
     * @inheritDoc
     */
    protected function getDefaultWrapped()
    {
        return new YourClass();
    }

    /
     * @inheritDoc
     * @return string
     */
    protected function getWrappedType(): ?string
    {
        return YourClass::class;
    }
    
    /
     * Unnecessary override if you are not going to use validation
     * @inheritDoc
     * @return Validator
     * @throws \Smoren\ExtendedExceptions\LogicException
     */
    protected function getDefaultValidator(): ?Validator
    {
        return (new Validator())
            ->addRule('validation_rule_alias', MyValidationRule::class);
    }
}

/
 * This declaration is not necessary if you are not going to use validation
 * @see Smoren\Containers\Transactional\Tests\Unit\Utility\PositiveNumberValidationRule
 */
class MyValidationRule implements ValidationRuleInterface
{
    protected array $errors = [];
    
    /
     * @inheritDoc
     */
    public function validate($data, $owner): bool
    {
        // ...
        return true;
    }

    /
     * @inheritDoc
     */
    public function getErrors()
    {
        return $this->errors;
    }
}

Client code

use Smoren\Containers\Transactional\Exceptions\ValidationException;

$yourObject = new YourClass();
$tWrapper = new TYourClass($yourObject);

echo $yourObject->someAttribute; // output: 1
echo $tWrapper->getWrapped()->someAttribute; // output: 1

$tWrapper->interact(function(YourClass $tmpObjectState) {
    $tmpObjectState->someAttribute = 2;
});

echo $yourObject->someAttribute; // output: 1

try {
    $tWrapper->validate(); // validate only
    echo $yourObject->someAttribute; // output: 1
} catch(ValidationException $e) {
    print_r($e->getErrors()); // output: ['validation_rule_alias' => [...]]
}

try {
    $tWrapper->apply(); // validate and apply
    echo $yourObject->someAttribute; // output: 2
} catch(ValidationException $e) {
    print_r($e->getErrors()); // output: ['validation_rule_alias' => [...]]
}

Ready to use transactional containers

TArray

Wraps PHP array with transactional interface.

use Smoren\Containers\Transactional\Structs\TArray;
use Smoren\Containers\Transactional\Exceptions\ValidationException;

$ta = new TArray([1, 2, 3]);
print_r($ta->getWrapped()); // output: [1, 2, 3]

$ta->interact(function(array &$arr) {
    array_push($arr, 4);
    array_push($arr, 5);
    $arr[0] = 0;
});


try {
    print_r($ta->getWrapped()); // output: [1, 2, 3]
    $ta->apply();
    print_r($ta->getWrapped()); // output: [0, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}

TLinkedList

Classic implementation of linked list data structure wrapped with transactional interface.

Wraps LinkedList container.

use Smoren\Containers\Transactional\Structs\TLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\LinkedList;

$tll = new TLinkedList([1, 2, 3]);
print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3]

$tll->interact(function(LinkedList $list) {
    $list->pushBack(4);
    $list->pushBack(5);
});

try {
    print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3]
    $tll->apply();
    print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}

TMappedCollection

Map-like data structure with transactional interface.

Wraps MappedCollection container.

use Smoren\Containers\Transactional\Structs\TMappedCollection;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\MappedCollection;

$tmc = new TMappedCollection([
    '0' => ['id' => 0],
]);

print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0]]

$tmc->interact(function(MappedCollection $collection) {
    $collection
        ->add('1', ['id' => 1])
        ->add('2', ['id' => 2])
        ->delete('2');
});

try {
    print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0]]
    $tmc->apply();
    print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0], ['1' => ['id' => 1]]]
} catch(ValidationException $e) {
    // if validation failed
}

TMappedLinkedList

LinkedList with mapping by id and with transactional interface.

Wraps MappedLinkedList container.

use Smoren\Containers\Transactional\Structs\TMappedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\MappedLinkedList;

$tmll = new TMappedLinkedList(
    new MappedLinkedList([1 => 11])
);

print_r($tmll->getWrapped()->toArray()); // output: [1 => 11]

$tmll->interact(function(MappedLinkedList $list) {
    $list->pushBack(2, 22);
    $list->pushBack(3, 33);
});

try {
    print_r($tmll->getWrapped()->toArray()); // output: [1 => 11]
    $tmll->apply();
    print_r($tmll->getWrapped()->toArray()); // output: [1 => 11, 2 => 22, 3 => 33]
} catch(ValidationException $e) {
    // if validation failed
}

TSortedLinkedList

LinkedList with presort and transactional interface.

Wraps SortedLinkedList container.

use Smoren\Containers\Transactional\Structs\TSortedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\SortedLinkedList;

/
 * Class IntegerSortedLinkedList
 */
class IntegerSortedLinkedList extends SortedLinkedList
{
    /
     * @inheritDoc
     */
    protected function getComparator(): callable
    {
        return function(int $lhs, int $rhs) {
            return $lhs > $rhs;
        };
    }
}

$tsll = new TSortedLinkedList(
    new IntegerSortedLinkedList([4, 1, 2])
);

print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 4]

$tsll->interact(function(IntegerSortedLinkedList $list) {
    $list->insert(5);
    $list->insert(3);
});

try {
    print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 4]
    $tsll->apply();
    print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}

TSortedMappedLinkedList

LinkedList with presort, mapping and transactional interface.

Wraps SortedMappedLinkedList container.

use Smoren\Containers\Transactional\Structs\TSortedMappedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\SortedMappedLinkedList;

$tsmll = new TSortedMappedLinkedList(
    new SortedMappedLinkedList([2 => -2, 1 => -1, 4 => -4])
);

print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 4 => -4]

$tsmll->interact(function(SortedMappedLinkedList $list) {
    $list->insert(3, 0);
});

try {
    print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 4 => -4]
    $tsmll->apply();
    print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 3 => 0, 4 => -4]
} catch(ValidationException $e) {
    // if validation failed
}

  Files folder image Files  
File Role Description
Files folder imagesrc (4 directories)
Files folder imagetests (2 files, 1 directory)
Accessible without login Plain text file codeception.yml Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  src  
File Role Description
Files folder imageBase (2 files)
Files folder imageExceptions (2 files)
Files folder imageInterfaces (3 files)
Files folder imageStructs (6 files)

  Files folder image Files  /  src  /  Base  
File Role Description
  Plain text file TransactionWrapper.php Class Class source
  Plain text file Validator.php Class Class source

  Files folder image Files  /  src  /  Exceptions  
File Role Description
  Plain text file ValidationException.php Class Class source
  Plain text file WrapperException.php Class Class source

  Files folder image Files  /  src  /  Interfaces  
File Role Description
  Plain text file RecursiveTransactional.php Class Class source
  Plain text file Restorable.php Class Class source
  Plain text file ValidationRuleInterface.php Class Class source

  Files folder image Files  /  src  /  Structs  
File Role Description
  Plain text file TArray.php Class Class source
  Plain text file TLinkedList.php Class Class source
  Plain text file TMappedCollection.php Class Class source
  Plain text file TMappedLinkedList.php Class Class source
  Plain text file TSortedLinkedList.php Class Class source
  Plain text file TSortedMappedLinkedList.php Class Class source

  Files folder image Files  /  tests  
File Role Description
Files folder imageunit (1 file, 1 directory)
  Accessible without login Plain text file unit.suite.yml Data Auxiliary data
  Accessible without login Plain text file _bootstrap.php Aux. Auxiliary script

  Files folder image Files  /  tests  /  unit  
File Role Description
Files folder imageUtility (5 files)
  Plain text file MainTest.php Class Class source

  Files folder image Files  /  tests  /  unit  /  Utility  
File Role Description
  Plain text file ArraySortedMappedLinkedList.php Class Class source
  Plain text file IdIssetValidationRule.php Class Class source
  Plain text file IdMappingValidationRule.php Class Class source
  Plain text file IntegerSortedLinkedList.php Class Class source
  Plain text file PositiveNumberValidationRule.php Class Class source

 Version Control Unique User Downloads Download Rankings  
 100%
Total:33
This week:0
All time:11,002
This week:560Up