Skip to content
Open
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ summary: Описание клиентского языка запросов.
* `GeometryPredicate` - класс для создания фильтра в запросе по геометрическим атрибутам.
* `createPredicate` - функция для создания предиката по заданным параметрам.
* `stringToPredicate` - функция для конвертации строки в предикат.
* `AttributeParam` - класс для описания атрибута в `SimplePredicate` и `DatePredicate`.
* `ConstParam`- класс для описания константы в `SimplePredicate` и `DatePredicate`.

Для импорта и использования классов языка запросов необходимо использовать следующий код:

Expand All @@ -56,7 +58,7 @@ import Builder from 'ember-flexberry-data/query/builder';
let builder = new Builder(store);
```

{% include note.html content="В версиях Flexberry Ember 2.x содержалось пространство имен Query, содержащее перечисленные выше классы. Поскольку в Ember 3.x пространства имен более не используются в связи с [использованием ES6-модулей](https://github.com/emberjs/rfcs/blob/master/text/0176-javascript-module-api.md), все классы, содержавшиеся в пространстве имен Query, во Flexberry Ember 3.x теперь необходимо импортировать напрямую из [папки query](https://github.com/Flexberry/ember-flexberry-data/tree/feature-ember-update/addon/query) аддона [ember-flexberry-data](https://github.com/Flexberry/ember-flexberry-data)." %}
> В версиях Flexberry Ember 2.x содержалось пространство имен Query, содержащее перечисленные выше классы. Поскольку в Ember 3.x пространства имен более не используются в связи с [использованием ES6-модулей](https://github.com/emberjs/rfcs/blob/master/text/0176-javascript-module-api.md), все классы, содержавшиеся в пространстве имен Query, во Flexberry Ember 3.x теперь необходимо импортировать напрямую из [папки query](https://github.com/Flexberry/ember-flexberry-data/tree/feature-ember-update/addon/query) аддона [ember-flexberry-data](https://github.com/Flexberry/ember-flexberry-data).

## Builder

Expand Down Expand Up @@ -100,13 +102,13 @@ builder.from('employee');

Для указания того, какой предикат будет использоваться в запросе, используется метод `where` построителя запросов. При этом можно использовать различные варианты передачи параметров в данный метод.

1. Передача предиката любого типа в качестве параметра:
1.Передача предиката любого типа в качестве параметра:

```javascript
builder.where(SomePredicate);
```

2. Передача имени атрибута, операции и значения атрибута (аналог использования `SimplePredicate`)в качестве параметров:
2.Передача имени атрибута, операции и значения атрибута (аналог использования `SimplePredicate`)в качестве параметров:

```javascript
let builder = new Builder(store, 'customer').where('firstName', FilterOperator.Eq, 'Vasya');
Expand All @@ -124,10 +126,10 @@ let builder = new Builder(store, 'customer').where('manager', FilterOperator.Eq,
let builder = new Builder(store, 'customer').where('manager.firstName', FilterOperator.Eq, 'Vasya');
```

{% include note.html content="Пожалуйста, не используйте в значениях ограничений функцию `cast` и другие OData-специфичные функции!<br/><br/>
> Пожалуйста, не используйте в значениях ограничений функцию `cast` и другие OData-специфичные функции!<br/><br/>
Поступая так, вы привязываетесь в запросах к бэкенду конкретного типа.<br/>
Язык запросов создан для того, чтобы абстрагироваться от какого-либо типа бэкенда.<br/>
При несоблюдении этого правила ожидайте проблемы при работе в офлайне или смене типа бэкенда.<br/>" %}
При несоблюдении этого правила ожидайте проблемы при работе в офлайне или смене типа бэкенда.

### Сортировка

Expand Down Expand Up @@ -177,7 +179,7 @@ builder.count();
builder.select('id,age,name');
```

{% include note.html content="Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод selectByProjection!" %}
> Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод selectByProjection!

## Указание проекции

Expand All @@ -187,19 +189,19 @@ builder.select('id,age,name');
builder.selectByProjection('EmployeeTestProjection');
```

{% include note.html content="Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод select!" %}
> Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод select!

## Создание объекта запроса

Для того, чтобы создать объект запроса с указанными ранее опциями, используется метод `build` построителя запросов:
Для создания объекта запроса с указанными ранее опциями используется метод `build` построителя запросов:

```javascript
builder.build();
```

## Использование объекта запроса

Созданный объект запроса должен быть передан в качестве второго параметра в метод [query](https://api.emberjs.com/ember-data/3.1/classes/DS.Store/methods/query?anchor=query) сервиса [store](https://api.emberjs.com/ember-data/3.1/classes/DS.Store) библиотеки [Ember Data](https://api.emberjs.com/ember-data/3.1).
Созданный объект запроса должен быть передан в качестве второго параметра в метод [query](https://api.emberjs.com/ember-data/3.1/classes/DS.Store/methods/query?anchor=query) сервиса [store](https://api.emberjs.com/ember-data/3.1/classes/DS.Store) библиотеки [Ember Data](https://api.emberjs.com/ember-data/3.1).

```javascript
store.query(modelName, builder.build());
Expand All @@ -213,7 +215,8 @@ store.query(modelName, builder.build());

#### Конструктор

Конструктор класса `SimplePredicate` принимает 3 параметра:
Конструктор класса `SimplePredicate` принимает 3 параметра:

* `attributePath` - атрибут (собственный или у связанных моделей).
* `operator` - оператор (операция).
* `value` - значение атрибута.
Expand All @@ -222,7 +225,75 @@ store.query(modelName, builder.build());
let predicate = new SimplePredicate('name', FilterOperator.Eq, 'Vasya');
```

### Свойства предиката
#### Свойства предиката

Получить заданный в предикате атрибут ("путь атрибута") можно с использованием свойства `attributePath` предиката:

```javascript
predicate.attributePath
```

Получить заданный в предикате оператор (операцию) можно с использованием свойства `operator` предиката:

```javascript
predicate.operator
```

Получить заданное в предикате значение для атрибута можно с использованием свойства `value` предиката:

```javascript
predicate.value
```

#### AttributeParam и ConstParam

Для расширения возможностей `SimplePredicate` были добавлены сущности `AttributeParam` (указание, что передаётся атрибут) и `ConstParam` (указание, что передаётся значение).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Пустая строка после заголовка

В качестве первого параметра конструктора класса `SimplePredicate` может передаваться атрибут, `AttributeParam` или `ConstParam`.
В качестве третьего параметра конструктора класса `SimplePredicate` может передаваться значение атрибута, `AttributeParam` или `ConstParam`.

Такое расширение позволяет делать запрос с указанием двух атрибутов.

```javascript
let predicate = new SimplePredicate(new AttributeParam('currentMark'), FilterOperator.Le, new AttributeParam('lastMark'));
```

Также становится возможным менять местами в конструкторе атрибут и значение атрибута

```javascript
let predicate = new SimplePredicate(new ConstParam(5), FilterOperator.Le, new AttributeParam('lastMark'));
```

Возможно указание и двух значений, однако в такой ситуации разумнее использовать `TruePredicate` или `FalsePredicate`.

Существуют **ограничения**, связанные с использованием `AttributeParam` и `ConstParam` в конструкторе `SimplePredicate`.

1.При применении двух `AttributeParam` в конструкторе `SimplePredicate` необходимо при использовании `IndexedDbAdapter` или `JsAdapter` мастера указывать с "id" (без этого указания некорректно могут обрабатываться ситуации, когда мастер не задан). Например, если у сущности есть мастера author и editor:

```javascript
let predicate = new SimplePredicate(new AttributeParam('author.id'), FilterOperator.Eq, new AttributeParam('editor.id'));
```

2.При указании двух `ConstParam` с датами в виде строковых констант в конструкторе `SimplePredicate` возможно некорректное поведение в связи с тем, что конструктор не распознает, что это даты.

### DatePredicate

`DatePredicate` - предикат для фильтрации записей по атрибуту с типом "дата".

#### Конструктор

Конструктор класса `DatePredicate` принимает 4 параметра:

* `attributePath` - атрибут (собственный или у связанных моделей).
* `operator` - оператор (операция).
* `value` - значение атрибута.
* `timeless` - флаг, указывающий нужно ли учитывать время при сравнении дат (если указано `true`, то время не учитывается).

```javascript
let predicate = new DatePredicate('birthday', FilterOperator.Eq, '2018-02-06T11:00:00.000Z');
let predicate = new DatePredicate('birthday', FilterOperator.Eq, '2018-02-06', true);
```

#### Свойства предиката

Получить заданный в предикате атрибут ("путь атрибута") можно с использованием свойства `attributePath` предиката:

Expand All @@ -242,13 +313,28 @@ predicate.operator
predicate.value
```

Получить заданный в предикате флаг для необходимости учета времени можно с использованием свойства `timeless` предиката:

```javascript
predicate.timeless
```

#### AttributeParam и ConstParam

Для расширения возможностей `DatePredicate` были добавлены сущности `AttributeParam` (указание, что передаётся атрибут) и `ConstParam` (указание, что передаётся значение). Их использование аналогично применению в `SimplePredicate`, однако есть дополнительное ограничение: в `ODataAdapter` пока что **не поддерживаются** ограничения, формируемые `DatePredicate`, в конструктор которого переданы два `AttributeParam` и флаг отсутствия учёта времени (фильтрация в этом случае вернёт некорректное значение).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Пустая строка после заголовка


```javascript
let predicate = new DatePredicate(new AttributeParam('startDate'), FilterOperator.Le, new AttributeParam('endDate'), true);
```

### ComplexPredicate

`ComplexPredicate` - предикат, объединяющий несколько предикатов с помощью логических условий.

#### Конструктор

Конструктор класса `ComplexPredicate` принимает 2 параметра:
Конструктор класса `ComplexPredicate` принимает 2 параметра:

* `condition` - логическое условие (операция) для объединения предикатов.
* `...predicates` - список предикатов для объединения.

Expand Down Expand Up @@ -344,7 +430,8 @@ predicate.containsValue

#### Конструктор

Конструктор класса `DetailPredicate` принимает единственный параметр:
Конструктор класса `DetailPredicate` принимает единственный параметр:

* `detailPath` - имя связанной детейловой модели.

```javascript
Expand Down Expand Up @@ -431,49 +518,6 @@ let cp1 = new ComplexPredicate(Condition.Or, sp1, sp2);
let dp = new DetailPredicate('tags').any(cp1);
```

### DatePredicate

`DatePredicate` - предикат для фильтрации записей по атрибуту с типом "дата".

#### Конструктор

Конструктор класса `DatePredicate` принимает 4 параметра:
* `attributePath` - атрибут (собственный или у связанных моделей).
* `operator` - оператор (операция).
* `value` - значение атрибута.
`timeless` - флаг, указывающий нужно ли учитывать время при сравнении дат (если указано `true`, то время не учитывается).

```javascript
let predicate = new DatePredicate('birthday', FilterOperator.Eq, '2018-02-06T11:00:00.000Z');
let predicate = new DatePredicate('birthday', FilterOperator.Eq, '2018-02-06', true);
```

#### Свойства предиката

Получить заданный в предикате атрибут ("путь атрибута") можно с использованием свойства `attributePath` предиката:

```javascript
predicate.attributePath
```

Получить заданный в предикате оператор (операцию) можно с использованием свойства `operator` предиката:

```javascript
predicate.operator
```

Получить заданное в предикате значение для атрибута можно с использованием свойства `value` предиката:

```javascript
predicate.value
```

Получить заданный в предикате флаг для необходимости учета времени можно с использованием свойства `timeless` предиката:

```javascript
predicate.timeless
```

### GeographyPredicate и GeometryPredicate

* `GeographyPredicate` - предикат для проверки пересечения атрибута с типом "Geography" с заданной геометрической фигурой.
Expand All @@ -482,6 +526,7 @@ predicate.timeless
#### Конструктор

Конструктор принимает один параметр:

* `attributePath` - атрибут (собственный или у связанных моделей).

Также необходимо задать геометрическую фигуру, пересечение с которой будет проверяться. Для этого нужно воспользоваться методом `intersects` предиката.
Expand Down Expand Up @@ -513,6 +558,7 @@ predicate.intersectsValue
#### Конструктор

Конструктор класса `NotPredicate` принимает единственный параметр:

* `predicate` - предикат, значение которого нужно инвертировать.

```javascript
Expand Down Expand Up @@ -542,7 +588,8 @@ let predicateToInvert = np.predicate;
let predicate = new IsOFPredicate('customer');
```

Конструктор класса `IsOfPredicate` может также принимать два параметра:
Конструктор класса `IsOfPredicate` может также принимать два параметра:

* `expression` - атрибут (собственный или у связанных моделей).
* `typeName` - имя модели.

Expand Down Expand Up @@ -572,6 +619,7 @@ let builder = new Builder(store, 'creator').isOf('man');
## Операторы (операции)

В клиентском языке есть два класса, которые содержат свойства, являющиеся операторами (операциями) предикатов:

* `Condition` - класс с логическими операциями для `ComplexPredicate`.
* `FilterOperator` - класс с операциями для `SimplePredicate`, `StringPredicate` и `DatePredicate`.

Expand Down