项目作者: mauretto78

项目描述 :
In-memory List is a PHP library that allows you to create and store in memory your lists, and then quickly retrieve and perform queries on it.
高级语言: PHP
项目地址: git://github.com/mauretto78/in-memory-list.git
创建时间: 2017-04-26T13:48:49Z
项目社区:https://github.com/mauretto78/in-memory-list

开源协议:MIT License

下载


In-memory List

Scrutinizer Code Quality
SensioLabsInsight
Build Status
Codacy Badge
license
Packagist

In-memory List easily allows you to create and save your lists in memory.

If you are looking for a caching system for your lists this library is suitable for you.

Grab your lists from your API, your database or whatever you want and store them in memory: then, you can quickly retrieve your lists from cache, sorting and performing queries on them.

This package uses:

Basic Usage

To create and store in memory you list do the following:

  1. use InMemoryList\Application\Client;
  2. $array = [
  3. ...
  4. ]
  5. $client = new Client();
  6. $collection = $client->create($array);
  7. foreach ($collection as $element){
  8. // ...
  9. }

Drivers

Avaliable drivers:

  • apcu
  • memcached
  • pdo
  • redis (default driver)
  1. use InMemoryList\Application\Client;
  2. // Apcu, no configuration is needed
  3. $client = new Client('apcu');
  4. // ..
  1. use InMemoryList\Application\Client;
  2. // Memcached, you can pass one or more servers
  3. $memcached_parameters = [
  4. [
  5. 'host' => 'localhost',
  6. 'port' => 11211
  7. ],
  8. [
  9. 'host' => 'localhost',
  10. 'port' => 11222
  11. ],
  12. // etc..
  13. ];
  14. $client = new Client('memcached', $memcached_parameters);
  15. // ..
  1. use InMemoryList\Application\Client;
  2. // Pdo
  3. $pdo_parameters = [
  4. 'driver' => 'mysql',
  5. 'host' => '127.0.0.1',
  6. 'username' => 'root',
  7. 'password' => '',
  8. 'database' => 'in-memory-list'
  9. 'port' => '3306'
  10. ];
  11. $client = new Client('pdo', $pdo_parameters);
  12. // ..
  1. use InMemoryList\Application\Client;
  2. // you have to use arrays
  3. // you can't use URI string like 'tcp://10.0.0.1:6379'
  4. // please refer to PRedis library documentation
  5. $redis_parameters = [
  6. 'scheme' => 'tcp',
  7. 'host' => '127.0.0.1',
  8. 'port' => 6379,
  9. 'options' => [
  10. 'profile' => '3.0',
  11. ],
  12. ];
  13. $client = new Client('redis', $redis_parameters);
  14. // ..

Refer to official page for more details on PRedis connection.

Parameters

When use create method to a generate a list, you can provide to it a parameters array. The allowed keys are:

  • uuid - uuid of list
  • element-uuid - uuid for the list elements
  • headers - headers array for the list
  • chunk-size - the chunks size in which the array will be splitted (integer) **
  • ttl - time to live of the list (in seconds) **

** = NOT AVALIABLE WITH PDO DRIVER

uuid

You can assign an uuid to your list (instead, a uuid will be generated):

  1. use InMemoryList\Application\Client;
  2. $array = [
  3. ...
  4. ]
  5. $client = new Client();
  6. $client->create($array, [
  7. 'uuid' => 'simple-array'
  8. ]);
  9. // And now you can retrive the list:
  10. $simpleArray = $client->getRepository()->findListByUuid('simple-array');
  11. //..

headers

You can set a headers array to your list:

  1. use InMemoryList\Application\Client;
  2. $array = [
  3. ...
  4. ]
  5. $headers = [
  6. 'expires' => 'Sat, 26 Jul 1997 05:00:00 GMT',
  7. 'hash' => 'ec457d0a974c48d5685a7efa03d137dc8bbde7e3'
  8. ];
  9. $client = new Client();
  10. $collection = $client->create($array, [
  11. 'uuid' => 'simple-array',
  12. 'headers' => $headers
  13. ]);
  14. // get headers
  15. var_dump($client->getRepository()->getHeaders('simple-array'));
  16. // ...

element-uuid

You can assign an uuid to list elemens (instead, a uuid will be generated). Consider this array:

  1. $simpleArray = [
  2. [
  3. "userId" => 1,
  4. "id" => 1,
  5. "title" => "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  6. "body" => "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  7. ],
  8. ...
  9. ]

