Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions docs/МенеджерСущностей.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
```bsl
// Регистрирует переданный тип класса-сценария в модели данных.
//
// Повторная регистрация типа модель не меняет: остается прежний объект модели, с которым уже
// работают хранилища. Регистрировать классы можно и после передачи менеджера другим потокам, но
// таблицы создает Инициализировать, поэтому обычно классы регистрируют до него.
//
// Параметры:
// ТипСущности - Тип - Тип для добавления в модель
//
Expand Down
32 changes: 29 additions & 3 deletions docs/МодельДанных.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## МодельДанных

Модель общая у всех потоков, работающих с менеджером: операции читают ее на каждом шаге, а классы
можно регистрировать и после передачи менеджера другим потокам.

### ПриСозданииОбъекта

```bsl
Expand All @@ -10,21 +13,44 @@
### Получить

```bsl

// Возвращает объект модели типа сущности.
//
// Параметры:
// ТипСущности - Тип - Тип сущности.
//
// Возвращаемое значение:
// ОбъектМодели - Объект модели типа.
// Неопределено - Тип не зарегистрирован в модели.
//
Функция Получить(ТипСущности) Экспорт
```

### ПолучитьОбъектыМодели

```bsl

// Возвращает объекты модели всех зарегистрированных типов.
//
// Возвращаемое значение:
// Массив из ОбъектМодели - Копия на момент вызова: типы, зарегистрированные позже, в нее не
// попадут.
//
Функция ПолучитьОбъектыМодели() Экспорт
```

### СоздатьОбъектМодели

```bsl

// Регистрирует тип сущности в модели.
//
// Если тип уже зарегистрирован, возвращается существующий объект модели: с ним уже могут работать
// хранилища и операции других потоков, поэтому он не подменяется.
//
// Параметры:
// ТипСущности - Тип - Тип сущности.
//
// Возвращаемое значение:
// ОбъектМодели - Объект модели типа.
//
Функция СоздатьОбъектМодели(ТипСущности) Экспорт
```

19 changes: 10 additions & 9 deletions docs/ОбъектМодели.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
### ПриСозданииОбъекта

```bsl

Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных)
// Создает объект модели по аннотациям класса сущности.
//
// Параметры:
// ПТипСущности - Тип - Тип класса сущности.
// ПМодельДанных - МодельДанных - Модель, к которой относится объект.
// ПИмяТаблицы - Строка - Имя таблицы вместо имени из аннотации класса. Так создаются объекты
// модели подчиненных таблиц: класс элемента у них один, а таблицы разные.
// - Неопределено - Имя таблицы берется из аннотации класса.
//
Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных, ПИмяТаблицы = Неопределено)
```

### ИмяТаблицы
Expand Down Expand Up @@ -32,13 +40,6 @@
Функция ПодчиненныеТаблицы() Экспорт
```

### Служебный_ИмяТаблицы

```bsl
// @internal
Процедура Служебный_ИмяТаблицы(ПИмяТаблицы) Экспорт
```

### Идентификатор

```bsl
Expand Down
7 changes: 6 additions & 1 deletion docs/ТипыКолонок.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
* Время
* ДатаВремя
* Ссылка
* ДвоичныеДанные

### Типы

```bsl

// Возвращает все типы колонок модели.
//
// Возвращаемое значение:
// ФиксированныйМассив из Строка - Имена типов колонок.
//
Функция Типы() Экспорт
```

Expand Down
6 changes: 5 additions & 1 deletion docs/ТипыПодчиненныхТаблиц.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
### Типы

```bsl

// Возвращает все типы подчиненных таблиц.
//
// Возвращаемое значение:
// ФиксированныйМассив из Строка - Имена типов подчиненных таблиц.
//
Функция Типы() Экспорт
```

2 changes: 1 addition & 1 deletion packagedef
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
.ЗависитОт("annotations", "1.6.0")
.ЗависитОт("asserts", "1.6.2")
.ЗависитОт("atomic", "0.1.1")
.ЗависитОт("collectionos", "0.8.4")
.ЗависитОт("collectionos", "0.9.0")
.ЗависитОт("fluent", "0.6.1")
.ЗависитОт("fs", "1.2.0")
.ЗависитОт("lambdas", "0.3.5")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@

ОбъектМоделиЭлементКоллекции = Новый ОбъектМодели(
Тип("СлужебнаяСущность_ЭлементКоллекцииКлючЗначение"),
РодительскийОбъектМодели.МодельДанных()
РодительскийОбъектМодели.МодельДанных(),
ПодчиненнаяТаблица.ИмяТаблицы
);

