Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
micoli committed Jul 14, 2023
0 parents commit 50adb89
Show file tree
Hide file tree
Showing 23 changed files with 995 additions and 0 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: "Tests"

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
test:
name: "${{ matrix.operating-system }} / PHP ${{ matrix.php-version }}"
runs-on: ${{ matrix.operating-system }}
continue-on-error: false

strategy:
matrix:
operating-system: ['ubuntu-latest']
php-version: ['8.1','8.2']

steps:
- name: "Checkout code"
uses: actions/checkout@v3

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

- name: "Set composer cache directory"
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
shell: bash

- name: "Cache composer"
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-${{ matrix.php-version }}-composer-

- name: "Install dependencies"
run: composer install --no-interaction --no-progress

- name: "PHPUnit version"
run: vendor/bin/phpunit --version

- name: "Run Coding standard"
run: vendor/bin/php-cs-fixer fix --verbose --dry-run

- name: "Run Psalm"
run: vendor/bin/psalm

- name: "Run tests"
run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml

- name: Upload coverage report to Coveralls
run: vendor/bin/coveralls.php --service=github --coverage_clover=build/logs/clover.xml -v
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.phpunit.cache
.phpunit.result.cache
.php-cs-fixer.cache
vendor
build
composer.lock

54 changes: 54 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@Symfony' => true,
'@PHP80Migration' => true,
'@PHP80Migration:risky' => true,
'declare_strict_types' => true,
'phpdoc_align' => false,
'phpdoc_summary' => false,
'phpdoc_to_comment' => false,
'concat_space' => ['spacing' => 'one'],
'header_comment' => ['header' => '', 'separate' => 'both'],
'multiline_whitespace_before_semicolons' => false,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_imports' => [
'sort_algorithm' => 'alpha',
'imports_order' => ['class', 'function', 'const'],
],
'phpdoc_order' => true,
'array_syntax' => ['syntax' => 'short'],
'echo_tag_syntax' => ['format' => 'long'],
'php_unit_method_casing' => false,
'php_unit_set_up_tear_down_visibility' => true,
'php_unit_internal_class' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'final_internal_class' => false,
'increment_style' => ['style' => 'pre'],
'return_type_declaration' => ['space_before' => 'none'],
'trailing_comma_in_multiline' => ['elements' => ['arrays', 'arguments', 'parameters']],
'global_namespace_import' => ['import_classes' => true, 'import_constants' => false, 'import_functions' => false],
'void_return' => true,
'yoda_style' => [
'equal' => false,
'identical' => false,
],
'class_definition' => [
'multi_line_extends_each_single_line' => true,
],
'single_line_throw' => false,
'compact_nullable_typehint' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->name('*.php'),
);
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.PHONY: test-unit
test-unit:
vendor/bin/phpunit

.PHONY: test-static
test-static:
vendor/bin/psalm

.PHONY: test-coding-standard
test-coding-standard:
vendor/bin/php-cs-fixer fix --verbose

.PHONY: update-doc
update-doc:
php ./update-doc.php README.md

.PHONY: tests-all
tests-all: test-coding-standard test-unit test-static update-doc
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Micoli\Elql


A flat database manager.

[![Build Status](https://github.com/micoli/elql/workflows/Tests/badge.svg)](https://github.com/micoli/elql/actions)
[![Coverage Status](https://coveralls.io/repos/github/micoli/Elql/badge.svg?branch=main)](https://coveralls.io/github/micoli/elql?branch=main)
[![Latest Stable Version](http://poser.pugx.org/micoli/elql/v)](https://packagist.org/packages/micoli/elql)
[![Total Downloads](http://poser.pugx.org/micoli/elql/downloads)](https://packagist.org/packages/micoli/elql)
[![Latest Unstable Version](http://poser.pugx.org/micoli/elql/v/unstable)](https://packagist.org/packages/micoli/elql) [![License](http://poser.pugx.org/micoli/elql/license)](https://packagist.org/packages/micoli/elql)
[![PHP Version Require](http://poser.pugx.org/micoli/elql/require/php)](https://packagist.org/packages/micoli/elql)

## Installation

This library is installable via [Composer](https://getcomposer.org/):

```bash
composer require micoli/elql
```

## Requirements

This library requires PHP 8.0 or later.

## Project status

While this library is still under development, it is still in early development status. It follows semver version tagging.

[//]: # (## Quick start)

40 changes: 40 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "micoli/elql",
"type": "library",
"license": "MIT",
"require": {
"php": ">=8.1",
"symfony/expression-language": "6.2.*",
"symfony/filesystem": "6.2.*",
"symfony/lock": "6.2.*",
"symfony/property-access": "6.2.*",
"symfony/property-info": "6.2.*",
"symfony/serializer": "6.2.*",
"symfony/yaml": "^6.3"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"vimeo/psalm": "^5.9",
"friendsofphp/php-cs-fixer": "^3.16",
"phpdocumentor/reflection-docblock": "^5.3",
"symfony/var-dumper": "^6.2",
"php-coveralls/php-coveralls": "^0.1.0",
"ramsey/uuid": "^4.7"
},
"autoload": {
"psr-4": {
"Micoli\\Elql\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Micoli\\Elql\\Tests\\": "tests/"
}
},
"authors": [
{
"name": "Olivier MICHAUD",
"email": "olivier@micoli.org"
}
]
}
7 changes: 7 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
tmpDir: ./build/cache/phpstan
level: max
treatPhpDocTypesAsCertain: false
paths:
- ./src
- ./tests
24 changes: 24 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd"
bootstrap="tests/bootstrap.php"
executionOrder="depends,defects"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage/>
<source>
<include>
<directory suffix=".php">src</directory>
</include>
</source>
</phpunit>
18 changes: 18 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
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" />
<directory name="tests" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>
92 changes: 92 additions & 0 deletions src/Elql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

declare(strict_types=1);

namespace Micoli\Elql;

use Micoli\Elql\Persister\PersisterInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

class Elql
{
public function __construct(
public readonly PersisterInterface $persister,
private readonly ExpressionLanguage $expressionLanguage = new ExpressionLanguage(),
) {
}

public function add(object ...$records): void
{
if (count($records) === 0) {
return;
}
foreach ($records as $record) {
$this->persister->addRecord($record);
}
}

/**
* @template T
*
* @param class-string<T> $model
*
* @return T[]
*/
public function find(string $model, string $where = null): array
{
return array_values(array_filter(
$this->persister->getRecords($model)->data,
fn (mixed $record) => $this->match($record, $where),
));
}

/**
* @param class-string $model
*/
public function delete(string $model, string $where = null): void
{
$this->persister->updateRecords($model, array_values(array_filter(
$this->persister->getRecords($model)->data,
fn (mixed $record) => !$this->match($record, $where),
)));
}

/**
* @param class-string $model
*/
public function count(string $model, string $where = null): int
{
return count($this->find($model, $where));
}

/**
* @template T
*
* @param class-string<T> $model
* @param callable(T):T $updater
*/
public function update(string $model, callable $updater, string $where = null): void
{
$this->persister->updateRecords($model, array_map(
/** @param T $record */
fn (mixed $record): mixed => $this->match($record, $where)
? $updater($record)
: $record,
$this->persister->getRecords($model)->data,
));
}

/**
* @param object $record
*
* @psalm-param T|object $record
*/
private function match(mixed $record, ?string $where): bool
{
if ($where === null) {
return true;
}

return (bool) $this->expressionLanguage->evaluate($where, ['record' => $record]);
}
}

0 comments on commit 50adb89

Please sign in to comment.