Maybe you would use id key as uuid in your list:

  1. use InMemoryList\Application\Client;
  2. $client = new Client();
  3. $collection = $client->create($simpleArray, [
  4. 'uuid' => 'simple-array',
  5. 'element-uuid' => 'id'
  6. ]);
  7. // now to retrieve a single element, you can simply do:
  8. $itemWithId1 = $collection[1];

chunk-size

You can specify the number of elements of each chunk in which the original array will be splitted. The default value is 1000.

  1. use InMemoryList\Application\Client;
  2. $client = new Client();
  3. $collection = $client->create($array, [
  4. 'uuid' => 'simple-array',
  5. 'element-uuid' => 'id',
  6. 'chunk-size' => 1500
  7. ]);
  8. // ..

PLEASE NOTE THAT chunk-size IS NOT AVALIABLE WITH PDO DRIVER

ttl

You can specify a ttl (in seconds) for your lists:

  1. use InMemoryList\Application\Client;
  2. $client = new Client();
  3. $collection = $client->create($array, [
  4. 'uuid' => 'simple-array',
  5. 'element-uuid' => 'id',
  6. 'ttl' => 3600
  7. ]);
  8. // ..

PLEASE NOTE THAT ttl IS NOT AVALIABLE WITH PDO DRIVER

Delete an element

To delete an element in you list do this:

  1. // ..
  2. $client->getRepository()->deleteElement(
  3. $listUuid,
  4. $elementUuid,
  5. );

Push an element

To push an element in you list, use pushElement function. You must provide the list uuid, the element uuid and element data (data must be consistent - see Validation). Look at this example:

  1. // ..
  2. $client->pushElement(
  3. 'fake-list-uuid',
  4. 5001,
  5. [
  6. 'id' => 5001,
  7. 'name' => 'Name 5001',
  8. 'email' => 'Email 5001',
  9. ]
  10. );

Update an element

To update an element in you list, use updateElement function. You must provide the list uuid, the element uuid and element data (data must be consistent - see Validation). Look at this example:

  1. // ..
  2. $client->getRepository()->updateElement(
  3. 'list-to-update',
  4. 4325,
  5. [
  6. 'id' => 4325,
  7. 'title' => 'New Title',
  8. // ..
  9. ]
  10. );

Ttl

You can update ttl of a persisted list with updateTtl method, and retrive the ttl with getTtl function:

  1. // ...
  2. $client->getRepository()->updateTtl(
  3. 'your-list-uuid',
  4. 3600 // ttl in seconds
  5. );
  6. // get Ttl of the list
  7. $client->getRepository()->getTtl('your-list-uuid'); // 3600

PLEASE NOTE THAT ttl IS NOT AVALIABLE WITH PDO DRIVER

Validation (Data consistency)

Please note that your data must be consistent:

  1. // simple string list
  2. $stringArray = [
  3. 'Lorem Ipsum',
  4. 'Ipse Dixit',
  5. 'Dolor facium',
  6. ];
  7. $collection = $client->create($stringArray, [
  8. 'uuid' => 'string-array',
  9. 'ttl' => 3600
  10. ]);
  11. // array list, you must provide elements with consistent structure
  12. $listArray[] = [
  13. 'id' => 1,
  14. 'title' => 'Lorem Ipsum',
  15. ];
  16. $listArray[] = [
  17. 'id' => 2,
  18. 'title' => 'Ipse Dixit',
  19. ];
  20. $listArray[] = [
  21. 'id' => 3,
  22. 'title' => 'Dolor facium',
  23. ];
  24. $collection = $client->create($listArray, [
  25. 'uuid' => 'simple-array',
  26. 'element-uuid' => 'id',
  27. 'ttl' => 3600
  28. ]);
  29. // entity list, the objects must have the same properties
  30. $entityArray[] = new User(1, 'Mauro');
  31. $entityArray[] = new User(2, 'Cristina');
  32. $entityArray[] = new User(3, 'Lilli');
  33. $collection = $client->create($entityArray, [
  34. 'uuid' => 'entity-array',
  35. 'element-uuid' => 'id',
  36. 'ttl' => 3600
  37. ]);

