https://github.com/morebec/orkestra-postgresql-document-store
[READ ONLY] Orkestra Component allowing to easily use PostgreSQL as a Document Store
https://github.com/morebec/orkestra-postgresql-document-store
document document-store json jsonb orkestra php postgresql
Last synced: about 1 month ago
JSON representation
[READ ONLY] Orkestra Component allowing to easily use PostgreSQL as a Document Store
- Host: GitHub
- URL: https://github.com/morebec/orkestra-postgresql-document-store
- Owner: Morebec
- License: apache-2.0
- Created: 2021-04-21T01:01:31.000Z (about 5 years ago)
- Default Branch: 2.x
- Last Pushed: 2023-03-31T18:46:54.000Z (about 3 years ago)
- Last Synced: 2025-01-23T05:14:15.153Z (over 1 year ago)
- Topics: document, document-store, json, jsonb, orkestra, php, postgresql
- Language: PHP
- Homepage:
- Size: 35.2 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# PostgreSQLDocumentStore
Implementation of a Document Store using PostgreSQL's JSONB features.
It is based on `doctrine/dbal` for accessing the database internally.
## Installation
```shell
composer require morebec/orkestra-postgresql-document-store
```
## Usage
The Document Store uses `doctrine/dbal` for accessing the database.
Therefore, it requires a DBAL Connection as a constructor dependency.
It also relies on a `ClockInterface` from the `morebec/orkestra-date-time`component in order to access
the current date time.
```php
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;
use Morebec\Orkestra\DateTime\SystemClock;
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore;
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStoreConfiguration;
$connection = DriverManager::getConnection([
'url' => '...'
], new Configuration());
$config = new PostgreSqlDocumentStoreConfiguration();
$clock = new SystemClock();
$store = new PostgreSqlDocumentStore($connection, $config, $clock);
```
The second parameter corresponds to the configuration of the DocumentStore. This configuration class
can be used to alter the behaviour of the document store.
### Inserting Documents
To insert a document in a collection:
```php
/** @var Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore $store */
$store->insertDocument('users', 'usr123456789', [
'id' => 'usr123456789',
'username' => 'jane.doe',
'fullname' => 'Jane Doe',
'emailAddress' => 'jane.doe@email.com'
]);
```
If the collection does not exist, it will be created automatically.
### Finding Documents
Finding elements can be performed using the `findOneDocument` and `findManyDocuments` methods of the
document store. These methods accept either a string representing a PostgreSQL json query or a `Filter`
which is a simple API for a query builder with the document store:
```php
use Morebec\Orkestra\PostgreSqlDocumentStore\Filter\Filter;
use Morebec\Orkestra\PostgreSqlDocumentStore\Filter\FilterOperator;
$store->insertDocument('users', 'usr123456789', [
'id' => 'usr123456789',
'username' => 'jane.doe',
'fullname' => 'Jane Doe',
'emailAddress' => 'jane.doe@email.com',
'preferredLanguage' => 'ENGLISH'
]);
// Finds a document by its ID.
$store->findOneDocument('users', Filter::findById('usr123456789'));
// Finds a document by a single field:
$store->findOneDocument('users', Filter::findByField('username', FilterOperator::EQUAL(), 'jane.doe'));
// Finds a document by a multiple criteria
$store->findOneDocument('users',
Filter::where('username', FilterOperator::EQUAL(), 'jane.doe')
->or('preferredLanguage', FilterOperator::IS_NOT(), null)
);
// You can also use strings to have greater control over the query:
$store->findOneDocument('users', 'data->>fullname = \'Jane Doe\'');
```
> If you are using the `Filter` query builder, the values are automatically escaped using prepared statements placeholders.
> However if you are using a string for a query, the values will not be escaped, and you must make sure that you are not introducing potential loopholes
> for SQL Injections.
> Internally a column `data` with type `JSONB` is added to every created collection table.
> This is why if you are doing a string query, you must specify the `data` column.
> For even greater control, the document store exposes a `getConnection` method which returns the `DBAL` connection
> which you can use to make more complex queries using doctrine's Query Builder or raw connection.
### Updating Documents
To update a document, use the `updateDocument` method.
This method does not support partial documents, and therefore overwrites the document in the store
with the provided one:
```php
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore;
/** @var $store PostgreSqlDocumentStore **/
$store->updateDocument('users', 'usr123456789', [
'id' => 'usr123456789',
'username' => 'jane.doe',
'fullname' => 'Jane A. Doe',
'emailAddress' => 'new.jane.doe@email.com',
'preferredLanguage' => 'FRENCH'
]);
```
### Removing Documents
Removing a document can be done as follows:
```php
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore;
/** @var $store PostgreSqlDocumentStore **/
$store->removeDocument('users', 'usr123456789');
```
### Changing table names prefix.
In order to have better control over the collection tables it manages,
the document store adds a prefix to any table that it creates.
This prefix can be configured in the document store configuration:
```php
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStoreConfiguration;
$config = new PostgreSqlDocumentStoreConfiguration();
$config->collectionPrefix = 'you_prefix_';
```
### Transaction Management
If you need to use transactions for your operations, you can do this by accessing the DBAL connection:
```php
$connection = $store->getConnection();
$connection->transactional(static function() use ($store) {
$store->insertDocument('users', 'usr123456789', [
'id' => 'usr123456789',
'username' => 'jane.doe',
'fullname' => 'Jane Doe',
'emailAddress' => 'jane.doe@email.com',
'preferredLanguage' => 'ENGLISH'
]);
$store->insertDocument('users', 'usrABCDEFGHI', [
'id' => 'usrABCDEFGHI',
'username' => 'john.doe',
'fullname' => 'John Doe',
'emailAddress' => 'john.doe@email.com',
'preferredLanguage' => 'SPANISH'
]);
});
```
## Testing
To run the tests execute the following command:
```shell
vendor/bin/phpunit tests/
```
It is required to have an instance of postgresql running with a password-less role `postgres` and a database named `postgres`.
To easily get this setup and running a `docker-compose` configuration file is available at the root of this project.
To run it simply execute the following command:
```shell
docker-compose up -d
```