Skip to content

Commit

Permalink
Init Remap
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz committed Mar 16, 2024
0 parents commit 84e6a7c
Show file tree
Hide file tree
Showing 13 changed files with 545 additions and 0 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/phpunit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
on:
pull_request:
push:

name: "PHPUnit"

jobs:
phpunit:
name: PHP ${{ matrix.php }}-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
php:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
steps:
- name: Checkout
uses: actions/[email protected]

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer:v2
coverage: pcov

- name: Install dependencies
run: composer install

- name: Run tests with code coverage.
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always

- name: Upload coverage to Codecov.
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
34 changes: 34 additions & 0 deletions .github/workflows/psalm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
on:
pull_request:
push:

name: "Psalm"

jobs:
phpunit:
name: PHP ${{ matrix.php }}-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
php:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
steps:
- name: Checkout
uses: actions/[email protected]

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer:v2

- name: Install dependencies
run: composer install

- name: Run psalm.
run: vendor/bin/psalm --shepherd --stats --output-format=github --php-version=${{ matrix.php }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/vendor/
.idea
composer.lock
.phpunit.result.cache
.phpunit.cache
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# User ID tracing

The library allows you to track the unique user in the application.

[![Latest Stable Version](https://poser.pugx.org/xepozz/remap/v/stable.svg)](https://packagist.org/packages/xepozz/remap)
[![Total Downloads](https://poser.pugx.org/xepozz/remap/downloads.svg)](https://packagist.org/packages/xepozz/remap)
[![phpunit](https://github.com/xepozz/remap/workflows/PHPUnit/badge.svg)](https://github.com/xepozz/remap/actions)
[![codecov](https://codecov.io/gh/xepozz/remap/branch/master/graph/badge.svg?token=UREXAOUHTJ)](https://codecov.io/gh/xepozz/remap)
[![type-coverage](https://shepherd.dev/github/xepozz/remap/coverage.svg)](https://shepherd.dev/github/xepozz/remap)

## Installation

```bash
composer req xepozz/remap
```

## Description

The library allows you to map data from the database to objects.

The main goal is to simplify the process of querying long SQL queries and mapping the result to objects.

The mapper is designed to be used with querying of many objects at once.
It uses `\Generator` to fetch data from the database and map it to objects one by one, so it's memory efficient.

Under the hood, it uses:
- [yiisoft/db](https://github.com/yiisoft/db) to fetch data from the database
- [yiisoft/hydrator](https://github.com/yiisoft/hydrator) to map data to objects.

## Usage

Pass a class name and a query to the `Remap`.

```php
final class Todo
{
public int $id;
public string $title;
public int $status;
public int $created_at;
}
```

```php
$sql = 'SELECT id, title, status, created_at FROM todo WHERE id = :id LIMIT 1';
$params = ['id' => 1];

$remap->map(Todo::class, $sql, $params); // returns \Generator of Todo objects
```

### Tips

#### Define query-related methods in the class

```php
final class Todo
{
public int $id;
public string $title;
public int $status;
public int $created_at;

public static function selectOne(int $id): array
{
return [
'SELECT id, title, status, created_at FROM todo WHERE id = :id LIMIT 1',
['id' => $id],
];
}

public static function selectAll(): string
{
return 'SELECT id, title, status, created_at FROM todo';
}
}
```

And now it's easy to use:

```php
$remap->map(Todo::class, ...Todo::selectOne(1));
$remap->map(Todo::class, Todo::selectOne(1)); // or shorter
$remap->map(Todo::class, Todo::selectAll());
```

#### Unpack and store the result

```php
$remap->map(...)
```

Always returns a generator. If you want to get an array of objects, use `iterator_to_array`:

```php
$result = iterator_to_array(
$remap->map(Todo::class, Todo::selectOne(1))
);
```

Or shorter:

```php
$result = [...$remap->map(Todo::class, Todo::selectOne(1))];
```
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "xepozz/remap",
"type": "library",
"require": {
"yiisoft/hydrator": "dev-master",
"yiisoft/db": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^10.5",
"vimeo/psalm": "^5.23",
"yiisoft/db-sqlite": "^1.0"
},
"autoload": {
"psr-4": {
"Xepozz\\Remap\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Xepozz\\Remap\\Tests\\": "tests/"
}
},
"authors": [
{
"name": "Dmitrii Derepko",
"email": "[email protected]"
}
]
}
25 changes: 25 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
colors="true"
failOnRisky="false"
failOnWarning="false"
stopOnFailure="false"
executionOrder="random"
resolveDependencies="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
cacheDirectory=".phpunit.cache"
>
<php>
<ini name="error_reporting" value="-1"/>
</php>
<testsuites>
<testsuite name="Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>./src</directory>
</include>
</source>
</phpunit>
17 changes: 17 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<psalm
errorLevel="2"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
findUnusedCode="false"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>
40 changes: 40 additions & 0 deletions src/Remap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Xepozz\Remap;

use Throwable;
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Hydrator\HydratorInterface;

final class Remap
{
public function __construct(
private readonly HydratorInterface $hydrator,
private readonly ConnectionInterface $connection,
) {
}

/**
* @template T
* @param class-string<T> $class
* @return iterable<T>
* @throws Throwable
* @throws Exception
* @throws InvalidConfigException
*/
public function map(string $class, string|array $sql, array $params = []): iterable
{
if (is_array($sql)) {
$params = $sql[1] ?? $params;
$sql = $sql[0];
}
$iterator = $this->connection->createCommand($sql, $params)->query();
foreach ($iterator as $row) {
yield $this->hydrator->create($class, $row);
}
}
}
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
database.
Loading

0 comments on commit 84e6a7c

Please sign in to comment.