diff --git a/pages/products/flexberry-ember/3.x/work-with-data/efd3_query-language.ru.md b/pages/products/flexberry-ember/3.x/work-with-data/efd3_query-language.ru.md index 592c4bb8a..093d7f798 100644 --- a/pages/products/flexberry-ember/3.x/work-with-data/efd3_query-language.ru.md +++ b/pages/products/flexberry-ember/3.x/work-with-data/efd3_query-language.ru.md @@ -47,6 +47,8 @@ summary: Описание клиентского языка запросов. * `GeometryPredicate` - класс для создания фильтра в запросе по геометрическим атрибутам. * `createPredicate` - функция для создания предиката по заданным параметрам. * `stringToPredicate` - функция для конвертации строки в предикат. +* `AttributeParam` - класс для описания атрибута в `SimplePredicate` и `DatePredicate`. +* `ConstParam`- класс для описания константы в `SimplePredicate` и `DatePredicate`. Для импорта и использования классов языка запросов необходимо использовать следующий код: @@ -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 @@ -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'); @@ -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-специфичные функции!

+> Пожалуйста, не используйте в значениях ограничений функцию `cast` и другие OData-специфичные функции!

Поступая так, вы привязываетесь в запросах к бэкенду конкретного типа.
Язык запросов создан для того, чтобы абстрагироваться от какого-либо типа бэкенда.
-При несоблюдении этого правила ожидайте проблемы при работе в офлайне или смене типа бэкенда.
" %} +При несоблюдении этого правила ожидайте проблемы при работе в офлайне или смене типа бэкенда. ### Сортировка @@ -177,7 +179,7 @@ builder.count(); builder.select('id,age,name'); ``` -{% include note.html content="Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод selectByProjection!" %} +> Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод selectByProjection! ## Указание проекции @@ -187,11 +189,11 @@ builder.select('id,age,name'); builder.selectByProjection('EmployeeTestProjection'); ``` -{% include note.html content="Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод select!" %} +> Если используется данный способ указания вычитываемых атрибутов в запросе, то нельзя одновременно использовать в запросе метод select! ## Создание объекта запроса -Для того, чтобы создать объект запроса с указанными ранее опциями, используется метод `build` построителя запросов: +Для создания объекта запроса с указанными ранее опциями используется метод `build` построителя запросов: ```javascript builder.build(); @@ -199,7 +201,7 @@ 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()); @@ -213,7 +215,8 @@ store.query(modelName, builder.build()); #### Конструктор -Конструктор класса `SimplePredicate` принимает 3 параметра: +Конструктор класса `SimplePredicate` принимает 3 параметра: + * `attributePath` - атрибут (собственный или у связанных моделей). * `operator` - оператор (операция). * `value` - значение атрибута. @@ -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` (указание, что передаётся значение). +В качестве первого параметра конструктора класса `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` предиката: @@ -242,13 +313,28 @@ predicate.operator predicate.value ``` +Получить заданный в предикате флаг для необходимости учета времени можно с использованием свойства `timeless` предиката: + +```javascript +predicate.timeless +``` + +#### AttributeParam и ConstParam + +Для расширения возможностей `DatePredicate` были добавлены сущности `AttributeParam` (указание, что передаётся атрибут) и `ConstParam` (указание, что передаётся значение). Их использование аналогично применению в `SimplePredicate`, однако есть дополнительное ограничение: в `ODataAdapter` пока что **не поддерживаются** ограничения, формируемые `DatePredicate`, в конструктор которого переданы два `AttributeParam` и флаг отсутствия учёта времени (фильтрация в этом случае вернёт некорректное значение). + +```javascript +let predicate = new DatePredicate(new AttributeParam('startDate'), FilterOperator.Le, new AttributeParam('endDate'), true); +``` + ### ComplexPredicate `ComplexPredicate` - предикат, объединяющий несколько предикатов с помощью логических условий. #### Конструктор -Конструктор класса `ComplexPredicate` принимает 2 параметра: +Конструктор класса `ComplexPredicate` принимает 2 параметра: + * `condition` - логическое условие (операция) для объединения предикатов. * `...predicates` - список предикатов для объединения. @@ -344,7 +430,8 @@ predicate.containsValue #### Конструктор -Конструктор класса `DetailPredicate` принимает единственный параметр: +Конструктор класса `DetailPredicate` принимает единственный параметр: + * `detailPath` - имя связанной детейловой модели. ```javascript @@ -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" с заданной геометрической фигурой. @@ -482,6 +526,7 @@ predicate.timeless #### Конструктор Конструктор принимает один параметр: + * `attributePath` - атрибут (собственный или у связанных моделей). Также необходимо задать геометрическую фигуру, пересечение с которой будет проверяться. Для этого нужно воспользоваться методом `intersects` предиката. @@ -513,6 +558,7 @@ predicate.intersectsValue #### Конструктор Конструктор класса `NotPredicate` принимает единственный параметр: + * `predicate` - предикат, значение которого нужно инвертировать. ```javascript @@ -542,7 +588,8 @@ let predicateToInvert = np.predicate; let predicate = new IsOFPredicate('customer'); ``` -Конструктор класса `IsOfPredicate` может также принимать два параметра: +Конструктор класса `IsOfPredicate` может также принимать два параметра: + * `expression` - атрибут (собственный или у связанных моделей). * `typeName` - имя модели. @@ -572,6 +619,7 @@ let builder = new Builder(store, 'creator').isOf('man'); ## Операторы (операции) В клиентском языке есть два класса, которые содержат свойства, являющиеся операторами (операциями) предикатов: + * `Condition` - класс с логическими операциями для `ComplexPredicate`. * `FilterOperator` - класс с операциями для `SimplePredicate`, `StringPredicate` и `DatePredicate`.