forked from nixel2007/entity
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathМенеджерСущностей.os
280 lines (239 loc) · 17.6 KB
/
МенеджерСущностей.os
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#Использовать "../Аннотации"
#Использовать "../internal"
#Использовать asserts
#Использовать logos
#Использовать reflector
// Хранит данные о типах полей, колонках, настроек таблиц для типов сущностей
Перем МодельДанных;
// Хранит коннектор к БД, транслирующий команды менеджера сущностей в запросы к БД
Перем Коннектор;
Перем СтрокаСоединенияКоннектора;
Перем ПараметрыКоннектора;
Перем Лог;
// Конструктор объекта МенеджерСущностей.
//
// Параметры:
// ТипКоннектора - Тип - Тип класса, реализующего интерфейс Коннектор.
// СтрокаСоединения - Строка - Строка соединения к БД, к которой подключается коннектор.
// ППараметрыКоннектора - Массив - Массив дополнительных параметров коннектора. Содержимое произвольное.
//
Процедура ПриСозданииОбъекта(Знач ТипКоннектора, Знач СтрокаСоединения = "", Знач ППараметрыКоннектора = Неопределено)
Лог = Логирование.ПолучитьЛог("oscript.lib.entity.manager");
Лог.Отладка("Инициализация менеджера сущностей с коннектором %1", ТипКоннектора);
ПроверитьПоддержкуИнтерфейсаКоннектора(ТипКоннектора);
МодельДанных = Новый МодельДанных;
Коннектор = РаботаСКоннекторами.СоздатьКоннектор(ТипКоннектора);
СтрокаСоединенияКоннектора = СтрокаСоединения;
Если ППараметрыКоннектора = Неопределено Тогда
ПараметрыКоннектора = Новый Массив;
Иначе
ПараметрыКоннектора = ППараметрыКоннектора;
КонецЕсли;
КонецПроцедуры
// Регистрирует переданный тип класса-сценария в модели данных.
//
// Параметры:
// ТипСущности - Тип - Тип для добавления в модель
//
Процедура ДобавитьКлассВМодель(ТипСущности) Экспорт
ПроверитьЧтоКлассЯвляетсяСущностью(ТипСущности);
МодельДанных.СоздатьОбъектМодели(ТипСущности);
КонецПроцедуры
// Получить модель данных - хранилище информации о типах полей, колонок, таблиц для типов сущостей.
//
// Возвращаемое значение:
// МодельДанных
//
Функция ПолучитьМодельДанных() Экспорт
Возврат МодельДанных;
КонецФункции
// Запускает процессы инициализации коннектора и таблиц БД.
//
Процедура Инициализировать() Экспорт
РаботаСКоннекторами.ОткрытьКоннектор(Коннектор, СтрокаСоединенияКоннектора, ПараметрыКоннектора);
ОбъектыМодели = МодельДанных.ПолучитьОбъектыМодели();
Для Каждого ОбъектМодели Из ОбъектыМодели Цикл
Коннектор.ИнициализироватьТаблицу(ОбъектМодели);
ПодчиненныеТаблицы = ОбъектМодели.ПодчиненныеТаблицы();
Для Каждого ПодчиненнаяТаблица Из ПодчиненныеТаблицы Цикл
ОбъектМоделиЭлементКоллекции = ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы(
ОбъектМодели,
ПодчиненнаяТаблица
);
Коннектор.ИнициализироватьТаблицу(ОбъектМоделиЭлементКоллекции);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
// Создает экземпляр сущности, расширенный методами паттерна Active Record.
//
// Параметры:
// ТипСущности - Тип - Тип создаваемой сущности.
//
// Возвращаемое значение:
// Произвольный - экземпляр класса сущности с типом, привязанным к переданному "ТипуСущности",
// с дополнительными методами паттерна Active Record.
//
Функция СоздатьЭлемент(ТипСущности) Экспорт
ОбъектМодели = МодельДанных.Получить(ТипСущности);
Возврат АктивнаяЗапись.СоздатьИзМенеджера(ОбъектМодели, ЭтотОбъект);
КонецФункции
// Сохраняет сущность в БД.
//
// Параметры:
// Сущность - Произвольный - Объект (экземпляр класса, зарегистрированного в модели) для сохранения в БД.
//
Процедура Сохранить(Сущность) Экспорт
ТипСущности = АктивнаяЗапись.ТипСущности(Сущность);
ОбъектМодели = МодельДанных.Получить(ТипСущности);
ПулСущностей = ПолучитьПулСущностей(ТипСущности);
РаботаСКоннекторами.Сохранить(Коннектор, ОбъектМодели, ПулСущностей, Сущность);
КонецПроцедуры
// Осуществляет поиск сущностей переданного типа по идентификатору.
//
// Параметры:
// ТипСущности - Тип - Тип искомой сущности.
// ОпцииПоиска - Произвольный - Опции поиска.
// Если параметр не задан или равен "Неопределено", то возвращаются все найденные сущности указанного типа.
// Если параметр имеет тип "Соответствие", то каждое значение соответствия преобразуется к условию поиска
// ИмяПоля = ЗначениеПоля, где ИмяПоля - ключ элемента соответствия, ЗначениеПоля - значение элемента соответствия.
// Если параметр имеет тип "ОпцииПоиска", то опции передаются как есть.
//
// Возвращаемое значение:
// Массив - Массив найденных сущностей. В качестве элементов массива выступают
// экземпляры класса с типом, равным переданному параметру "ТипСущности", с заполненными значениями полей.
//
Функция Получить(ТипСущности, Знач ОпцииПоиска = Неопределено) Экспорт
ОбъектМодели = МодельДанных.Получить(ТипСущности);
ПулСущностей = ПолучитьПулСущностей(ТипСущности);
Если ОпцииПоиска = Неопределено Тогда
ОпцииПоиска = Новый ОпцииПоиска;
КонецЕсли;
Возврат РаботаСКоннекторами.Получить(Коннектор, ОбъектМодели, ПулСущностей, ОпцииПоиска);
КонецФункции
// Осуществляет поиск сущности переданного типа по идентификатору.
//
// Параметры:
// ТипСущности - Тип - Тип искомой сущности.
// ОпцииПоиска - Произвольный - Опции поиска.
// Если параметр не задан или равен "Неопределено", то возвращаются все найденные сущности указанного типа.
// Если параметр имеет тип "Соответствие", то каждое значение соответствия преобразуется к условию поиска
// ИмяПоля = ЗначениеПоля, где ИмяПоля - ключ элемента соответствия, ЗначениеПоля - значение элемента соответствия.
// Если параметр имеет тип "ОпцииПоиска", то опции передаются как есть.
// Любой другой тип интерпретируется как поиск по &Идентификатору.
//
// Возвращаемое значение:
// Произвольный - Если сущность была найдена, то возвращается экземпляр класса с типом, равным переданному параметру
// "ТипСущности", с заполненными значениями полей. Иначе возвращается "Неопределено".
//
Функция ПолучитьОдно(ТипСущности, Знач ОпцииПоиска = Неопределено) Экспорт
ОбъектМодели = МодельДанных.Получить(ТипСущности);
ПулСущностей = ПолучитьПулСущностей(ТипСущности);
Если ОпцииПоиска = Неопределено Тогда
ОпцииПоиска = Новый ОпцииПоиска;
КонецЕсли;
Возврат РаботаСКоннекторами.ПолучитьОдно(Коннектор, ОбъектМодели, ПулСущностей, ОпцииПоиска);
КонецФункции
// Выполняет удаление сущности из базы данных.
// Сущность должна иметь заполненный идентификатор.
//
// Параметры:
// Сущность - Произвольный - Удаляемая сущность
//
Процедура Удалить(Сущность) Экспорт
ТипСущности = АктивнаяЗапись.ТипСущности(Сущность);
ОбъектМодели = МодельДанных.Получить(ТипСущности);
ПулСущностей = ПолучитьПулСущностей(ТипСущности);
РаботаСКоннекторами.Удалить(Коннектор, ОбъектМодели, ПулСущностей, Сущность);
КонецПроцедуры
// Выполняет очистку полную данных библиотеки.
// Дополнительно посылает всем используемым коннекторам запросы на закрытие соединения.
//
Процедура Закрыть() Экспорт
РаботаСКоннекторами.ЗакрытьКоннектор(Коннектор);
МодельДанных.Очистить();
СвойстваКоннектора = РаботаСКоннекторами.ПолучитьСвойстваКоннектора(Коннектор);
ХранилищаСущностей.Закрыть(ТипЗнч(Коннектор), СвойстваКоннектора.СтрокаСоединения, СвойстваКоннектора.Параметры);
// Для освобожения ссылок на все коннекторы и соединения с СУБД
ВыполнитьСборкуМусора();
КонецПроцедуры
// Посылает коннектору запрос на начало транзакции.
//
Процедура НачатьТранзакцию() Экспорт
РаботаСКоннекторами.НачатьТранзакцию(Коннектор);
КонецПроцедуры
// Посылает коннектору запрос на фиксацию транзакции.
//
Процедура ЗафиксироватьТранзакцию() Экспорт
РаботаСКоннекторами.ЗафиксироватьТранзакцию(Коннектор);
КонецПроцедуры
// Посылает коннектору запрос на отмену транзакции.
//
Процедура ОтменитьТранзакцию() Экспорт
РаботаСКоннекторами.ОтменитьТранзакцию(Коннектор);
КонецПроцедуры
// Возвращает текущий активный коннектор.
//
// Возвращаемое значение:
// АбстрактныйКоннектор - Возвращает экземпляр коннектора. Конкретная реализация определяется параметром
// ТипКоннектора при вызове конструктора МенеджерСущностей.
//
Функция ПолучитьКоннектор() Экспорт
Возврат Коннектор;
КонецФункции
// Получает ХранилищеСущностей, привязанное к переданному типу сущности.
//
// Параметры:
// ТипСущности - Тип - Тип сущности, зарегистрированный в Модели
//
// Возвращаемое значение:
// ХранилищеСущностей - Хранилище сущностей, привязанное к переданному типу сущности.
//
Функция ПолучитьХранилищеСущностей(ТипСущности) Экспорт
ОбъектМодели = МодельДанных.Получить(ТипСущности);
ХранилищеСущностей = ХранилищаСущностей.Получить(
ОбъектМодели,
Коннектор
);
Возврат ХранилищеСущностей;
КонецФункции
// @internal
// Для служебного пользования.
//
// Возвращает пул сущностей из хранилища сущностей, привязанного к переданному типу сущности.
//
// Параметры:
// ТипСущности - Тип - Тип сущности, зарегистрированный в Модели.
//
// Возвращаемое значение:
// Соответствие - Пул сущностей.
//
Функция ПолучитьПулСущностей(ТипСущности) Экспорт
Возврат ПолучитьХранилищеСущностей(ТипСущности).ПолучитьПулСущностей();
КонецФункции
// <Описание процедуры>
//
// Параметры:
// ТипКоннектора - Тип - Тип, проверяемый на реализацию интерфейса
//
Процедура ПроверитьПоддержкуИнтерфейсаКоннектора(ТипКоннектора)
ИнтерфейсКоннектор = Новый ИнтерфейсОбъекта;
ИнтерфейсКоннектор.ИзОбъекта(Тип("АбстрактныйКоннектор"));
РефлекторОбъекта = Новый РефлекторОбъекта(ТипКоннектора);
ПоддерживаетсяИнтерфейсКоннектора = РефлекторОбъекта.РеализуетИнтерфейс(ИнтерфейсКоннектор);
Ожидаем.Что(
ПоддерживаетсяИнтерфейсКоннектора,
СтрШаблон("Тип <%1> не реализует интерфейс коннектора", ТипКоннектора)
).ЭтоИстина();
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// ТипКласса - Тип - Тип, в котором проверяется наличие необходимых аннотаций.
//
Процедура ПроверитьЧтоКлассЯвляетсяСущностью(ТипКласса)
РефлекторОбъекта = Новый РефлекторОбъекта(ТипКласса);
ТаблицаМетодов = РефлекторОбъекта.ПолучитьТаблицуМетодов("Сущность", Ложь);
Ожидаем.Что(ТаблицаМетодов, СтрШаблон("Класс %1 не имеет аннотации &Сущность", ТипКласса)).ИмеетДлину(1);
ТаблицаСвойств = РефлекторОбъекта.ПолучитьТаблицуСвойств("Идентификатор");
Ожидаем.Что(ТаблицаСвойств, СтрШаблон("Класс %1 не имеет поля с аннотацией &Идентификатор", ТипКласса)).ИмеетДлину(1);
КонецПроцедуры