ПриПолученииДанныхОтГлавного (БСП)

Автор: 1С
ОбщийМодуль.ВерсионированиеОбъектов
БСП

При получении данных от главного. См. СтандартныеПодсистемыСервер.ПриПолученииДанныхОтГлавного.

// См. СтандартныеПодсистемыСервер.ПриПолученииДанныхОтГлавного.
Процедура ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель) Экспорт
	
	Если Отправитель = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(ЭлементДанных) = Тип("РегистрСведенийНаборЗаписей.ВерсииОбъектов") И ЭлементДанных.Количество() > 0 Тогда
		ПрочитатьИнформациюОбУзле(ЭлементДанных[0]);
		
		Объект = ЭлементДанных.Отбор.Объект.Значение;
		
		// Сопоставляем входящие номера версии и владельца версии с номерами в этой ИБ.
		ПорядковыйНомерСинхронизируемойВерсии = ЭлементДанных.Отбор.НомерВерсии.Значение - ЭлементДанных[0].Смещение;
		ПорядковыйНомерВерсииВладельца = ЭлементДанных[0].ВерсияВладелец;
		
		НомерВерсии = НомерВерсииВРегистре(Объект, ПорядковыйНомерСинхронизируемойВерсии);
		Если ЗначениеЗаполнено(ПорядковыйНомерВерсииВладельца) Тогда
			ЭлементДанных[0].ВерсияВладелец = НомерВерсииВРегистре(Объект, ПорядковыйНомерВерсииВладельца);
		КонецЕсли;
		
		// Сравниваем с имеющейся версией.
		НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.Объект.Установить(Объект);
		НаборЗаписей.Отбор.НомерВерсии.Установить(НомерВерсии);
		НаборЗаписей.Прочитать();
		
		Если ОбщегоНазначения.ЗначениеВСтрокуXML(ЭлементДанных) = ОбщегоНазначения.ЗначениеВСтрокуXML(НаборЗаписей) Тогда
			// Считаем, что нет коллизии.
			ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать;
			Возврат;
		КонецЕсли;
		
		ЕстьКоллизия = Объект.ПолучитьОбъект() <> Неопределено И ПланыОбмена.ИзменениеЗарегистрировано(Отправитель.Ссылка, Объект);
		
		ТипВерсииОбъекта = Перечисления.ТипыВерсийОбъекта.НепринятыеДанныеПоКоллизии;
		Если Отправитель.ДополнительныеСвойства.Свойство("НепринятыеПоДатеЗапрета")
			И Отправитель.ДополнительныеСвойства.НепринятыеПоДатеЗапрета[Объект] <> Неопределено Тогда
				ЕстьКоллизия = Истина;
				Если Отправитель.ДополнительныеСвойства.НепринятыеПоДатеЗапрета[Объект] = "НепринятыйПоДатеЗапретаОбъектСуществуетВБазе" Тогда
					ТипВерсииОбъекта = Перечисления.ТипыВерсийОбъекта.НепринятыйПоДатеЗапретаОбъектСуществуетВБазе;
				Иначе
					ТипВерсииОбъекта = Перечисления.ТипыВерсийОбъекта.НепринятыйПоДатеЗапретаОбъектНеСуществуетВБазе;
				КонецЕсли;
		КонецЕсли;
		
		// Проверяем отмечена ли эта же версия к выгрузке.
		ВерсииКВыгрузке = ВерсииКВыгрузке(Объект, Отправитель.Ссылка);
		Для Каждого ВерсияКВыгрузке Из ВерсииКВыгрузке Цикл
			Если ВерсияКВыгрузке.НомерВерсии = НомерВерсии Тогда
				ЕстьКоллизия = Истина;
			КонецЕсли;
		КонецЦикла;
		
		// Записываем полученную версию, меняем ее номер с учетом несинхронизируемых версий.
		Если Не ЕстьКоллизия Тогда
			// Если объект не был изменен, то версия перезаписывается без проверки, так как неизвестно,
			// был ли изменен объект в узле-отправителе.
			Если НаборЗаписей.Количество() = 0 Тогда
				Запись = НаборЗаписей.Добавить();
				Запись.Объект = Объект;
				Запись.НомерВерсии = НомерВерсии;
			Иначе
				Запись = НаборЗаписей[0];
			КонецЕсли;
			ЗаполнитьЗначенияСвойств(Запись, ЭлементДанных[0], , "Объект,НомерВерсии");
			НаборЗаписей.Записать();
			ПланыОбмена.УдалитьРегистрациюИзменений(Отправитель.Ссылка, НаборЗаписей);
			ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать;
			Возврат;
		КонецЕсли;
		
		// Сохраняем данные последней записанной версии.
		НомерПоследнейВерсии = НомерПоследнейВерсии(Объект);
		ПоследняяВерсия = РегистрыСведений.ВерсииОбъектов.СоздатьМенеджерЗаписи();
		ПоследняяВерсия.Объект = Объект;
		ПоследняяВерсия.НомерВерсии = НомерПоследнейВерсии;
		ПоследняяВерсия.Прочитать();
		Если Не ПоследняяВерсия.ЕстьДанныеВерсии Тогда
			ПоследняяВерсия.ВерсияОбъекта = Новый ХранилищеЗначения(ДанныеДляХранения(Объект), Новый СжатиеДанных(9));
			ПоследняяВерсия.Записать();
		КонецЕсли;
		
		Если ВерсииКВыгрузке.Количество() = 0 Тогда 
			ЗаписатьВерсиюСИзменениемНомера(ЭлементДанных, ПолучениеЭлемента, Отправитель, НомерВерсии);
			Возврат;
		КонецЕсли;
		
		// Сдвигаем все зарегистрированные к отправке версии для вставки версии из главного узла.
		
		Для Каждого ОписаниеВерсии Из ВерсииКВыгрузке Цикл
			Если ОписаниеВерсии.НомерВерсии >= НомерВерсии Тогда
				НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
				НаборЗаписей.Отбор.Объект.Установить(Объект);
				НаборЗаписей.Отбор.НомерВерсии.Установить(ОписаниеВерсии.НомерВерсии);
				НаборЗаписей.Прочитать();
				ПланыОбмена.УдалитьРегистрациюИзменений(Отправитель.Ссылка, НаборЗаписей);
			КонецЕсли;
		КонецЦикла;
		
		КоллизииВерсийОбъектов = Новый Соответствие;
		Если Отправитель.ДополнительныеСвойства.Свойство("КоллизииВерсийОбъектов") Тогда
			КоллизииВерсийОбъектов = Отправитель.ДополнительныеСвойства.КоллизииВерсийОбъектов;
		Иначе
			Отправитель.ДополнительныеСвойства.Вставить("КоллизииВерсийОбъектов", КоллизииВерсийОбъектов);
		КонецЕсли;
		
		// Запоминаем версию, которая будет использована в качестве владельца непринятых.
		НомерВерсииСКоллизией = КоллизииВерсийОбъектов[Объект];
		СдвигНомераВерсии = 1;
		УстановитьВладельцаНепринятыхВерсий = Ложь;
		Если НомерВерсииСКоллизией = Неопределено Тогда
			СдвигНомераВерсии = 2;
			НомерВерсииСКоллизией = НомерВерсии + 1;
			УстановитьВладельцаНепринятыхВерсий = Истина;
		КонецЕсли;
		
		НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.Объект.Установить(Объект);
		НаборЗаписей.Прочитать();
		ВерсииОбъекта = НаборЗаписей.Выгрузить();
		Для Каждого Версия Из ВерсииОбъекта Цикл
			НаборЗаписей.Отбор.НомерВерсии.Установить(Версия.НомерВерсии);
			НаборЗаписей.Прочитать();
			Запись = НаборЗаписей[0];
			Записать = Ложь;
			Если Запись.ВерсияВладелец >= НомерВерсии Тогда
				Запись.ВерсияВладелец = Запись.ВерсияВладелец + СдвигНомераВерсии;
				Записать = Истина;
			КонецЕсли;
			Если Запись.НомерВерсии >= НомерВерсии Тогда
				Запись.НомерВерсии = Запись.НомерВерсии + СдвигНомераВерсии;
				Запись.ТипВерсииОбъекта = ТипВерсииОбъекта;
				Если УстановитьВладельцаНепринятыхВерсий И Не ЗначениеЗаполнено(Запись.ВерсияВладелец) Тогда
					Запись.ВерсияВладелец = НомерВерсииСКоллизией;
				КонецЕсли;
				Записать = Истина;
			КонецЕсли;
			Если Записать Тогда
				Записи = НаборЗаписей.Выгрузить();
				НаборЗаписей.Очистить();
				НаборЗаписей.Записать();
				НаборЗаписей.Отбор.НомерВерсии.Установить(Записи[0].НомерВерсии);
				НаборЗаписей.Загрузить(Записи);
				НаборЗаписей.Записать();
			КонецЕсли;
		КонецЦикла;
		
		// Создаем версию-владельца непринятых версий.
		Если КоллизииВерсийОбъектов[Объект] = Неопределено Тогда
			НомерВерсииСКоллизией = НомерВерсии + 1;
			АвторВерсии = ОбщегоНазначения.МенеджерОбъектаПоСсылке(Отправитель.Ссылка).ЭтотУзел();
			НомерПоследнейОтклоненнойВерсии = ВерсииКВыгрузке[0].НомерВерсии + СдвигНомераВерсии;
			СоздатьВерсиюВладельцаНепринятых(НомерПоследнейОтклоненнойВерсии, НомерВерсииСКоллизией, Объект, АвторВерсии);
			КоллизииВерсийОбъектов.Вставить(Объект, НомерВерсииСКоллизией);
		КонецЕсли;
		
		ЗаписатьВерсиюСИзменениемНомера(ЭлементДанных, ПолучениеЭлемента, Отправитель, НомерВерсии);
	КонецЕсли;
	
КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

ПриПолученииДанныхОтГлавного (БСП)

Обновлятор-1С: групповое (пакетное) обновление и обслуживание всех баз за один раз