Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a104cf5
Add minor changes
byjg Mar 23, 2025
37bf984
Replace SqlObject by SqlStatement
byjg Mar 24, 2025
5ab7491
Fix tests
byjg Mar 24, 2025
d32643b
Change MapFromDbToInstanceHandler.php
byjg Mar 24, 2025
d701109
Documentation
byjg Mar 24, 2025
171a4b5
Add UpdateConstraintInterface.php
byjg Mar 24, 2025
725a8e3
Add UpdateConstraintInterface.php
byjg Mar 24, 2025
84a41c3
Fix Psalm issues.
byjg Mar 24, 2025
07d3ee7
Merge branch 'master' into 6.0
byjg Mar 24, 2025
a9a0cbb
Remove deprecations; Clean up code;
byjg Mar 24, 2025
7eff5bb
Add documentation
byjg Mar 24, 2025
088807e
Add documentation
byjg Mar 25, 2025
fb54a4c
Create ObserverEvent.php
byjg Mar 26, 2025
f425143
Change MapperFunctions.php
byjg Mar 27, 2025
f0b8ce6
Remove Deprecations
byjg Mar 27, 2025
22fa468
Fix Namespace
byjg Mar 27, 2025
e326eb9
update documentation
byjg Mar 27, 2025
8591d1a
Fix Repository::setBeforeUpdate and Repository::setBeforeInsert
byjg Mar 27, 2025
5d189c6
Add beforeUpdate and beforeInsert to the table attribute.
byjg Mar 27, 2025
1740758
Refactor data handling and documentation
byjg Mar 28, 2025
f7bfe57
Update Documentation.
byjg Mar 30, 2025
7a7d767
Merge branch 'master' into 6.0
byjg May 22, 2025
58b1e4f
Fix tests to use SqlStatement instead of SqlObject
byjg May 22, 2025
60ce725
Refactor query logic and add support for HAVING clause.
byjg May 31, 2025
45ccf74
Merge branch 'master' into 6.0
byjg Aug 15, 2025
e9c1b37
Replace `SqlObject` with `SqlStatement` in tests and update method us…
byjg Aug 15, 2025
db853d3
Minor changes
byjg Sep 5, 2025
40b6653
Refactor method signatures to use nullable types for improved type sa…
byjg Oct 28, 2025
420742f
Merge branch 'refs/heads/master' into 6.0
byjg Oct 28, 2025
5009d89
Refactor to replace `SqlObject` with `SqlStatement` across relevant c…
byjg Oct 28, 2025
4db0a9d
Add `#[Override]` attribute to methods and update imports for attribu…
byjg Oct 29, 2025
68a50e4
Refactor to replace `DbDriverInterface` with `DatabaseExecutor` acros…
byjg Oct 29, 2025
77b56cb
Add `buildAndExecuteIterator` to `QueryBuilderInterface` and implemen…
byjg Oct 29, 2025
8c1074a
Update "using-mapper-object" documentation for improved clarity and f…
byjg Oct 29, 2025
7e7d8ec
Add `#[Override]` attribute to methods in UUID attributes and related…
byjg Oct 29, 2025
91e74fe
Refactor tests and repositories to replace `DbDriverInterface` with `…
byjg Oct 29, 2025
b455d76
Refactor `RepositoryPkListTest` to clean up commented-out test method…
byjg Oct 29, 2025
94138c2
Refactor `SelectBinaryUuidMapper` and `UpdateBinaryUuidMapper` to `Fo…
byjg Nov 1, 2025
fc6373b
Add comprehensive tests for mapper functions including `StandardMappe…
byjg Nov 1, 2025
66d301c
Refactor to replace `DbFunctionsInterface` with `DatabaseExecutor` ac…
byjg Nov 2, 2025
b29dfdb
Refactor to replace `UniqueIdGeneratorInterface` with `MapperFunction…
byjg Nov 2, 2025
bdf7fab
Add `HexUuidMapperFunctionTest` to validate UUID handling as primary …
byjg Nov 5, 2025
94522d8
Introduce `ActiveRecordQuery` for a fluent and chainable query API. U…
byjg Nov 6, 2025
949e43c
Refactor `HexUuidMapperFunctionTest` and remove redundant `assertIsAr…
byjg Nov 6, 2025
0498fa0
Improve primary key handling in `Repository::getPrimaryKeys`. Validat…
byjg Nov 6, 2025
ee84353
Update `Repository` docblocks to include missing exceptions and adjus…
byjg Nov 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
strategy:
matrix:
php-version:
- "8.4"
- "8.3"
- "8.2"
- "8.1"
Expand All @@ -40,8 +41,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/phpunit
- run: ./vendor/bin/psalm
- run: ./vendor/bin/phpunit

Documentation:
if: github.ref == 'refs/heads/master'
Expand All @@ -50,5 +51,6 @@ jobs:
with:
folder: php
project: ${{ github.event.repository.name }}
secrets: inherit
secrets:
DOC_TOKEN: ${{ secrets.DOC_TOKEN }}

28 changes: 28 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
tasks:
- name: Run Composer
command: |
composer install

image: byjg/gitpod-image:latest

jetbrains:
phpstorm:
vmoptions: '-Xmx4g'
plugins:
- com.github.copilot
- com.intellij.kubernetes
- com.intellij.mermaid
- ru.adelf.idea.dotenv
- org.toml.lang

vscode:
extensions:
- ikappas.composer
- hbenl.test-adapter-converter
- hbenl.vscode-test-explorer
- felixfbecker.php-debug
- neilbrayfield.php-docblocker
- bmewburn.vscode-intelephense-client
- getpsalm.psalm-vscode-plugin
- SonarSource.sonarlint-vscode
- recca0120.vscode-phpunit
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug current Script in Console",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
},
{
"name": "PHPUnit Debug",
"type": "php",
"request": "launch",
"program": "${workspaceFolder}/vendor/bin/phpunit",
"cwd": "${workspaceFolder}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
}
]
}
81 changes: 55 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ Key Features:
* Can be used with any DTO, Entity, Model or whatever class with public properties or with getter and setter
* The repository support a variety of datasources: MySql, Sqlite, Postgres, MySQL, Oracle (see byjg/anydataset)
* A class Mapper is used for mapping the Entity and the repository
* Powerful mapper functions for automatic data transformation between models and database
* Small and simple to use

## Architecture

MicroORM implements **Martin Fowler's enterprise patterns**:

- **[Repository](https://martinfowler.com/eaaCatalog/repository.html)**: Mediates between domain and data mapping layers
- **[Data Mapper](https://martinfowler.com/eaaCatalog/dataMapper.html)**: Separates domain objects from database tables
- **[Active Record](https://martinfowler.com/eaaCatalog/activeRecord.html)**: Wraps database rows with domain logic (
alternative approach)

You can choose the pattern that best fits your application: use Repository + Data Mapper for complex domains, or Active
Record for simpler CRUD-focused applications.

These are the key components:

```text
Expand All @@ -35,26 +46,35 @@ These are the key components:
│ ┌───────────────┴─────┐
│ │ Query │
│ └───────────────┬─────┘
│ ┌───────────────┴─────┐
│ │ DbDriverInterface │───────────────┐
│ └───────────────┬─────┘
│ │
└──────────────────────────┘ .─────────.
│ │
│`─────────'│
│ │
│ DB │
│ │
│ │
`─────────'
│ ┌───────────────┴─────┐ ┌──────────────────────┐
│ │ DatabaseExecutor │────────│ DbDriverInterface │
│ └───────────────┬─────┘ └────────────┬─────────┘
│ │
└──────────────────────────┘ .─────────.
│ │
│`─────────'│
│ │
│ DB │
│ │
│ │
`─────────'
```

* Model is a get/set class to retrieve or save the data into the database
* Mapper will create the definitions to map the Model into the Database.
* Query will use the Mapper to prepare the query to the database based on DbDriverInterface
* DbDriverIntarce is the implementation to the Database connection.
* Repository put all this together
* **Model** can be any class with public properties or with getter and setter. It is used to retrieve or save the data
into the database
* **Mapper** defines the relationship between the Model properties and the database fields
* **FieldMapping** defines individual field mappings within the Mapper (field names, transformations, relationships via
`parentTable`)
* **Query** defines what to retrieve from/update in the database. It uses the Mapper to prepare the query to the
database converting the Model properties to database fields
* **DatabaseExecutor** (external package) wraps the DbDriver and provides transaction management, query execution, and
access to database helpers
* **DbDriverInterface** (external package) is the actual database driver implementation that connects to the database
* **Repository** orchestrates all MicroORM components and uses DatabaseExecutor to interact with the database

For a detailed explanation of the architecture and when to use each layer,
see [Architecture Layers: Infrastructure vs Domain](docs/architecture-layers.md).


## Getting Started
Expand Down Expand Up @@ -89,20 +109,21 @@ Let's look at an example:
class MyModel
{
#[FieldAttribute(primaryKey: true)]
public ?int $id;
public ?int $id = null;

#[FieldAttribute()]
public ?string $name;
public ?string $name = null;

#[FieldAttribute(fieldName: 'company_id')
public ?int $companyId;
public ?int $companyId = null;
}
```