ОбъектМоделиЭлементКоллекции.Служебный_ИмяТаблицы(ПодчиненнаяТаблица.ИмяТаблицы);
// Колонки модели только для чтения, но этот объект модели только что создан и еще никому не отдан.
КолонкиОбъектаМодели = ОбъектМоделиЭлементКоллекции.Колонки();

Expand Down
4 changes: 4 additions & 0 deletions src/Классы/МенеджерСущностей.os
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@

// Регистрирует переданный тип класса-сценария в модели данных.
//
// Повторная регистрация типа модель не меняет: остается прежний объект модели, с которым уже
// работают хранилища. Регистрировать классы можно и после передачи менеджера другим потокам, но
// таблицы создает Инициализировать, поэтому обычно классы регистрируют до него.
//
// Параметры:
// ТипСущности - Тип - Тип для добавления в модель
//
Expand Down
50 changes: 40 additions & 10 deletions src/Классы/МодельДанных.os
Original file line number Diff line number Diff line change
@@ -1,25 +1,55 @@
#Использовать collectionos

// КартаКопированиеПриЗаписи - Тип сущности: ее объект модели. Модель общая у всех потоков, работающих
// с менеджером: операции читают ее на каждом шаге, а меняется она только при регистрации класса.
Перем ХранилищеМодели;

Процедура ПриСозданииОбъекта()
ХранилищеМодели = Новый Соответствие;
ХранилищеМодели = Новый КартаКопированиеПриЗаписи();
КонецПроцедуры

// Возвращает объект модели типа сущности.
//
// Параметры:
// ТипСущности - Тип - Тип сущности.
//
// Возвращаемое значение:
// ОбъектМодели - Объект модели типа.
// Неопределено - Тип не зарегистрирован в модели.
//
Функция Получить(ТипСущности) Экспорт
Возврат ХранилищеМодели.Получить(ТипСущности);
Возврат ХранилищеМодели.ПолучитьИлиУмолчание(ТипСущности, Неопределено);
КонецФункции

// Возвращает объекты модели всех зарегистрированных типов.
//
// Возвращаемое значение:
// Массив из ОбъектМодели - Копия на момент вызова: типы, зарегистрированные позже, в нее не
// попадут.
//
Функция ПолучитьОбъектыМодели() Экспорт
ВсеОбъектыМодели = Новый Массив;
Для Каждого КлючИЗначение Из ХранилищеМодели Цикл
ВсеОбъектыМодели.Добавить(КлючИЗначение.Значение);
КонецЦикла;

Возврат ВсеОбъектыМодели;

Возврат ХранилищеМодели.Значения().ВМассив();

КонецФункции

// Регистрирует тип сущности в модели.
//
// Если тип уже зарегистрирован, возвращается существующий объект модели: с ним уже могут работать
// хранилища и операции других потоков, поэтому он не подменяется.
//
// Параметры:
// ТипСущности - Тип - Тип сущности.
//
// Возвращаемое значение:
// ОбъектМодели - Объект модели типа.
//
Функция СоздатьОбъектМодели(ТипСущности) Экспорт

// Объект строится вне карты: конструктор разбирает аннотации класса, и держать на это время
// блокировку изменения карты незачем.
ОбъектМодели = Новый ОбъектМодели(ТипСущности, ЭтотОбъект);
ХранилищеМодели.Вставить(ТипСущности, ОбъектМодели);

Возврат ОбъектМодели;
Возврат ХранилищеМодели.ВставитьЕслиОтсутствует(ТипСущности, ОбъектМодели).Иначе_(ОбъектМодели);

КонецФункции
20 changes: 14 additions & 6 deletions src/Классы/ОбъектМодели.os
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@

Перем Рефлектор;

Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных)
// Создает объект модели по аннотациям класса сущности.
//
// Параметры:
// ПТипСущности - Тип - Тип класса сущности.
// ПМодельДанных - МодельДанных - Модель, к которой относится объект.
// ПИмяТаблицы - Строка - Имя таблицы вместо имени из аннотации класса. Так создаются объекты

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

ну-ка подробнее, как оно работает на релизной версии с примерами разных типов подчиненных таблиц, и как оно работает после этой правки.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Поведение не меняется. Ниже — как это работает на релизе v5.4.0.2 и что поменяла правка; проверено одним сценарием на релизе и на ветке.

