diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74d6b5f..833c6f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Continuous Integration +name: CI tests on: [workflow_dispatch, push, pull_request] diff --git a/README.md b/README.md index d33a8d2..47aa189 100644 --- a/README.md +++ b/README.md @@ -92,16 +92,6 @@ The generated AQL for this query is: FOR i IN 1..100 FILTER i < 50 LIMIT 10 SORT i DESC RETURN i ``` -## API -See the following pages on details for the API - -- API - - [Query clauses](docs/api/query-clauses.md): how to search, select, sort and limit data - - [Statement clauses](docs/api/statement-clauses.md): data manipulation & variable declaration - - [Graph clauses](docs/api/graph-clauses.md): graph traversals - - [Functions](docs/api/functions.md): a list of all supported AQL functions - - [Subqueries](docs/core-concepts/subqueries.md): how to create subqueries, joins etc. - ### (Always) bind user input No matter what, never trust user input and always bind it. ``` @@ -113,6 +103,18 @@ Binds are registered in order and given an id. If you want to specify the bind n $qb->bind('your data', 'your-bind-id') ``` +## Documentation +- API + - [Query clauses](docs/api/query-clauses.md): how to search, select, sort and limit data + - [Statement clauses](docs/api/statement-clauses.md): data manipulation & variable declaration + - [Graph clauses](docs/api/graph-clauses.md): graph traversals + - [Functions](docs/api/functions.md): a list of all supported AQL functions + - [Subqueries](docs/core-concepts/subqueries.md): how to create subqueries, joins etc. +- Core Concepts + - [Terminology](docs/core-concepts/terminology.md): definitions of terms used in the documentation + - [Data binding](docs/core-concepts/data-binding.md): How to inject external data and collections + - [Subqueries](docs/core-concepts/subqueries.md): Subquery creation + ## References & resources ### ArangoDB diff --git a/docs/api/functions.md b/docs/api/functions.md index d9d9dc3..43457ed 100644 --- a/docs/api/functions.md +++ b/docs/api/functions.md @@ -5,7 +5,7 @@ This page gives an overview of the AQL functions supported by this query builder If you are missing a function please create an issue requesting it. In the meantime you can use the raw clause. ## Using functions -Functions always return expressions to be used in clauses and other functions. +Functions always return expressions to be used in clauses or other expressions. Example: ``` @@ -17,44 +17,46 @@ $qb->for('i', '1..100') ->return('i'); ``` - ## Array functions - | Description | AQL Function | | :-------------------- | :-------------------------------------------------------------------------------------------- | -| count($value) | [COUNT()](https://www.arangodb.com/docs/stable/aql/functions-array.html#count) | -| countDistinct($value) | [COUNT_DISTINCT()](https://www.arangodb.com/docs/stable/aql/functions-array.html#count) | -| first($value) | [FIRST()](https://www.arangodb.com/docs/stable/aql/functions-array.html#first) | -| last($value) | [LAST()](https://www.arangodb.com/docs/stable/aql/functions-array.html#last) | -| length($value) | [LENGTH()](https://www.arangodb.com/docs/stable/aql/functions-array.html#length) | +| count($value) | [COUNT(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-array.html#count) | +| countDistinct($value) | [COUNT_DISTINCT(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-array.html#count) | +| first($value) | [FIRST(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-array.html#first) | +| last($value) | [LAST(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-array.html#last) | +| length($value) | [LENGTH(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-array.html#length) | ## Date functions - | Description | AQL Function | | :-------------------- | :-------------------------------------------------------------------------------------------- | | dateNow() | [DATE_NOW()](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_now) | | dateIso8601(numeric|string|DateTime $date) | [DATE_ISO8601(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_iso8601) | | dateTimestamp(numeric|string|DateTime $date) | [DATE_TIMESTAMP(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_timestamp) | -| | []() | -| | []() | -| | []() | -| | []() | +| dateYear($date) | [DATE_YEAR(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_year) | +| dateMonth($date) | [DATE_MONTH(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_month) | +| dateDay($date) | [DATE_DAY(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_day) | +| dateHour($date) | [DATE_HOUR(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_hour) | +| dateMinute($date) | [DATE_MINUTE(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_minute) | +| dateSecond($date) | [DATE_SECOND(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_second) | +| dateMillisecond($date) | [DATE_MILLISECOND(date)](https://www.arangodb.com/docs/stable/aql/functions-date.html#date_millisecond) | ## GEO functions - | Description | AQL Function | | :-------------------- | :-------------------------------------------------------------------------------------------- | | distance($latitude1, $longitude1, $latitude2, $longitude2) | [DISTANCE(latitude1, longitude1, latitude2, longitude2)](https://www.arangodb.com/docs/stable/aql/functions-geo.html#distance) | ## Miscellaneous functions - | Description | AQL Function | | :-------------------- | :-------------------------------------------------------------------------------------------- | | document($collection, $id = null) | [DOCUMENT(collection, id)](https://www.arangodb.com/docs/stable/aql/functions-miscellaneous.html#document) | -| average($value) | []() | -| avg($value) | []() | -| max($value) | []() | -| min($value) | []() | -| rand() | []() | -| sum($value) | []() | + +## Numeric functions +| Description | AQL Function | +| :-------------------- | :-------------------------------------------------------------------------------------------- | +| average($value) | [AVERAGE(numArray](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#average) | +| avg($value) | [AVG(numArray](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#average) | +| max($value) | [MAX(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#max) | +| min($value) | [MIN(anyArray)](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#min) | +| rand() | [RAND()](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#rand) | +| sum($value) | [SUM(numArray)](https://www.arangodb.com/docs/stable/aql/functions-numeric.html#sum) | diff --git a/docs/core-concepts/data-binding.md b/docs/core-concepts/data-binding.md index 655712b..1a53aed 100644 --- a/docs/core-concepts/data-binding.md +++ b/docs/core-concepts/data-binding.md @@ -1,3 +1,36 @@ # Data binding +``` +bind($data, $to = null) +``` +Inject data through the bind command. + +**Example 1:** +``` +$qb->filter('u.age', '==', $qb->bind(18)); +``` +Resulting AQL: `FILTER u.age == @{a_generated_id}` + +**Example 2 - with bind id:** +``` +$qb->filter('u.age', '==', $qb->bind(18, 'my_bind')); +``` +Resulting AQL: `FILTER u.age == @my_bind` ## Bind collection names +``` +bindCollection($data, $to = null) +``` +Inject collection names through the bindCollection command. + +**Example 1:** +``` +$qb->for('user', $qb->bindCollection('users')); +``` +Resulting AQL: `FOR user IN @@{a_generated_id}` + +**Example 2 - with bind id:** +``` +$qb->for('user', $qb->bindCollection('users', 'collectionBind')); +``` +Resulting AQL: `FOR user IN @@collectionBind` + diff --git a/docs/core-concepts/subqueries.md b/docs/core-concepts/subqueries.md index 429034f..5d4bc7b 100644 --- a/docs/core-concepts/subqueries.md +++ b/docs/core-concepts/subqueries.md @@ -1,5 +1,5 @@ # Subqueries -You can easily create subqueries by passing one query bulder object to another as an expression. +You can easily create subqueries by passing one query builder object to another as an expression. Example: ``` @@ -9,7 +9,7 @@ Example: ->return('u._key') ->get(); - $result = (new QueryBuilder()) + $mainQuery = (new QueryBuilder()) ->for('u', 'users') ->filter('u._key', '==', $subQuery) ->return('u') diff --git a/src/Traits/NormalizesExpressions.php b/src/Traits/NormalizesExpressions.php index cf7f2ed..1704a95 100644 --- a/src/Traits/NormalizesExpressions.php +++ b/src/Traits/NormalizesExpressions.php @@ -189,11 +189,6 @@ protected function determineArgumentType($argument, $allowedExpressionTypes = nu } } - //Fallback to BindExpression if allowed - if (isset($allowedExpressionTypes['Bind'])) { - return 'Bind'; - } - throw new ExpressionTypeException( "This argument, '{$argument}', does not match one of these expression types: " diff --git a/tests/Unit/AQL/DateFunctionsTest.php b/tests/Unit/AQL/DateFunctionsTest.php index 4f67885..8873d36 100644 --- a/tests/Unit/AQL/DateFunctionsTest.php +++ b/tests/Unit/AQL/DateFunctionsTest.php @@ -7,6 +7,8 @@ /** * @covers \LaravelFreelancerNL\FluentAQL\AQL\HasDateFunctions + * @covers \LaravelFreelancerNL\FluentAQL\Traits\NormalizesDateFunctions + * @covers \LaravelFreelancerNL\FluentAQL\Traits\NormalizesFunctions */ class DateFunctionsTest extends TestCase {