Skip to content

Commit

Permalink
Merge pull request #28 from martin-georgiev/develop
Browse files Browse the repository at this point in the history
Release v0.12
  • Loading branch information
martin-georgiev authored Aug 20, 2018
2 parents 26e8bc2 + 5a9a8a9 commit e8450fe
Show file tree
Hide file tree
Showing 111 changed files with 2,386 additions and 445 deletions.
13 changes: 11 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,16 @@ script:
else
composer check-security;
fi;
- composer run-tests-with-clover
- if [ "$(phpenv version-name)" != "$LATEST_PHP_VERSION" ]; then
echo "Tests with reporting in Clover format are skipped for older PHP versions";
composer run-tests;
else
composer run-tests-with-clover;
fi;

after_script:
- php bin/coveralls -v
- if [ "$(phpenv version-name)" != "$LATEST_PHP_VERSION" ]; then
echo "Coveralls report is skipped for older PHP versions";
else
bin/php-coveralls -v;
fi;
334 changes: 12 additions & 322 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "*",
"jakub-onderka/php-parallel-lint": "^1.0",
"php-coveralls/php-coveralls": "^2.1",
"phpstan/phpstan": "^0.10.2",
"phpstan/phpstan-phpunit": "^0.10",
"phpunit/phpunit": "^5.7|^6.0|^7.0",
"satooshi/php-coveralls": "^2.0",
"sensiolabs/security-checker": "^4.1"
},