Как сейчас (v5.4.0.2)

  1. Родительский ОбъектМодели в ЗаполнитьПодчиненныеТаблицы описывает каждое поле с &ПодчиненнаяТаблица:

    • имя таблицы — ИмяТаблицы из аннотации, а без него Строка(ТипСущности) + "_" + ИмяПоля;
    • Тип — Массив или Структура, плюс ТипЭлемента и КаскадноеЧтение.
  2. Для записи, чтения и Инициализировать ОбработкаКоллекций.ПолучитьОбъектМоделиДляПодчиненнойТаблицы каждый раз строит новый ОбъектМодели служебного класса СлужебнаяСущность_ЭлементКоллекцииКлючЗначение (колонки id, ref, key, value). Конструктор берёт имя таблицы из &Сущность служебного класса — СлужебнаяСущность_ЭлементКоллекцииКлючЗначение.

  3. Затем Служебный_ИмяТаблицы(ПодчиненнаяТаблица.ИмяТаблицы) подменяет имя таблицы, и Колонки() этого свежего объекта донастраиваются:

    • key — Целое для массива и Строка для структуры;
    • у ref ТипСсылки — тип родителя;
    • value — примитивный тип элемента либо Ссылка на класс элемента.

    Объект никому не передан, поэтому эти правки контракт не нарушают.

Что изменилось. Имя таблицы передаётся третьим параметром конструктора и присваивается в его конце, то есть там же, где раньше его ставил Служебный_ИмяТаблицы сразу после конструктора. После ЗаполнитьКолонки конструктор ИмяТаблицы не читает: имя подчинённых таблиц по умолчанию собирается из ТипСущности. Поэтому результат тот же. Ушёл только экспортный мутатор, через который имя таблицы можно было поменять у уже опубликованного объекта модели.

Примеры. Это СущностьСоВсемиТипамиКолонок из фикстур и класс Заказ с таблицей Заказы и тремя подчинёнными таблицами без ИмяТаблицы (массив Целое, структура Дата, массив ссылок). SQLite, сохранение и чтение. Вывод на v5.4.0.2 и на ветке совпадает строка в строку, на 2.2.0 и на 2.3.0-next:

СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок)
  Массив: Массив из Строка -> таблица ВсеТипыКолонок_Массив; key Целое; ref Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок); value Строка
  Структура: Структура из Строка -> таблица ВсеТипыКолонок_Структура; key Строка; ref Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок); value Строка
  МассивСсылок: Массив из СущностьСоВсемиТипамиКолонок -> таблица ВсеТипыКолонок_МассивСсылок; key Целое; ref Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок); value Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок)
  МассивСсылокКаскад: Массив из СущностьСоВсемиТипамиКолонок, каскадно -> таблица ВсеТипыКолонок_МассивСсылокКаскад; key Целое; ref Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок); value Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок)
Заказ (таблица Заказы)
  Числа: Массив из Целое -> таблица Заказ_Числа; key Целое; ref Ссылка -> Заказ (таблица Заказы); value Целое
  Сроки: Структура из Дата -> таблица Заказ_Сроки; key Строка; ref Ссылка -> Заказ (таблица Заказы); value Дата
  Позиции: Массив из СущностьСоВсемиТипамиКолонок -> таблица Заказ_Позиции; key Целое; ref Ссылка -> Заказ (таблица Заказы); value Ссылка -> СущностьСоВсемиТипамиКолонок (таблица СущностьСоВсемиТипамиКолонок)
Таблицы в БД: sqlite_sequence, ВсеТипыКолонок_Массив, ВсеТипыКолонок_МассивСсылок, ВсеТипыКолонок_МассивСсылокКаскад, ВсеТипыКолонок_Структура, Заказ_Позиции, Заказ_Сроки, Заказ_Числа, Заказы, СущностьСоВсемиТипамиКолонок
Заказ_Числа: (1, 0, 30) (1, 1, 10) (1, 2, 20)
Заказ_Сроки: (1, Начало, 01.10.2026 0:00:00) (1, Конец, 07.10.2026 0:00:00)
Заказ_Позиции: (1, 0, 7)
Прочитано: Числа = 30, 10, 20; Сроки = 01.10.2026 .. 07.10.2026; Позиции[0] = 7 (Число)

Попутно заметил расхождение, которое было и до этого PR. Описание аннотации ПодчиненнаяТаблица обещает имя по умолчанию ИмяТаблицыСущности_ИмяСвойства, а код берёт имя класса: у Заказ с таблицей Заказы получается Заказ_Числа, а не Заказы_Числа. Здесь я это не трогал. Что поправить — описание или поведение?

