https://github.com/peroks/model-store
Model Store: Permanent data store for models.
https://github.com/peroks/model-store
database json mysql mysqli pdo pdo-mysql persistent-storage
Last synced: 6 months ago
JSON representation
Model Store: Permanent data store for models.
- Host: GitHub
- URL: https://github.com/peroks/model-store
- Owner: peroks
- License: mit
- Created: 2023-02-18T11:00:12.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-06-08T11:46:01.000Z (about 1 year ago)
- Last Synced: 2025-06-08T12:31:02.449Z (about 1 year ago)
- Topics: database, json, mysql, mysqli, pdo, pdo-mysql, persistent-storage
- Language: PHP
- Homepage:
- Size: 141 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Model Store: Permanent data store for models.
## Reason why
The purpose of this package is to store models **permanently**. Currently,
**JSON files** and **MySql databases** (mysqli and pdo-mysql) are supported.
The Model Store is an abstraction layer on top of the permanent store.
It automatically creates **JSON files** or **database schemas** for you based
on your models.
The Model Store provides a simple [interface](src/StoreInterface.php) for
reading models from and writing models to the permanents store.
## How to use
### The Store interface
You can of course access a database directly, but the
recommended way it to create a `Store instance` and use the
[StoreInterface](src/StoreInterface.php).
### Connecting to a model store
In order to connect to a model store, you must create a new **model store instance**.
Currently, these model stores are supported:
- `FileStore`: JSON file store
- `MysqlStore`: Native MySql store (mysqli)
- `MysqlJsonStore`: Native MySql (mysqli) store with JSON support
- `PdoStore`: PDO MySql store (pdo-mysqli)
- `PdoJsonStore`: PDO MySql (pdo-mysqli) store with JSON support
The JsonStore classes stores models in MySQL `json` columns with
additional columns for indices and constraints.
You can also create your own implementation of the
[StoreInterface](src/StoreInterface.php).
#### File store
Storing your models in a JSON file is only recommended for **very small** data
stores, no more than a few MBs. It's intended for use in **development**
and **rapid prototyping**, but not in **production**. For each PHP request
the complete JSON file is loaded into memory, and it will consume more
and more **ram** and **cpu** as the file grows.
To connect to a JSON file store, just provide the full path and file name
to the JSON file which contains your models. If the file does not
exist, it will be created.
```php
use Peroks\Model\Store\FileStore;
$store = new FileStore( '//.json' );
```
#### PDO MySql store
To connect to a PDO MySql store, just provide the
[connection info](https://www.php.net/manual/en/mysqli.quickstart.connections.php)
for the MySQL database.
All connection properties below are required, except for `port` and `socket`,
which are mutually exclusive. If the host is `localhost`, a `socket` is expected.
The connection info can be an `array` or an `object`.
```php
use Peroks\Model\Store\PdoStore;
$store = new PdoStore( [
'host' => 'localhost||',
'name' => '',
'user' => '',
'pass' => '',
'port' => '',
'socket' => '',
] );
```
Alternatively, you can use the `PdoJsonStore` class, which stores the
models in MySql `json` columns. Additional columns are only created for
primary, index and constraint properties.
#### Native MySql (mysqli) store
You can also connect to a MySql database using the native `mysqli` driver
if you prefer. Just replace the store class `PdoStore` with `MysqlStore`.
```php
use Peroks\Model\Store\MysqlStore;
$store = new MysqlStore( [
'host' => 'localhost||',
'name' => '',
'user' => '',
'pass' => '',
'port' => '',
'socket' => '',
] );
```
Alternatively, you can use the `MysqlJsonStore` class, which stores the
models in MySql `json` columns. Additional columns are only created for
primary, index and constraint properties.
### Creating and Updating database schemas
Before you can start using a database store, you need to build the
**database schema** based on your models. Fortunately, you don't need to do this
manually. To create (and update) your database schema, call the `build()`
method with an array of the model **class names** that you want to store.
This will also create a new database if it doesn't already exist.
You should only call the `build()` method when you create a new model store or
when your models have changed. Do **not** call `build()` every time you connect to
the store. You can use `info( 'ready' )` to check if the db is ready for use or not.
```php
use Peroks\Model\Store\MysqlStore;
$store = new MysqlStore( $connection );
if ( ! $store->info( 'ready' ) ) {
$store->build( [
MyModelOne::class,
MyModelTwo::class,
MyModelThree::class,
] );
}
```
If a model contains [sub-models](https://github.com/peroks/model#nested-models),
database tables are automatically created for the sub-models.
You do not need to include sub-models in the `build()` method.
So, if you have a hierarchy of models, you only need to provide
your **top-level** models.
## Caching
You can cache query results in memory with the special `Cache` store.
The constructor takes another store instance as the only argument.
Calls to `has()`, `get()`, `list()` and `filter()` return cached results when available.
The cache is cleared every time `set()`, `delete()` or `build()` are called.
```php
use Peroks\Model\Store\Cache;
use Peroks\Model\Store\PdoJsonStore;
$store = new Cache( new PdoJsonStore( $connection ) );
$model = $store->get( SomeClass::class, 'someId' );
$model = $store->get( SomeClass::class, 'someId' ); // Cached result.
```
## Examples
The below examples assume that a model store instance has already been created,
i.e. like this
```php
use Peroks\Model\Store\MysqlStore;
$store = new MysqlStore( [
'host' => 'localhost||',
'name' => '',
'user' => '',
'pass' => '',
'port' => '',
'socket' => '',
] );
```
All methods accept the **model class name** as the first argument.
The only exception is `set`, since the class name can be derived from the
model instance.
#### Check if a model exists in the store
```php
$exists = $store->has( MyModelOne::class, 123 );
$exists = $store->has( MyModelOne::class, 'abc' );
```
#### Get a single model by id
```php
$stored_model = $store->get( MyModelOne::class, 123 );
$stored_model = $store->get( MyModelOne::class, 'abc' );
```
#### Get an array of models by their ids
```php
$some_models = $store->list( MyModelOne::class, [123, 'abc', 'xyz'] );
$all_models = $store->list( MyModelOne::class );
```
If no ids are provided, all models of the given class are returned.
#### Get models by their property values
The `filter` method returns all models of the given **class name** matching
pairs of property ids and their values, i.e.
```php
$some_artists = $store->filter( Artist::class, [
'first_name' => 'Tom',
'last_name' => 'Waits',
] );
$all_artists = $store->filter( Artist::class );
```
If no property filter is provided, all models of the given class are returned
(same as `list()`).
#### Add or update a model in the store
```php
$model = new Artist( [ 'first_name' => 'Tom', 'last_name' => 'Waits' ] );
$store->set( $model );
```
#### Delete a model from the store
```php
$store->delete( MyModelOne::class, 123 );
$store->delete( MyModelOne::class, 'abc' );
```
## Installing
You need **composer** to download and install this
[package](https://packagist.org/packages/peroks/model-store).
Just run `composer require peroks/model-store` in your project.