diff --git a/lib.config b/lib.config index efbf7b1..d88f4eb 100644 --- a/lib.config +++ b/lib.config @@ -8,6 +8,7 @@ + diff --git "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\240\320\260\320\261\320\276\321\202\320\260\320\241\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200\320\260\320\274\320\270.os" "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\240\320\260\320\261\320\276\321\202\320\260\320\241\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200\320\260\320\274\320\270.os" index 3323d22..32b6e4c 100644 --- "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\240\320\260\320\261\320\276\321\202\320\260\320\241\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200\320\260\320\274\320\270.os" +++ "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\240\320\260\320\261\320\276\321\202\320\260\320\241\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200\320\260\320\274\320\270.os" @@ -1,309 +1,338 @@ -#Использовать asserts - -Перем СвойстваКоннекторов; - -Функция СоздатьКоннектор(ТипКоннектора) Экспорт - Коннектор = Новый(ТипКоннектора); - СвойстваКоннектора = Конструктор_СвойстваКоннектора(); - СвойстваКоннекторов.Вставить(Коннектор, СвойстваКоннектора); - - Возврат Коннектор; -КонецФункции - -Процедура ОткрытьКоннектор(Коннектор, СтрокаСоединения, ПараметрыКоннектора) Экспорт - СвойстваКоннектора = СвойстваКоннекторов.Получить(Коннектор); - СвойстваКоннектора.СтрокаСоединения = СтрокаСоединения; - СвойстваКоннектора.Параметры = ПараметрыКоннектора; - - Коннектор.Открыть(СтрокаСоединения, ПараметрыКоннектора); -КонецПроцедуры - -Процедура ЗакрытьКоннектор(Коннектор) Экспорт - Если Коннектор.Открыт() Тогда - Коннектор.Закрыть(); - КонецЕсли; -КонецПроцедуры - -Процедура Сохранить(Коннектор, ОбъектМодели, ПулСущностей, Сущность) Экспорт - ТипСущности = АктивнаяЗапись.ТипСущности(Сущность); - - ПроверитьЧтоКлассЯвляетсяСущностью(ТипСущности); - ПроверитьЧтоТипСущностиЗарегистрированВМодели(ОбъектМодели); - ПроверитьНеобходимостьЗаполненияИдентификатора(ОбъектМодели, Сущность); - - Коннектор.Сохранить(ОбъектМодели, Сущность); - - // Сохранение полей, расширяемых таблицами - ПодчиненныеТаблицы = ОбъектМодели.ПодчиненныеТаблицы(); - Для Каждого ПодчиненнаяТаблица Из ПодчиненныеТаблицы Цикл - - ОбъектМоделиЭлементКоллекции = ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы( - ОбъектМодели, - ПодчиненнаяТаблица - ); - - // Очистка подчиненной таблицы - ЭлементОтбора = Новый ЭлементОтбора( - "ref", - ВидСравнения.Равно, - ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность) - ); - МассивОтборов = Новый Массив; - МассивОтборов.Добавить(ЭлементОтбора); - Коннектор.УдалитьСтрокиВТаблице(ОбъектМоделиЭлементКоллекции, МассивОтборов); - - РасширяемоеПоле = ОбъектМодели.ПолучитьЗначениеПоля(Сущность, ПодчиненнаяТаблица.ИмяПоля); - - Если НЕ ЗначениеЗаполнено(РасширяемоеПоле) Тогда - Продолжить; - КонецЕсли; - - КоллекцияСущностей = ОбработкаКоллекций.ПреобразоватьКоллекциюККоллекцииСущностей( - РасширяемоеПоле, - Сущность, - ОбъектМодели, - ПодчиненнаяТаблица - ); - - Для Каждого ЭлементКоллекции Из КоллекцияСущностей Цикл - Коннектор.Сохранить(ОбъектМоделиЭлементКоллекции, ЭлементКоллекции); - КонецЦикла; - - КонецЦикла; - - ПулСущностей.Вставить(ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность), Сущность); -КонецПроцедуры - -Функция Получить(Коннектор, ОбъектМодели, ПулСущностей, Отбор = Неопределено) Экспорт - Колонки = ОбъектМодели.Колонки(); - ПодчиненныеТаблицы = ОбъектМодели.ПодчиненныеТаблицы(); - - ПередаваемыйОтбор = Новый Массив; - - Если ТипЗнч(Отбор) = Тип("Соответствие") Тогда - // Переформируем ключи отбора из имен полей в имена колонок - Для Каждого КлючИЗначение Из Отбор Цикл - Колонка = Колонки.Найти(КлючИЗначение.Ключ, "ИмяПоля"); - Ожидаем.Что( - Колонка, - СтрШаблон("Не удалось найти данные о колонке по имени поля %1", КлючИЗначение.Ключ) - ).Не_().Равно(Неопределено); - - ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ВидСравнения.Равно, КлючИЗначение.Значение); - ПередаваемыйОтбор.Добавить(ЭлементОтбора); - КонецЦикла; - ИначеЕсли ТипЗнч(Отбор) = Тип("Массив") Тогда - Для Каждого ЭлементОтбора Из Отбор Цикл - Колонка = Колонки.Найти(ЭлементОтбора.ПутьКДанным, "ИмяПоля"); - Ожидаем.Что( - Колонка, - СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементОтбора.ПутьКДанным) - ).Не_().Равно(Неопределено); - - ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ЭлементОтбора.ВидСравнения, ЭлементОтбора.Значение); - ПередаваемыйОтбор.Добавить(ЭлементОтбора); - КонецЦикла; - ИначеЕсли ТипЗнч(Отбор) = Тип("ЭлементОтбора") Тогда - ЭлементОтбора = Отбор; - Колонка = Колонки.Найти(ЭлементОтбора.ПутьКДанным, "ИмяПоля"); - Ожидаем.Что( - Колонка, - СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементОтбора.ПутьКДанным) - ).Не_().Равно(Неопределено); - - ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ЭлементОтбора.ВидСравнения, ЭлементОтбора.Значение); - ПередаваемыйОтбор.Добавить(ЭлементОтбора); - ИначеЕсли Отбор = Неопределено Тогда - // no-op - Иначе - ВызватьИсключение "В метод получения данных передан неожиданный тип отбора: " + ТипЗнч(Отбор); - КонецЕсли; - - НайденныеСущности = Новый Массив; - - НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, ПередаваемыйОтбор); - Если НайденныеСтроки.Количество() = 0 Тогда - Возврат НайденныеСущности; - КонецЕсли; - - Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл - ЗначениеИдентификатора = НайденнаяСтрока.Получить(ОбъектМодели.Идентификатор().ИмяКолонки); - ЗначениеИдентификатора = ОбъектМодели.ПривестиЗначениеПоля( - ЗначениеИдентификатора, - ОбъектМодели.Идентификатор().ИмяПоля - ); - Сущность = ПулСущностей.Получить(ЗначениеИдентификатора); - Если Сущность = Неопределено Тогда - ХранилищеСущностей = ХранилищаСущностей.Получить(ОбъектМодели, Коннектор); - Сущность = АктивнаяЗапись.СоздатьИзХранилища(ОбъектМодели, ХранилищеСущностей); - ПулСущностей.Вставить(ЗначениеИдентификатора, Сущность); - КонецЕсли; - - Для Каждого Колонка Из Колонки Цикл - - ЗначениеКолонки = НайденнаяСтрока.Получить(Колонка.ИмяКолонки); - Если Колонка.ТипКолонки = ТипыКолонок.Ссылка И ЗначениеЗаполнено(ЗначениеКолонки) Тогда - - Если Колонка.ТипСсылки = ОбъектМодели.ТипСущности() И ЗначениеКолонки = ЗначениеИдентификатора Тогда - ЗначениеКолонки = Сущность; - Иначе - ХранилищеСущностейСсылки = ХранилищаСущностей.Получить( - ОбъектМодели.МодельДанных().Получить(Колонка.ТипСсылки), - Коннектор - ); - ЗначениеКолонки = ХранилищеСущностейСсылки.ПолучитьОдно(ЗначениеКолонки); - КонецЕсли; - КонецЕсли; - - ОбъектМодели.УстановитьЗначениеКолонкиВПоле(Сущность, Колонка.ИмяКолонки, ЗначениеКолонки); - КонецЦикла; - - Для Каждого ПодчиненнаяТаблица Из ПодчиненныеТаблицы Цикл - ОбъектМоделиЭлементКоллекции = ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы( - ОбъектМодели, - ПодчиненнаяТаблица - ); - - ЭлементОтбора = Новый ЭлементОтбора( - "ref", - ВидСравнения.Равно, - ЗначениеИдентификатора - ); - - МассивОтборов = Новый Массив; - МассивОтборов.Добавить(ЭлементОтбора); - ЗначениеКолонки = Коннектор.НайтиСтрокиВТаблице(ОбъектМоделиЭлементКоллекции, МассивОтборов); - - ЗначениеКолонки = ОбработкаКоллекций.ПреобразоватьКоллекциюСтрокККоллекции(ЗначениеКолонки, ПодчиненнаяТаблица); - - Если ПодчиненнаяТаблица.КаскадноеЧтение - И ТипыКолонок.ЭтоСсылочныйТип(ПодчиненнаяТаблица.ТипЭлемента) Тогда - - ХранилищеСущностейСсылки = ХранилищаСущностей.Получить( - ОбъектМодели.МодельДанных().Получить(ПодчиненнаяТаблица.ТипЭлемента), - Коннектор - ); - - Для НомерИндекса = 0 По ЗначениеКолонки.ВГраница() Цикл - ЗначениеКолонки[НомерИндекса] = ХранилищеСущностейСсылки.ПолучитьОдно(ЗначениеКолонки[НомерИндекса]); - КонецЦикла; - - КонецЕсли; - - ОбъектМодели.УстановитьЗначениеПодчиненнойТаблицыВПоле(Сущность, ПодчиненнаяТаблица.ИмяПоля, ЗначениеКолонки); - КонецЦикла; - - НайденныеСущности.Добавить(Сущность); - КонецЦикла; - - Возврат НайденныеСущности; -КонецФункции - -Функция ПолучитьОдно(Коннектор, ОбъектМодели, ПулСущностей, Знач Отбор = Неопределено) Экспорт - - Если Отбор = Неопределено Тогда - ПередаваемыйОтбор = Отбор; - ИначеЕсли ТипЗнч(Отбор) = Тип("Соответствие") Тогда - ПередаваемыйОтбор = Отбор; - ИначеЕсли ТипЗнч(Отбор) = Тип("Массив") Тогда - ПередаваемыйОтбор = Отбор; - ИначеЕсли ТипЗнч(Отбор) = Тип("ЭлементОтбора") Тогда - ПередаваемыйОтбор = Отбор; - Иначе - ПередаваемыйОтбор = Новый Соответствие(); - ПередаваемыйОтбор.Вставить(ОбъектМодели.Идентификатор().ИмяПоля, Отбор); - КонецЕсли; - - НайденныеСущности = Получить(Коннектор, ОбъектМодели, ПулСущностей, ПередаваемыйОтбор); - - Если НайденныеСущности.Количество() = 0 Тогда - Возврат Неопределено; - Иначе - Возврат НайденныеСущности[0]; - КонецЕсли; - -КонецФункции - -// Удаляет удаление сущности из базы данных. -// Сущность должна иметь заполненный идентификатор. -// -// Параметры: -// Сущность - Произвольный - Удаляемая сущность -// -Процедура Удалить(Коннектор, ОбъектМодели, ПулСущностей, Сущность) Экспорт - Коннектор.Удалить(ОбъектМодели, Сущность); - ПулСущностей.Удалить(Сущность); -КонецПроцедуры - -// Посылает коннектору запрос на начало транзакции. -// -Процедура НачатьТранзакцию(Коннектор) Экспорт - Коннектор.НачатьТранзакцию(); -КонецПроцедуры - -// Посылает коннектору запрос на фиксацию транзакции. -// -Процедура ЗафиксироватьТранзакцию(Коннектор) Экспорт - Коннектор.ЗафиксироватьТранзакцию(); -КонецПроцедуры - -// Посылает коннектору запрос на отмену транзакции. -// -Процедура ОтменитьТранзакцию(Коннектор) Экспорт - Коннектор.ОтменитьТранзакцию(); -КонецПроцедуры - -// Возвращает дополнительные свойства коннектора -// -// Параметры: -// Коннектор - АбстрактныйКоннектор - Коннектор, свойства которого необходимо получить. -// -// Возвращаемое значение: -// Структура - Дополнительные свойства коннектора. см. Конструктор_СвойстваКоннектора() -// -Функция ПолучитьСвойстваКоннектора(Коннектор) Экспорт - Возврат СвойстваКоннекторов.Получить(Коннектор); -КонецФункции - -// <Описание процедуры> -// -// Параметры: -// ТипКласса - Тип - Тип, в котором проверяется наличие необходимых аннотаций. -// -Процедура ПроверитьЧтоКлассЯвляетсяСущностью(ТипКласса) - - РефлекторОбъекта = Новый РефлекторОбъекта(ТипКласса); - ТаблицаМетодов = РефлекторОбъекта.ПолучитьТаблицуМетодов("Сущность", Ложь); - Ожидаем.Что(ТаблицаМетодов, СтрШаблон("Класс %1 не имеет аннотации &Сущность", ТипКласса)).ИмеетДлину(1); - - ТаблицаСвойств = РефлекторОбъекта.ПолучитьТаблицуСвойств("Идентификатор"); - Ожидаем.Что(ТаблицаСвойств, СтрШаблон("Класс %1 не имеет поля с аннотацией &Идентификатор", ТипКласса)).ИмеетДлину(1); - -КонецПроцедуры - -Процедура ПроверитьЧтоТипСущностиЗарегистрированВМодели(ОбъектМодели) - // TODO: проверка должна быть в момент получения репозитория - Ожидаем.Что(ОбъектМодели, "Тип сущности не зарегистрирован в модели данных").Не_().Равно(Неопределено); -КонецПроцедуры - -Процедура ПроверитьНеобходимостьЗаполненияИдентификатора(ОбъектМодели, Сущность) - Если ОбъектМодели.Идентификатор().ГенерируемоеЗначение Тогда - Возврат; - КонецЕсли; - - ЗначениеИдентификатора = ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность); - Ожидаем.Что( - ЗначениеИдентификатора, СтрШаблон("Сущность с типом %1 должна иметь заполненный идентификатор", Тип(Сущность)) - ).Заполнено(); - -КонецПроцедуры - -Функция Конструктор_СвойстваКоннектора() - СвойстваКоннектора = Новый Структура; - СвойстваКоннектора.Вставить("СтрокаСоединения"); - СвойстваКоннектора.Вставить("Параметры"); - - Возврат СвойстваКоннектора; -КонецФункции - -СвойстваКоннекторов = Новый Соответствие(); +#Использовать asserts + +Перем СвойстваКоннекторов; + +Функция СоздатьКоннектор(ТипКоннектора) Экспорт + Коннектор = Новый(ТипКоннектора); + СвойстваКоннектора = Конструктор_СвойстваКоннектора(); + СвойстваКоннекторов.Вставить(Коннектор, СвойстваКоннектора); + + Возврат Коннектор; +КонецФункции + +Процедура ОткрытьКоннектор(Коннектор, СтрокаСоединения, ПараметрыКоннектора) Экспорт + СвойстваКоннектора = СвойстваКоннекторов.Получить(Коннектор); + СвойстваКоннектора.СтрокаСоединения = СтрокаСоединения; + СвойстваКоннектора.Параметры = ПараметрыКоннектора; + + Коннектор.Открыть(СтрокаСоединения, ПараметрыКоннектора); +КонецПроцедуры + +Процедура ЗакрытьКоннектор(Коннектор) Экспорт + Если Коннектор.Открыт() Тогда + Коннектор.Закрыть(); + КонецЕсли; +КонецПроцедуры + +Процедура Сохранить(Коннектор, ОбъектМодели, ПулСущностей, Сущность) Экспорт + ТипСущности = АктивнаяЗапись.ТипСущности(Сущность); + + ПроверитьЧтоКлассЯвляетсяСущностью(ТипСущности); + ПроверитьЧтоТипСущностиЗарегистрированВМодели(ОбъектМодели); + ПроверитьНеобходимостьЗаполненияИдентификатора(ОбъектМодели, Сущность); + + Коннектор.Сохранить(ОбъектМодели, Сущность); + + // Сохранение полей, расширяемых таблицами + ПодчиненныеТаблицы = ОбъектМодели.ПодчиненныеТаблицы(); + Для Каждого ПодчиненнаяТаблица Из ПодчиненныеТаблицы Цикл + + ОбъектМоделиЭлементКоллекции = ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы( + ОбъектМодели, + ПодчиненнаяТаблица + ); + + // Очистка подчиненной таблицы + ЭлементОтбора = Новый ЭлементОтбора( + "ref", + ВидСравнения.Равно, + ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность) + ); + МассивОтборов = Новый Массив; + МассивОтборов.Добавить(ЭлементОтбора); + Коннектор.УдалитьСтрокиВТаблице(ОбъектМоделиЭлементКоллекции, МассивОтборов); + + РасширяемоеПоле = ОбъектМодели.ПолучитьЗначениеПоля(Сущность, ПодчиненнаяТаблица.ИмяПоля); + + Если НЕ ЗначениеЗаполнено(РасширяемоеПоле) Тогда + Продолжить; + КонецЕсли; + + КоллекцияСущностей = ОбработкаКоллекций.ПреобразоватьКоллекциюККоллекцииСущностей( + РасширяемоеПоле, + Сущность, + ОбъектМодели, + ПодчиненнаяТаблица + ); + + Для Каждого ЭлементКоллекции Из КоллекцияСущностей Цикл + Коннектор.Сохранить(ОбъектМоделиЭлементКоллекции, ЭлементКоллекции); + КонецЦикла; + + КонецЦикла; + + ПулСущностей.Вставить(ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность), Сущность); +КонецПроцедуры + +Функция Получить(Коннектор, ОбъектМодели, ПулСущностей, Отбор = Неопределено, Сортировка = Неопределено) Экспорт + Колонки = ОбъектМодели.Колонки(); + ПодчиненныеТаблицы = ОбъектМодели.ПодчиненныеТаблицы(); + + ПередаваемыйОтбор = Новый Массив; + ПередаваемаяСортировка = Новый Массив; + + Если ТипЗнч(Отбор) = Тип("Соответствие") Тогда + // Переформируем ключи отбора из имен полей в имена колонок + Для Каждого КлючИЗначение Из Отбор Цикл + Колонка = Колонки.Найти(КлючИЗначение.Ключ, "ИмяПоля"); + Ожидаем.Что( + Колонка, + СтрШаблон("Не удалось найти данные о колонке по имени поля %1", КлючИЗначение.Ключ) + ).Не_().Равно(Неопределено); + + ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ВидСравнения.Равно, КлючИЗначение.Значение); + ПередаваемыйОтбор.Добавить(ЭлементОтбора); + КонецЦикла; + ИначеЕсли ТипЗнч(Отбор) = Тип("Массив") Тогда + Для Каждого ЭлементОтбора Из Отбор Цикл + Колонка = Колонки.Найти(ЭлементОтбора.ПутьКДанным, "ИмяПоля"); + Ожидаем.Что( + Колонка, + СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементОтбора.ПутьКДанным) + ).Не_().Равно(Неопределено); + + ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ЭлементОтбора.ВидСравнения, ЭлементОтбора.Значение); + ПередаваемыйОтбор.Добавить(ЭлементОтбора); + КонецЦикла; + ИначеЕсли ТипЗнч(Отбор) = Тип("ЭлементОтбора") Тогда + ЭлементОтбора = Отбор; + Колонка = Колонки.Найти(ЭлементОтбора.ПутьКДанным, "ИмяПоля"); + Ожидаем.Что( + Колонка, + СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементОтбора.ПутьКДанным) + ).Не_().Равно(Неопределено); + + ЭлементОтбора = Новый ЭлементОтбора(Колонка.ИмяКолонки, ЭлементОтбора.ВидСравнения, ЭлементОтбора.Значение); + ПередаваемыйОтбор.Добавить(ЭлементОтбора); + ИначеЕсли Отбор = Неопределено Тогда + // no-op + Иначе + ВызватьИсключение "В метод получения данных передан неожиданный тип отбора: " + ТипЗнч(Отбор); + КонецЕсли; + + Если ТипЗнч(Сортировка) = Тип("Массив") Тогда + Для Каждого ЭлементПорядка Из Сортировка Цикл + Колонка = Колонки.Найти(ЭлементПорядка.ПутьКДанным, "ИмяПоля"); + Ожидаем.Что( + Колонка, + СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементПорядка.ПутьКДанным) + ).Не_().Равно(Неопределено); + + ЭлементПорядка = Новый ЭлементПорядка(Колонка.ИмяКолонки, ЭлементПорядка.НаправлениеСортировки); + ПередаваемаяСортировка.Добавить(ЭлементПорядка); + КонецЦикла; + ИначеЕсли ТипЗнч(Сортировка) = Тип("ЭлементПорядка") Тогда + ЭлементПорядка = Сортировка; + Колонка = Колонки.Найти(ЭлементПорядка.ПутьКДанным, "ИмяПоля"); + Ожидаем.Что( + Колонка, + СтрШаблон("Не удалось найти данные о колонке по имени поля %1", ЭлементПорядка.ПутьКДанным) + ).Не_().Равно(Неопределено); + + ЭлементПорядка = Новый ЭлементПорядка(Колонка.ИмяКолонки, ЭлементПорядка.НаправлениеСортировки); + ПередаваемаяСортировка.Добавить(ЭлементПорядка); + ИначеЕсли Сортировка = Неопределено Тогда + // no-op + Иначе + ВызватьИсключение "В метод получения данных передан неожиданный тип сортировки: " + ТипЗнч(Сортировка); + КонецЕсли; + + НайденныеСущности = Новый Массив; + + НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, ПередаваемыйОтбор, ПередаваемаяСортировка); + Если НайденныеСтроки.Количество() = 0 Тогда + Возврат НайденныеСущности; + КонецЕсли; + + Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл + ЗначениеИдентификатора = НайденнаяСтрока.Получить(ОбъектМодели.Идентификатор().ИмяКолонки); + ЗначениеИдентификатора = ОбъектМодели.ПривестиЗначениеПоля( + ЗначениеИдентификатора, + ОбъектМодели.Идентификатор().ИмяПоля + ); + Сущность = ПулСущностей.Получить(ЗначениеИдентификатора); + Если Сущность = Неопределено Тогда + ХранилищеСущностей = ХранилищаСущностей.Получить(ОбъектМодели, Коннектор); + Сущность = АктивнаяЗапись.СоздатьИзХранилища(ОбъектМодели, ХранилищеСущностей); + ПулСущностей.Вставить(ЗначениеИдентификатора, Сущность); + КонецЕсли; + + Для Каждого Колонка Из Колонки Цикл + + ЗначениеКолонки = НайденнаяСтрока.Получить(Колонка.ИмяКолонки); + Если Колонка.ТипКолонки = ТипыКолонок.Ссылка И ЗначениеЗаполнено(ЗначениеКолонки) Тогда + + Если Колонка.ТипСсылки = ОбъектМодели.ТипСущности() И ЗначениеКолонки = ЗначениеИдентификатора Тогда + ЗначениеКолонки = Сущность; + Иначе + ХранилищеСущностейСсылки = ХранилищаСущностей.Получить( + ОбъектМодели.МодельДанных().Получить(Колонка.ТипСсылки), + Коннектор + ); + ЗначениеКолонки = ХранилищеСущностейСсылки.ПолучитьОдно(ЗначениеКолонки); + КонецЕсли; + КонецЕсли; + + ОбъектМодели.УстановитьЗначениеКолонкиВПоле(Сущность, Колонка.ИмяКолонки, ЗначениеКолонки); + КонецЦикла; + + Для Каждого ПодчиненнаяТаблица Из ПодчиненныеТаблицы Цикл + ОбъектМоделиЭлементКоллекции = ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы( + ОбъектМодели, + ПодчиненнаяТаблица + ); + + ЭлементОтбора = Новый ЭлементОтбора( + "ref", + ВидСравнения.Равно, + ЗначениеИдентификатора + ); + + МассивОтборов = Новый Массив; + МассивОтборов.Добавить(ЭлементОтбора); + МассивСортировки = Новый Массив; + ЗначениеКолонки = Коннектор.НайтиСтрокиВТаблице(ОбъектМоделиЭлементКоллекции, МассивОтборов, МассивСортировки); + + ЗначениеКолонки = ОбработкаКоллекций.ПреобразоватьКоллекциюСтрокККоллекции(ЗначениеКолонки, ПодчиненнаяТаблица); + + Если ПодчиненнаяТаблица.КаскадноеЧтение + И ТипыКолонок.ЭтоСсылочныйТип(ПодчиненнаяТаблица.ТипЭлемента) Тогда + + ХранилищеСущностейСсылки = ХранилищаСущностей.Получить( + ОбъектМодели.МодельДанных().Получить(ПодчиненнаяТаблица.ТипЭлемента), + Коннектор + ); + + Для НомерИндекса = 0 По ЗначениеКолонки.ВГраница() Цикл + ЗначениеКолонки[НомерИндекса] = ХранилищеСущностейСсылки.ПолучитьОдно(ЗначениеКолонки[НомерИндекса]); + КонецЦикла; + + КонецЕсли; + + ОбъектМодели.УстановитьЗначениеПодчиненнойТаблицыВПоле(Сущность, ПодчиненнаяТаблица.ИмяПоля, ЗначениеКолонки); + КонецЦикла; + + НайденныеСущности.Добавить(Сущность); + КонецЦикла; + + Возврат НайденныеСущности; +КонецФункции + +Функция ПолучитьОдно(Коннектор, ОбъектМодели, ПулСущностей, Знач Отбор = Неопределено) Экспорт + + Если Отбор = Неопределено Тогда + ПередаваемыйОтбор = Отбор; + ИначеЕсли ТипЗнч(Отбор) = Тип("Соответствие") Тогда + ПередаваемыйОтбор = Отбор; + ИначеЕсли ТипЗнч(Отбор) = Тип("Массив") Тогда + ПередаваемыйОтбор = Отбор; + ИначеЕсли ТипЗнч(Отбор) = Тип("ЭлементОтбора") Тогда + ПередаваемыйОтбор = Отбор; + Иначе + ПередаваемыйОтбор = Новый Соответствие(); + ПередаваемыйОтбор.Вставить(ОбъектМодели.Идентификатор().ИмяПоля, Отбор); + КонецЕсли; + + НайденныеСущности = Получить(Коннектор, ОбъектМодели, ПулСущностей, ПередаваемыйОтбор); + + Если НайденныеСущности.Количество() = 0 Тогда + Возврат Неопределено; + Иначе + Возврат НайденныеСущности[0]; + КонецЕсли; + +КонецФункции + +// Удаляет удаление сущности из базы данных. +// Сущность должна иметь заполненный идентификатор. +// +// Параметры: +// Сущность - Произвольный - Удаляемая сущность +// +Процедура Удалить(Коннектор, ОбъектМодели, ПулСущностей, Сущность) Экспорт + Коннектор.Удалить(ОбъектМодели, Сущность); + ПулСущностей.Удалить(Сущность); +КонецПроцедуры + +// Посылает коннектору запрос на начало транзакции. +// +Процедура НачатьТранзакцию(Коннектор) Экспорт + Коннектор.НачатьТранзакцию(); +КонецПроцедуры + +// Посылает коннектору запрос на фиксацию транзакции. +// +Процедура ЗафиксироватьТранзакцию(Коннектор) Экспорт + Коннектор.ЗафиксироватьТранзакцию(); +КонецПроцедуры + +// Посылает коннектору запрос на отмену транзакции. +// +Процедура ОтменитьТранзакцию(Коннектор) Экспорт + Коннектор.ОтменитьТранзакцию(); +КонецПроцедуры + +// Возвращает дополнительные свойства коннектора +// +// Параметры: +// Коннектор - АбстрактныйКоннектор - Коннектор, свойства которого необходимо получить. +// +// Возвращаемое значение: +// Структура - Дополнительные свойства коннектора. см. Конструктор_СвойстваКоннектора() +// +Функция ПолучитьСвойстваКоннектора(Коннектор) Экспорт + Возврат СвойстваКоннекторов.Получить(Коннектор); +КонецФункции + +// <Описание процедуры> +// +// Параметры: +// ТипКласса - Тип - Тип, в котором проверяется наличие необходимых аннотаций. +// +Процедура ПроверитьЧтоКлассЯвляетсяСущностью(ТипКласса) + + РефлекторОбъекта = Новый РефлекторОбъекта(ТипКласса); + ТаблицаМетодов = РефлекторОбъекта.ПолучитьТаблицуМетодов("Сущность", Ложь); + Ожидаем.Что(ТаблицаМетодов, СтрШаблон("Класс %1 не имеет аннотации &Сущность", ТипКласса)).ИмеетДлину(1); + + ТаблицаСвойств = РефлекторОбъекта.ПолучитьТаблицуСвойств("Идентификатор"); + Ожидаем.Что(ТаблицаСвойств, СтрШаблон("Класс %1 не имеет поля с аннотацией &Идентификатор", ТипКласса)).ИмеетДлину(1); + +КонецПроцедуры + +Процедура ПроверитьЧтоТипСущностиЗарегистрированВМодели(ОбъектМодели) + // TODO: проверка должна быть в момент получения репозитория + Ожидаем.Что(ОбъектМодели, "Тип сущности не зарегистрирован в модели данных").Не_().Равно(Неопределено); +КонецПроцедуры + +Процедура ПроверитьНеобходимостьЗаполненияИдентификатора(ОбъектМодели, Сущность) + Если ОбъектМодели.Идентификатор().ГенерируемоеЗначение Тогда + Возврат; + КонецЕсли; + + ЗначениеИдентификатора = ОбъектМодели.ПолучитьЗначениеИдентификатора(Сущность); + Ожидаем.Что( + ЗначениеИдентификатора, СтрШаблон("Сущность с типом %1 должна иметь заполненный идентификатор", Тип(Сущность)) + ).Заполнено(); + +КонецПроцедуры + +Функция Конструктор_СвойстваКоннектора() + СвойстваКоннектора = Новый Структура; + СвойстваКоннектора.Вставить("СтрокаСоединения"); + СвойстваКоннектора.Вставить("Параметры"); + + Возврат СвойстваКоннектора; +КонецФункции + +СвойстваКоннекторов = Новый Соответствие(); diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200.os" index d6d901e..665d76c 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200.os" @@ -91,7 +91,7 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Отбор = Неопределено) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Отбор = Неопределено, Сортировка = Неопределено) Экспорт МассивЗначений = Новый Массив; Возврат МассивЗначений; diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQL.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQL.os" index 1c15771..baf72e9 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQL.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\261\321\201\321\202\321\200\320\260\320\272\321\202\320\275\321\213\320\271\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQL.os" @@ -58,19 +58,8 @@ ОбъектМодели.ИмяТаблицы() ); - СтрокаУсловий = ""; - - Для сч = 0 По Отбор.ВГраница() Цикл - ЭлементОтбора = Отбор[сч]; - ПредставлениеСчетчика = "п" + Формат(сч + 1, "ЧН=0; ЧГ="); - Если ЗначениеЗаполнено(СтрокаУсловий) Тогда - СтрокаУсловий = СтрокаУсловий + Символы.ПС + Символы.Таб + "AND "; - КонецЕсли; - СтрокаУсловий = СтрокаУсловий - + СтрШаблон("%1 %2 @%3", ЭлементОтбора.ПутьКДанным, ЭлементОтбора.ВидСравнения, ПредставлениеСчетчика); - Запрос.УстановитьПараметр(ПредставлениеСчетчика, ЭлементОтбора.Значение); - КонецЦикла; - + СтрокаУсловий = ПолучитьСтрокуУсловий(Запрос, Отбор); + Если ЗначениеЗаполнено(СтрокаУсловий) Тогда ТекстЗапроса = ТекстЗапроса + Символы.ПС + "WHERE " + СтрокаУсловий; КонецЕсли; @@ -93,7 +82,7 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор = Неопределено, Знач Сортировка = Неопределено) Экспорт НайденныеСтроки = Новый Массив; Колонки = ОбъектМодели.Колонки(); @@ -105,26 +94,17 @@ ОбъектМодели.ИмяТаблицы() ); - СтрокаУсловий = ""; - - Для сч = 0 По Отбор.ВГраница() Цикл - ЭлементОтбора = Отбор[сч]; - ПредставлениеСчетчика = "п" + Формат(сч + 1, "ЧН=0; ЧГ="); - Если ЗначениеЗаполнено(СтрокаУсловий) Тогда - СтрокаУсловий = СтрокаУсловий + Символы.ПС + Символы.Таб + "AND "; - КонецЕсли; - СтрокаУсловий = СтрокаУсловий + СтрШаблон( - "%1 %2 @%3", - ЭлементОтбора.ПутьКДанным, - ЭлементОтбора.ВидСравнения, - ПредставлениеСчетчика - ); - Запрос.УстановитьПараметр(ПредставлениеСчетчика, ЭлементОтбора.Значение); - КонецЦикла; + СтрокаУсловий = ПолучитьСтрокуУсловий(Запрос, Отбор); Если ЗначениеЗаполнено(СтрокаУсловий) Тогда ТекстЗапроса = ТекстЗапроса + Символы.ПС + "WHERE " + СтрокаУсловий; КонецЕсли; + + СтрокаСортировки = ПолучитьСтрокуСортировки(Сортировка); + + Если ЗначениеЗаполнено(СтрокаСортировки) Тогда + ТекстЗапроса = ТекстЗапроса + Символы.ПС + "ORDER BY " + СтрокаСортировки; + КонецЕсли; Лог.Отладка("Поиск сущности в таблице %1:%2%3", ОбъектМодели.ИмяТаблицы(), Символы.ПС, ТекстЗапроса); @@ -256,4 +236,60 @@ Запрос.ВыполнитьКоманду(); -КонецПроцедуры \ No newline at end of file +КонецПроцедуры + +Функция ПолучитьСтрокуУсловий(Запрос, Отбор) Экспорт + + СтрокаУсловий = ""; + + Если Отбор = Неопределено Тогда + Возврат СтрокаУсловий; + КонецЕсли; + + Для сч = 0 По Отбор.ВГраница() Цикл + ЭлементОтбора = Отбор[сч]; + ПредставлениеСчетчика = "п" + Формат(сч + 1, "ЧН=0; ЧГ="); + Если ЗначениеЗаполнено(СтрокаУсловий) Тогда + СтрокаУсловий = СтрокаУсловий + Символы.ПС + Символы.Таб + "AND "; + КонецЕсли; + СтрокаУсловий = СтрокаУсловий + СтрШаблон( + "%1 %2 @%3", + ЭлементОтбора.ПутьКДанным, + ЭлементОтбора.ВидСравнения, + ПредставлениеСчетчика + ); + Запрос.УстановитьПараметр(ПредставлениеСчетчика, ЭлементОтбора.Значение); + КонецЦикла; + + Возврат СтрокаУсловий; + +КонецФункции + +Функция ПолучитьСтрокуСортировки(Сортировка) + + СтрокаСортировки = ""; + + Если Сортировка = Неопределено Тогда + Возврат СтрокаСортировки; + КонецЕсли; + + Для сч = 0 По Сортировка.ВГраница() Цикл + ЭлементСортировки = Сортировка[сч]; + + Если ЗначениеЗаполнено(СтрокаСортировки) Тогда + СтрокаСортировки = СтрокаСортировки + ", " + Символы.ПС + Символы.Таб; + КонецЕсли; + + ИмяКолонки = ЭлементСортировки.ПутьКДанным; + Направление = ?(ЭлементСортировки.НаправлениеСортировки = НаправлениеСортировки.Возр, "ASC", "DESC"); + + СтрокаСортировки = СтрокаСортировки + СтрШаблон( + "%1 %2", + ИмяКолонки, + Направление + ); + КонецЦикла; + + Возврат СтрокаСортировки; + +КонецФункции diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" index ac6f4af..bfcebb5 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" @@ -1,4 +1,5 @@ #Использовать "../internal" +#Использовать fluent // Для хранения статуса соединения Перем Открыт; @@ -187,7 +188,7 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Отбор = Неопределено) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Отбор = Неопределено, Сортировка = Неопределено) Экспорт ИмяТаблицы = ОбъектМодели.ИмяТаблицы(); @@ -201,24 +202,60 @@ Колонки = ОбъектМодели.Колонки(); - Для Каждого ЭлементОтбора Из Отбор Цикл + Если Отбор <> Неопределено Тогда + Для Каждого ЭлементОтбора Из Отбор Цикл - НайденныеКолонки = Колонки.НайтиСтроки(Новый Структура("ИмяКолонки", ЭлементОтбора.ПутьКДанным)); + НайденныеКолонки = Колонки.НайтиСтроки(Новый Структура("ИмяКолонки", ЭлементОтбора.ПутьКДанным)); - Если НайденныеКолонки.Количество() = 0 Тогда - ИмяПоля = ЭлементОтбора.ПутьКДанным; - Иначе - ИмяПоля = НайденныеКолонки[0].ИмяПоля; - КонецЕсли; + Если НайденныеКолонки.Количество() = 0 Тогда + ИмяПоля = ЭлементОтбора.ПутьКДанным; + Иначе + ИмяПоля = НайденныеКолонки[0].ИмяПоля; + КонецЕсли; - СтрокаУсловие = СтрШаблон( + СтрокаУсловие = СтрШаблон( "Элемент -> Элемент._Сущность.%1 %2 Значение", - ИмяПоля, - ЭлементОтбора.ВидСравнения - ); - ДополнительныеПараметры = Новый Структура("Значение", ЭлементОтбора.Значение); - ПроцессорКоллекций = ПроцессорКоллекций.Фильтровать(СтрокаУсловие, ДополнительныеПараметры); - КонецЦикла; + ИмяПоля, + ЭлементОтбора.ВидСравнения + ); + ДополнительныеПараметры = Новый Структура("Значение", ЭлементОтбора.Значение); + ПроцессорКоллекций = ПроцессорКоллекций.Фильтровать(СтрокаУсловие, ДополнительныеПараметры); + КонецЦикла; + КонецЕсли; + + Если Сортировка <> Неопределено Тогда + СтрокаСортировка = ""; + Для Каждого ЭлементПорядка Из Сортировка Цикл + + НайденныеКолонки = Колонки.НайтиСтроки(Новый Структура("ИмяКолонки", ЭлементПорядка.ПутьКДанным)); + + Если НайденныеКолонки.Количество() = 0 Тогда + ИмяПоля = ЭлементПорядка.ПутьКДанным; + Иначе + ИмяПоля = НайденныеКолонки[0].ИмяПоля; + КонецЕсли; + ПорядокСортировки = ?(ЭлементПорядка.НаправлениеСортировки = НаправлениеСортировки.Возр, "ПрямойПорядок", "ОбратныйПорядок"); + + // формирование текста лямбды для сравнения элементов по нескольким полям + СтрокаСортировка = СтрокаСортировка + СтрШаблон( + "Сравнение = ПроцессорыКоллекцийСлужебный.СравнениеЗначений%1(Элемент1._Сущность.%2, Элемент2._Сущность.%2); + |Если Сравнение <> 0 Тогда + | Возврат Сравнение; + |КонецЕсли; + | + |", + ПорядокСортировки, + ИмяПоля + ); + + КонецЦикла; + + Если СтрокаСортировка <> "" Тогда + СтрокаСортировка = "(Элемент1, Элемент2) -> " + Символы.ПС + СтрокаСортировка + "Возврат Сравнение;"; + + ПроцессорКоллекций = ПроцессорКоллекций.Сортировать(СтрокаСортировка); + КонецЕсли; + КонецЕсли; ДанныеТаблицы = ПроцессорКоллекций.ВМассив(); diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" index f2b9300..5a62318 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" @@ -184,7 +184,7 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор = Неопределено, Сортировка = Неопределено) Экспорт НайденныеСтроки = Новый Массив; @@ -195,15 +195,52 @@ ПроцессорКоллекций = ПроцессорыКоллекций.ИзКоллекции(Таблица); - Для Каждого ЭлементОтбора Из Отбор Цикл - СтрокаУсловие = СтрШаблон( + Если Отбор <> Неопределено Тогда + Для Каждого ЭлементОтбора Из Отбор Цикл + СтрокаУсловие = СтрШаблон( "Элемент -> Элемент.Значение.Получить(""%1"") %2 Значение", - ЭлементОтбора.ПутьКДанным, - ЭлементОтбора.ВидСравнения - ); - ДополнительныеПараметры = Новый Структура("Значение", ЭлементОтбора.Значение); - ПроцессорКоллекций = ПроцессорКоллекций.Фильтровать(СтрокаУсловие, ДополнительныеПараметры); - КонецЦикла; + ЭлементОтбора.ПутьКДанным, + ЭлементОтбора.ВидСравнения + ); + ДополнительныеПараметры = Новый Структура("Значение", ЭлементОтбора.Значение); + ПроцессорКоллекций = ПроцессорКоллекций.Фильтровать(СтрокаУсловие, ДополнительныеПараметры); + КонецЦикла; + КонецЕсли; + + Если Сортировка <> Неопределено Тогда + Колонки = ОбъектМодели.Колонки(); + СтрокаСортировка = ""; + Для Каждого ЭлементПорядка Из Сортировка Цикл + + НайденныеКолонки = Колонки.НайтиСтроки(Новый Структура("ИмяКолонки", ЭлементПорядка.ПутьКДанным)); + + Если НайденныеКолонки.Количество() = 0 Тогда + ИмяПоля = ЭлементПорядка.ПутьКДанным; + Иначе + ИмяПоля = НайденныеКолонки[0].ИмяПоля; + КонецЕсли; + ПорядокСортировки = ?(ЭлементПорядка.НаправлениеСортировки = НаправлениеСортировки.Возр, "ПрямойПорядок", "ОбратныйПорядок"); + + // формирование текста лямбды для сравнения элементов по нескольким полям + СтрокаСортировка = СтрокаСортировка + СтрШаблон( + "Сравнение = ПроцессорыКоллекцийСлужебный.СравнениеЗначений%1(Элемент1.Значение.Получить(""%2""), Элемент2.Значение.Получить(""%2"")); + |Если Сравнение <> 0 Тогда + | Возврат Сравнение; + |КонецЕсли; + | + |", + ПорядокСортировки, + ИмяПоля + ); + + КонецЦикла; + + Если СтрокаСортировка <> "" Тогда + СтрокаСортировка = "(Элемент1, Элемент2) -> " + Символы.ПС + СтрокаСортировка + "Возврат Сравнение;"; + + ПроцессорКоллекций = ПроцессорКоллекций.Сортировать(СтрокаСортировка); + КонецЕсли; + КонецЕсли; ДанныеТаблицы = ПроцессорКоллекций.ВМассив(); diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" index 119e95d..777b026 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" @@ -238,9 +238,9 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор = Неопределено, Знач Сортировка = Неопределено) Экспорт - Возврат КоннекторSQL.НайтиСтрокиВТаблице(ОбъектМодели, Отбор); + Возврат КоннекторSQL.НайтиСтрокиВТаблице(ОбъектМодели, Отбор, Сортировка); КонецФункции diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" index 101f6a7..ff81d7c 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" @@ -187,9 +187,9 @@ // Массив - Массив, элементами которого являются "Соответствия". Ключом элемента соответствия является имя колонки, // значением элемента соответствия - значение колонки. // -Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор) Экспорт +Функция НайтиСтрокиВТаблице(ОбъектМодели, Знач Отбор = Неопределено, Знач Сортировка = Неопределено) Экспорт - Возврат КоннекторSQL.НайтиСтрокиВТаблице(ОбъектМодели, Отбор); + Возврат КоннекторSQL.НайтиСтрокиВТаблице(ОбъектМодели, Отбор, Сортировка); КонецФункции diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" index a189b96..5a9c99d 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" @@ -118,10 +118,10 @@ // Массив - Массив найденных сущностей. В качестве элементов массива выступают // экземпляры класса с типом, равным переданному "ТипуСущности", с заполненными значениями полей. // -Функция Получить(ТипСущности, Отбор = Неопределено) Экспорт +Функция Получить(ТипСущности, Отбор = Неопределено, Сортировка = Неопределено) Экспорт ОбъектМодели = МодельДанных.Получить(ТипСущности); ПулСущностей = ПолучитьПулСущностей(ТипСущности); - Возврат РаботаСКоннекторами.Получить(Коннектор, ОбъектМодели, ПулСущностей, Отбор); + Возврат РаботаСКоннекторами.Получить(Коннектор, ОбъектМодели, ПулСущностей, Отбор, Сортировка); КонецФункции // Осуществляет поиск сущности переданного типа по идентификатору. diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\237\320\276\321\200\321\217\320\264\320\272\320\260.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\237\320\276\321\200\321\217\320\264\320\272\320\260.os" new file mode 100644 index 0000000..e73488b --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\237\320\276\321\200\321\217\320\264\320\272\320\260.os" @@ -0,0 +1,7 @@ +Перем ПутьКДанным Экспорт; +Перем НаправлениеСортировки Экспорт; + +Процедура ПриСозданииОбъекта(ППутьКДанным, ПНаправлениеСортировки = Неопределено) + ПутьКДанным = ППутьКДанным; + НаправлениеСортировки = ПНаправлениеСортировки; +КонецПроцедуры \ No newline at end of file diff --git "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" index c345ac2..612aba2 100644 --- "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" +++ "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200InMemory.os" @@ -253,4 +253,45 @@ Ожидаем.Что(Результат[0].Имя).Равно("1"); -КонецПроцедуры \ No newline at end of file +КонецПроцедуры + +&Тест +Процедура СортировкаПоДвумКолонкам() Экспорт + + // Дано + МодельДанных = Новый МодельДанных(); + ОбъектМодели = МодельДанных.СоздатьОбъектМодели(Тип("СущностьСоВсемиТипамиКолонок")); + Коннектор.ИнициализироватьТаблицу(ОбъектМодели); + + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + Сущность1.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + Сущность2.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность2); + + Сущность3 = Новый СущностьСоВсемиТипамиКолонок; + Сущность3.Целое = 3; + Сущность3.ДатаВремя = Дата(2019, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность3); + + // Когда + МассивСортировок = Новый Массив(); + МассивСортировок.Добавить(Новый ЭлементПорядка("ДатаВремя", НаправлениеСортировки.Возр)); + МассивСортировок.Добавить(Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв)); + + НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, , МассивСортировок); + + // Тогда + Ожидаем.Что(НайденныеСтроки, "Все строки получены").ИмеетДлину(3); + Ожидаем.Что(НайденныеСтроки[0].Получить("Целое"), "Строки отсортированы по полю").Равно(2); + Ожидаем.Что(НайденныеСтроки[1].Получить("Целое"), "Строки отсортированы по полю").Равно(1); + Ожидаем.Что(НайденныеСтроки[2].Получить("Целое"), "Строки отсортированы по полю").Равно(3); + +КонецПроцедуры + +ПередЗапускомТеста(); +СортировкаПоДвумКолонкам(); diff --git "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" index 9752a8f..0f0ec00 100644 --- "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" +++ "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200JSON.os" @@ -239,4 +239,42 @@ Ожидаем.Что(НайденныйПростойОбъект.Идентификатор).Равно("1"); Ожидаем.Что(НайденныйПростойОбъект.Поле).Равно("2"); -КонецПроцедуры \ No newline at end of file +КонецПроцедуры + +&Тест +Процедура СортировкаПоДвумКолонкам() Экспорт + + // Дано + МодельДанных = Новый МодельДанных(); + ОбъектМодели = МодельДанных.СоздатьОбъектМодели(Тип("СущностьСоВсемиТипамиКолонок")); + Коннектор.ИнициализироватьТаблицу(ОбъектМодели); + + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + Сущность1.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + Сущность2.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность2); + + Сущность3 = Новый СущностьСоВсемиТипамиКолонок; + Сущность3.Целое = 3; + Сущность3.ДатаВремя = Дата(2019, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность3); + + // Когда + МассивСортировок = Новый Массив(); + МассивСортировок.Добавить(Новый ЭлементПорядка("ДатаВремя", НаправлениеСортировки.Возр)); + МассивСортировок.Добавить(Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв)); + + НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, , МассивСортировок); + + // Тогда + Ожидаем.Что(НайденныеСтроки, "Все строки получены").ИмеетДлину(3); + Ожидаем.Что(НайденныеСтроки[0].Получить("Целое"), "Строки отсортированы по полю").Равно(2); + Ожидаем.Что(НайденныеСтроки[1].Получить("Целое"), "Строки отсортированы по полю").Равно(1); + Ожидаем.Что(НайденныеСтроки[2].Получить("Целое"), "Строки отсортированы по полю").Равно(3); + +КонецПроцедуры diff --git "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" index e6f495f..c2e7dfd 100644 --- "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" +++ "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200PostgreSQL.os" @@ -265,3 +265,41 @@ Ожидаем.Что(РезультатЗапроса, "Сущность удалилась").ИмеетДлину(0); КонецПроцедуры + +&Тест +Процедура СортировкаПоДвумКолонкам() Экспорт + + // Дано + МодельДанных = Новый МодельДанных(); + ОбъектМодели = МодельДанных.СоздатьОбъектМодели(Тип("СущностьСоВсемиТипамиКолонок")); + Коннектор.ИнициализироватьТаблицу(ОбъектМодели); + + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + Сущность1.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + Сущность2.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность2); + + Сущность3 = Новый СущностьСоВсемиТипамиКолонок; + Сущность3.Целое = 3; + Сущность3.ДатаВремя = Дата(2019, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность3); + + // Когда + МассивСортировок = Новый Массив(); + МассивСортировок.Добавить(Новый ЭлементПорядка("ДатаВремя", НаправлениеСортировки.Возр)); + МассивСортировок.Добавить(Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв)); + + НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, , МассивСортировок); + + // Тогда + Ожидаем.Что(НайденныеСтроки, "Все строки получены").ИмеетДлину(3); + Ожидаем.Что(НайденныеСтроки[0].Получить("Целое"), "Строки отсортированы по полю").Равно(2); + Ожидаем.Что(НайденныеСтроки[1].Получить("Целое"), "Строки отсортированы по полю").Равно(1); + Ожидаем.Что(НайденныеСтроки[2].Получить("Целое"), "Строки отсортированы по полю").Равно(3); + +КонецПроцедуры diff --git "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" index e38ef2b..b223810 100644 --- "a/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" +++ "b/tests/\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200SQLite.os" @@ -249,6 +249,44 @@ КонецПроцедуры +&Тест +Процедура СортировкаПоДвумКолонкам() Экспорт + + // Дано + МодельДанных = Новый МодельДанных(); + ОбъектМодели = МодельДанных.СоздатьОбъектМодели(Тип("СущностьСоВсемиТипамиКолонок")); + Коннектор.ИнициализироватьТаблицу(ОбъектМодели); + + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + Сущность1.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + Сущность2.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность2); + + Сущность3 = Новый СущностьСоВсемиТипамиКолонок; + Сущность3.Целое = 3; + Сущность3.ДатаВремя = Дата(2019, 1, 1, 0, 0, 0); + Коннектор.Сохранить(ОбъектМодели, Сущность3); + + // Когда + МассивСортировок = Новый Массив(); + МассивСортировок.Добавить(Новый ЭлементПорядка("ДатаВремя", НаправлениеСортировки.Возр)); + МассивСортировок.Добавить(Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв)); + + НайденныеСтроки = Коннектор.НайтиСтрокиВТаблице(ОбъектМодели, , МассивСортировок); + + // Тогда + Ожидаем.Что(НайденныеСтроки, "Все строки получены").ИмеетДлину(3); + Ожидаем.Что(НайденныеСтроки[0].Получить("Целое"), "Строки отсортированы по полю").Равно(2); + Ожидаем.Что(НайденныеСтроки[1].Получить("Целое"), "Строки отсортированы по полю").Равно(1); + Ожидаем.Что(НайденныеСтроки[2].Получить("Целое"), "Строки отсортированы по полю").Равно(3); + +КонецПроцедуры + // TODO: Больше тестов на непосредственно коннектор // ПередЗапускомТеста(); // Сохранить(); diff --git "a/tests/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" "b/tests/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" index 59d39c9..6e13c88 100644 --- "a/tests/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" +++ "b/tests/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" @@ -600,4 +600,68 @@ КонецПроцедуры +&Тест +Процедура СортировкаПоКолонке() Экспорт + + // Дано + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + МенеджерСущностей.Сохранить(Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + МенеджерСущностей.Сохранить(Сущность2); + + // Когда + Сущности = МенеджерСущностей.Получить( + Тип("СущностьСоВсемиТипамиКолонок"), + , + Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв) + ); + + // Тогда + Ожидаем.Что(Сущности, "Все сущности получены").ИмеетДлину(2); + Ожидаем.Что(Сущности[0].Целое, "Сущности отсортированы по полю").Равно(2); + Ожидаем.Что(Сущности[1].Целое, "Сущности отсортированы по полю").Равно(1); + +КонецПроцедуры + +&Тест +Процедура СортировкаПоДвумКолонкам() Экспорт + + // Дано + Сущность1 = Новый СущностьСоВсемиТипамиКолонок; + Сущность1.Целое = 1; + Сущность1.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + МенеджерСущностей.Сохранить(Сущность1); + + Сущность2 = Новый СущностьСоВсемиТипамиКолонок; + Сущность2.Целое = 2; + Сущность2.ДатаВремя = Дата(2018, 1, 1, 0, 0, 0); + МенеджерСущностей.Сохранить(Сущность2); + + Сущность3 = Новый СущностьСоВсемиТипамиКолонок; + Сущность3.Целое = 3; + Сущность3.ДатаВремя = Дата(2019, 1, 1, 0, 0, 0); + МенеджерСущностей.Сохранить(Сущность3); + + // Когда + МассивСортировок = Новый Массив(); + МассивСортировок.Добавить(Новый ЭлементПорядка("ДатаВремя", НаправлениеСортировки.Возр)); + МассивСортировок.Добавить(Новый ЭлементПорядка("Целое", НаправлениеСортировки.Убыв)); + + Сущности = МенеджерСущностей.Получить( + Тип("СущностьСоВсемиТипамиКолонок"), + , + МассивСортировок + ); + + // Тогда + Ожидаем.Что(Сущности, "Все сущности получены").ИмеетДлину(3); + Ожидаем.Что(Сущности[0].Целое, "Сущности отсортированы по полю").Равно(2); + Ожидаем.Что(Сущности[1].Целое, "Сущности отсортированы по полю").Равно(1); + Ожидаем.Что(Сущности[2].Целое, "Сущности отсортированы по полю").Равно(3); + +КонецПроцедуры + // TODO: Переписать тесты с проверки на записи в таблице БД на вызов методов поиска, когда они будут реализованы