// модели подчиненных таблиц: класс элемента у них один, а таблицы разные.
// - Неопределено - Имя таблицы берется из аннотации класса.
//
Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных, ПИмяТаблицы = Неопределено)

МодельДанных = ПМодельДанных;
ТипСущности = ПТипСущности;
Expand All @@ -27,6 +36,10 @@
ЗаполнитьПодчиненныеТаблицы();
Рефлектор = Новый Рефлектор;

Если ПИмяТаблицы <> Неопределено Тогда
ИмяТаблицы = ПИмяТаблицы;
КонецЕсли;

КонецПроцедуры

Функция ИмяТаблицы() Экспорт
Expand All @@ -50,11 +63,6 @@
Возврат ПодчиненныеТаблицы.Скопировать();
КонецФункции

// @internal
Процедура Служебный_ИмяТаблицы(ПИмяТаблицы) Экспорт
ИмяТаблицы = ПИмяТаблицы;
КонецПроцедуры

Функция Идентификатор() Экспорт
Возврат Идентификатор;
КонецФункции
Expand Down
47 changes: 28 additions & 19 deletions src/Модули/ТипыКолонок.os
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@
Перем Ссылка Экспорт;
Перем ДвоичныеДанные Экспорт;

// ФиксированныйМассив из Строка - Все типы колонок.
Перем Типы;
// ФиксированныйМассив из Строка - Примитивные типы колонок.
Перем ПримитивныеТипы;

// Возвращает все типы колонок модели.
//
// Возвращаемое значение:
// ФиксированныйМассив из Строка - Имена типов колонок.
//
Функция Типы() Экспорт
Возврат Типы;
КонецФункции
Expand Down Expand Up @@ -68,23 +75,25 @@
Ссылка = "Ссылка";
ДвоичныеДанные = "ДвоичныеДанные";

Типы = Новый Массив;
Типы.Добавить(Целое);
Типы.Добавить(Дробное);
Типы.Добавить(Булево);
Типы.Добавить(Строка);
Типы.Добавить(Дата);
Типы.Добавить(Время);
Типы.Добавить(ДатаВремя);
Типы.Добавить(Ссылка);
Типы.Добавить(ДвоичныеДанные);
ВсеТипы = Новый Массив;
ВсеТипы.Добавить(Целое);
ВсеТипы.Добавить(Дробное);
ВсеТипы.Добавить(Булево);
ВсеТипы.Добавить(Строка);
ВсеТипы.Добавить(Дата);
ВсеТипы.Добавить(Время);
ВсеТипы.Добавить(ДатаВремя);
ВсеТипы.Добавить(Ссылка);
ВсеТипы.Добавить(ДвоичныеДанные);
Типы = Новый ФиксированныйМассив(ВсеТипы);

ПримитивныеТипы = Новый Массив;
ПримитивныеТипы.Добавить(Целое);
ПримитивныеТипы.Добавить(Дробное);
ПримитивныеТипы.Добавить(Булево);
ПримитивныеТипы.Добавить(Строка);
ПримитивныеТипы.Добавить(Дата);
ПримитивныеТипы.Добавить(Время);
ПримитивныеТипы.Добавить(ДатаВремя);
ПримитивныеТипы.Добавить(ДвоичныеДанные);
Примитивные = Новый Массив;
Примитивные.Добавить(Целое);
Примитивные.Добавить(Дробное);
Примитивные.Добавить(Булево);
Примитивные.Добавить(Строка);
Примитивные.Добавить(Дата);
Примитивные.Добавить(Время);
Примитивные.Добавить(ДатаВремя);
Примитивные.Добавить(ДвоичныеДанные);
ПримитивныеТипы = Новый ФиксированныйМассив(Примитивные);
13 changes: 10 additions & 3 deletions src/Модули/ТипыПодчиненныхТаблиц.os
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
Перем Массив Экспорт;
Перем Структура Экспорт;

// ФиксированныйМассив из Строка - Все типы подчиненных таблиц.
Перем Типы;

// Возвращает все типы подчиненных таблиц.
//
// Возвращаемое значение:
// ФиксированныйМассив из Строка - Имена типов подчиненных таблиц.
//
Функция Типы() Экспорт
Возврат Типы;
КонецФункции

Массив = "Массив";
Структура = "Структура";

Типы = Новый Массив;
Типы.Добавить(Массив);
Типы.Добавить(Структура);
ВсеТипы = Новый Массив;
ВсеТипы.Добавить(Массив);
ВсеТипы.Добавить(Структура);
Типы = Новый ФиксированныйМассив(ВсеТипы);
Loading
Loading