In this example, we have a class `MyModel` with three properties: `id`, `name`, and `companyId`.

The `id` property is marked as a primary key. The `name` property is a simple field.
The `companyId` property is a field with a different name in the database `company_id`.
* The `id` property is marked as a primary key.
* The `name` property is a simple field.
* The `companyId` property is a field with a different name in the database `company_id`.

The `TableAttribute` is used to define the table name in the database.

Expand All @@ -111,8 +132,7 @@ The `TableAttribute` is used to define the table name in the database.
After defining the Model, you can connect the Model with the repository.

```php
$dbDriver = \ByJG\AnyDataset\Db\Factory::getDbRelationalInstance('mysql://user:password@server/schema');

$dbDriver = \ByJG\AnyDataset\Db\Factory::getDbInstance('mysql://user:password@server/schema');
$repository = new \ByJG\MicroOrm\Repository($dbDriver, MyModel::class);
```

Expand Down Expand Up @@ -153,6 +173,11 @@ $result = $repository->getByQuery($query);
* [Querying the Database](docs/querying-the-database.md)
* [Updating the database](docs/updating-the-database.md)
* [Using the Mapper Object](docs/using-mapper-object.md)
* [The Model Attributes](docs/model-attribute.md)
* [The Repository Class](docs/repository.md)
* [Common Traits for Timestamp Fields](docs/common-traits.md)
* [Architecture Layers: Infrastructure vs Domain](docs/architecture-layers.md)
* [Comparison with Other ORMs (Eloquent, Doctrine)](docs/comparison-with-other-orms.md)