Instead, a ListElementNotConsistentException will be thrown. Example:

  1. // ListElementNotConsistentException will be thrown
  2. $listArray[] = [
  3. 'id' => 1,
  4. 'title' => 'Lorem Ipsum',
  5. ];
  6. $listArray[] = [
  7. 'id' => 2,
  8. 'non-consistent-key' => 'Ipse Dixit',
  9. ];
  10. $listArray[] = [
  11. 'id' => 3,
  12. 'title' => 'Dolor facium',
  13. ];
  14. $collection = $client->create($listArray, [
  15. 'uuid' => 'simple-array',
  16. 'element-uuid' => 'id',
  17. 'ttl' => 3600
  18. ]);

Sorting and Quering

You can perform queries on your list. This library uses Array Query, please refer to it for the official documentation.

  1. use ArrayQuery\QueryBuilder;
  2. // ..
  3. $list = $client->getRepository()->findListByUuid('simple-array');
  4. $qb = QueryBuilder::create($list);
  5. $qb
  6. ->addCriterion('id', '3', '>')
  7. ->sortedBy('id', 'DESC');
  8. // get results
  9. foreach ($qb->getResults() as $element){
  10. // ...
  11. }

Commands

If you have an application which uses Symfony Console, you have some commands avaliable:

  • iml:cache:flush to flush the cache
  • iml:cache:index [<from>] [<to>] to get full index of items stored in cache
  • iml:cache:schema:create Create database schema (only for PDO driver)
  • iml:cache:schema:destroy Destroys database schema (only for PDO driver)
  • iml:cache:statistics to get cache statistics

You can register the commands in your app, consider this example:

  1. #!/usr/bin/env php
  2. <?php
  3. // Example of a Silex Application 'bin/console' file
  4. // we use \Knp\Provider\ConsoleServiceProvider as ConsoleServiceProvider, use what you want
  5. set_time_limit(0);
  6. require __DIR__.'/../vendor/autoload.php';
  7. $app = new Silex\Application();
  8. $app->register(new \Knp\Provider\ConsoleServiceProvider(), array(
  9. 'console.name' => '...',
  10. 'console.version' => '...',
  11. 'console.project_directory' => __DIR__.'/..'
  12. ));
  13. $console = $app['console'];
  14. // add commands here
  15. ...
  16. $console->add(new \InMemoryList\Command\CreateSchemaCommand(...));
  17. $console->add(new \InMemoryList\Command\DestroySchemaCommand(...));
  18. $console->add(new \InMemoryList\Command\FlushCommand(...));
  19. $console->add(new \InMemoryList\Command\IndexCommand(...));
  20. $console->add(new \InMemoryList\Command\StatisticsCommand(...));
  21. $console->run();

You have to provide to commands your driver and connection parameters array. Example:

  1. $console->add(new \InMemoryList\Command\FlushCommand('redis', [
  2. 'host' => '127.0.0.1',
  3. 'port' => 6379,
  4. ]));

Testing

In order to run all the tests, you have two options:

1. Install all the drivers on your machine

The first way it to install all the drivers on your machine:

Once installed all the drivers, create a file called config/parameters.yml and paste in the content of config/parameters.dist.yml. Finally, change your configuration if needed:

  1. redis_parameters:
  2. scheme: 'tcp'
  3. host: '127.0.0.1'
  4. port: '6379'
  5. options:
  6. profile: '3.2'
  7. memcached_parameters:
  8. host: 'localhost'
  9. port: '11211'
  10. pdo_parameters:
  11. driver: 'mysql'
  12. host: '127.0.0.1'
  13. username: 'root'
  14. password: ~
  15. database: 'in-memory-list'
  16. port: '3306'
  17. options: ~

2. Run the project with Docker

You can run the project with Docker.

STEP1: Make the build

  1. docker-compose build

STEP2: Raise the app

  1. docker-compose up -d

STEP3: Enter in the docker container

  1. docker exec -it inmemorylist_app_1 bash

STEP4: Create the schema and run the tests in the container

  1. php bin/console iml:cache:schema:create
  2. vendor/bin/phpunit

Built With

  • PRedis - Flexible and feature-complete Redis client for PHP and HHVM
  • ramsey/uuid - A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).
  • Symfony Console - Symfony Console Component

Support

If you found an issue or had an idea please refer to this section.

Authors

License

This project is licensed under the MIT License - see the LICENSE.md file for details