Expand All @@ -49,7 +49,7 @@
"bin/php-cs-fixer fix --config='./.php_cs' --show-progress=none --no-interaction --diff -v"
],
"run-static-analysis": [
"bin/phpstan analyse --level=4 src/"
"bin/phpstan analyse --level=5 src/"
],
"run-static-analysis-including-tests": [
"@run-static-analysis",
Expand Down
63 changes: 63 additions & 0 deletions docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Available operators

| PostgreSQL operator | Register for DQL as | Implemented by
|---|---|---|
| @> | CONTAINS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SmallIntArray` |
| <@ | IS_CONTAINED_BY | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\IsContainedBy` |
| && | OVERLAPS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Overlaps` |
| -> | JSON_GET_FIELD | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetField` |
| ->> | JSON_GET_FIELD_AS_TEXT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsText` |
| #> | JSON_GET_OBJECT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObject` |
| #>> | JSON_GET_OBJECT_AS_TEXT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObjectAsText` |


# Available functions

| PostgreSQL functions | Register for DQL as | Implemented by
|---|---|---|
| all | ALL_OF | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All` |
| any | ANY_OF | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any` |
| array_append | ARRAY_APPEND | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend` |
| array_cat | ARRAY_CAT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCat` |
| array_dims | ARRAY_DIMENSIONS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayDimensions` |
| array_length | ARRAY_LENGTH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayLength` |
| array_ndims | ARRAY_NUMBER_OF_DIMENSIONS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayNumberOfDimensions` |
| array_prepend | ARRAY_PREPEND | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayPrepend` |
| array_remove | ARRAY_REMOVE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayRemove` |
| array_replace | ARRAY_REPLACE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayReplace` |
| array_to_json | ARRAY_TO_JSON | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayToJson` |
| array_to_string | ARRAY_TO_STRING | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayToString` |
| cardinality | ARRAY_CARDINALITY | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Cardinality` |
| greatest | GREATEST | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Greatest` |
| json_array_length | JSON_ARRAY_LENGTH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonArrayLength` |
| json_each | JSON_EACH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonEach` |
| json_each_text | JSON_EACH_TEXT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonEachText` |
| JSON_OBJECT_KEYS | JSON_OBJECT_KEYS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonObjectKeys` |
| json_strip_nulls | JSON_STRIP_NULLS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonStripNulls` |
| jsonb_array_elements | JSONB_ARRAY_ELEMENTS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElements` |
| jsonb_array_elements_text | JSONB_ARRAY_ELEMENTS_TEXT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElementsText` |
| jsonb_array_length | JSONB_ARRAY_LENGTH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayLength` |
| jsonb_each | JSONB_EACH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEach` |
| jsonb_each_text | JSONB_EACH_TEXT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEachText` |
| jsonb_exists | JSONB_EXISTS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbExists` |
| jsonb_insert | JSONB_INSERT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbInsert` |
| jsonb_object_keys | JSONB_OBJECT_KEYS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectKeys` |
| jsonb_set | JSONB_SET | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbSet` |
| jsonb_strip_nulls | JSONB_STRIP_NULLS | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbStripNulls` |
| least | LEAST | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Least` |
| row_to_json | ROW_TO_JSON | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RowToJson` |
| string_to_array | STRING_TO_ARRAY | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StringToArray` |
| to_json | TO_JSON | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToJson` |
| to_jsonb | TO_JSONB | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToJsonb` |
| to_tsquery | TO_TSQUERY | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsquery` |
| to_tsvector | TO_TSVECTOR | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsvector` |
| tsmatch | TSMATCH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsmatch` |
| unnest | UNNEST | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Unnest` |


# Bonus functions

| PostgreSQL functions | Register for DQL as | Implemented by
|---|---|---|
| value = ANY(list of values) | IN_ARRAY | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\InArray` |
| CAST(json ->> node as BIGINT) | JSON_GET_FIELD_AS_INTEGER | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsInteger` |
10 changes: 10 additions & 0 deletions docs/AVAILABLE-TYPES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Available types

| PostgreSQL type | Implemented by |
|---|---|
| _int2 | `MartinGeorgiev\Doctrine\DBAL\Types\SmallIntArray` |
| _int4 | `MartinGeorgiev\Doctrine\DBAL\Types\IntegerArray` |
| _int8 | `MartinGeorgiev\Doctrine\DBAL\Types\BigIntArray` |
| _text | `MartinGeorgiev\Doctrine\DBAL\Types\TextArray` |
| _jsonb | `MartinGeorgiev\Doctrine\DBAL\Types\JsonbArray` |
| jsonb | `MartinGeorgiev\Doctrine\DBAL\Types\Jsonb` |
61 changes: 61 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Contributing

**Before opening your first PR**

For the sake of clear Git history and speedy review of your PR please check that the suggested changes are in line with the project's standards. Code style, static analysis and file validation scripts are already provided and can easily be checked with running from project's root:

`composer check-code-style` which will check for consistent code style

`composer fix-code-style` which will automatically apply fixes to the code style

`composer run-static-analysis-including-tests` which will run static analysis for the currently configured level

`composer run-tests` which will run the full test suite

`composer validate-files` which will validate that all PHP files can execute


----
**How to add more array-like data types?**

1. Extend `MartinGeorgiev\Doctrine\DBAL\Types\AbstractTypeArray`.

2. You must give the new data-type a unique within your application name. For this purpose, you can use the `TYPE_NAME` constant.
3. Depending on the new data-type nature you may have to overwrite some of the following methods:

`transformPostgresArrayToPHPArray()`

`transformArrayItemForPHP()`

`isValidArrayItemForDatabase()`


----
**How to add more functions?**

Most new functions will likely have a signature very similar to those already implemented in the project. This means new functions probably require only extending the base class and decorating it with some behaviour. Here are the two main steps to follow:
1. Extend `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AbstractFunction`.
2. Use calls to `setFunctionPrototype()` and `addNodeMapping()` to implement `customiseFunction()` for your new function class.

Example:

```php
<?php

declare(strict_types=1);

namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;

class ArrayAppend extends AbstractFunction
{
protected function customiseFunction(): void
{
$this->setFunctionPrototype('array_append(%s, %s)');
$this->addNodeMapping('StringPrimary'); # corresponds to param №1 in the prototype set in setFunctionPrototype
$this->addNodeMapping('Literal'); # corresponds to param №2 in the prototype set in setFunctionPrototype
# Add as more node mappings if needed.
}
}
```

*Beware that you cannot use **?** (e.g. the `??` operator) as part of any function prototype in Doctrine as this will fail the query parsing.*
39 changes: 39 additions & 0 deletions docs/INTEGRATING-WITH-DOCTRINE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## Integration with Symfony


*Register the DBAL types you plan to use*

Full set of the available types can be found [here](AVAILABLE-TYPES.md).

```php
<?php

use Doctrine\DBAL\Types\Type;

Type::addType('jsonb', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\Jsonb");
Type::addType('jsonb[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\JsonbArray");
Type::addType('smallint[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\SmallIntArray");
Type::addType('integer[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\IntegerArray");
Type::addType('bigint[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\BigIntArray");
Type::addType('text[]', "MartinGeorgiev\\Doctrine\\DBAL\\Types\\TextArray");
```


*Register the functions you'll use in your DQL queries*

Full set of the available types can be found [here](AVAILABLE-FUNCTIONS-AND-OPERATORS.md).

```php
<?php

use Doctrine\ORM\Configuration;

$configuration = new Configuration();

$configuration->addCustomStringFunction('TO_TSQUERY', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsquery::class);
$configuration->addCustomStringFunction('TO_TSVECTOR', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsvector::class);
$configuration->addCustomStringFunction('TSMATCH', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsmatch::class);

...
$em = EntityManager::create($dbParams, $configuration);
```
Loading

0 comments on commit e8450fe

Please sign in to comment.