## Advanced Topics

Expand All @@ -163,10 +188,14 @@ $result = $repository->getByQuery($query);
* [Caching the Results](docs/cache.md)
* [Observing the Database](docs/observers.md)
* [Controlling the data queried/updated](docs/controlling-the-data.md)
* [Mapper Functions](docs/mapper-functions.md)
* [Using FieldAlias](docs/using-fieldalias.md)
* [Tables without auto increments fields](docs/tables-without-auto-increment-fields.md)
* [Using With Recursive SQL Command](docs/using-with-recursive-sql-command.md)
* [QueryRaw (raw SQL)](docs/query-raw.md)
* [Update Constraints](docs/update-constraints.md)
* [Building SQL Queries](docs/query-build.md)
* [UUID Support](docs/uuid-support.md)

## Install

Expand Down Expand Up @@ -199,4 +228,4 @@ flowchart TD
```

----
[Open source ByJG](http://opensource.byjg.com)
[Open source ByJG](http://opensource.byjg.com)
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"php": ">=8.1 <8.4",
"php": ">=8.1 <8.5",
"ext-json": "*",
"ext-pdo": "*",
"byjg/anydataset-db": "^5.0"
"byjg/anydataset-db": "^6.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6",
"byjg/cache-engine": "^5.0",
"vimeo/psalm": "^5.9"
"phpunit/phpunit": "^10.5|^11.5",
"byjg/cache-engine": "^6.0",
"vimeo/psalm": "^5.9|^6.2"
},
"suggest": {
"ext-curl": "*",
Expand Down
Loading