Версии файлов / Модуль менеджера

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

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ПрограммныйИнтерфейс

#Область ДляВызоваИзДругихПодсистем

// СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

// Возвращает реквизиты объекта, которые разрешается редактировать
// с помощью обработки группового изменения реквизитов.
//
// Возвращаемое значение:
//  Массив из Строка
//
Функция РеквизитыРедактируемыеВГрупповойОбработке() Экспорт

	РедактируемыеРеквизиты = Новый Массив;
	РедактируемыеРеквизиты.Добавить("Комментарий");

	Возврат РедактируемыеРеквизиты;

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

// Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

// СтандартныеПодсистемы.УправлениеДоступом

// Параметры:
//   Ограничение - см. УправлениеДоступомПереопределяемый.ПриЗаполненииОграниченияДоступа.Ограничение.
//
Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт

	Ограничение.Текст =
	"РазрешитьЧтение
	|ГДЕ
	|	ЧтениеОбъектаРазрешено(Владелец.ВладелецФайла)
	|;
	|РазрешитьИзменениеЕслиРазрешеноЧтение
	|ГДЕ
	|	ИзменениеОбъектаРазрешено(Владелец.ВладелецФайла)";

	Ограничение.ТекстДляВнешнихПользователей = Ограничение.Текст;

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

// Конец СтандартныеПодсистемы.УправлениеДоступом

#КонецОбласти

#КонецОбласти

#Область ОбработчикиСобытий

Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
	Если ВидФормы = "ФормаОбъекта" Тогда
		СтандартнаяОбработка = Ложь;
		ВыбраннаяФорма       = "Обработка.РаботаСФайлами.Форма.ВерсияПрисоединенногоФайла";
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

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

	ПараметрыВыборки = Параметры.ПараметрыВыборки;
	ПараметрыВыборки.ПолныеИменаОбъектов = Метаданные.Справочники.ВерсииФайлов.ПолноеИмя();
	ПараметрыВыборки.СпособВыборки = ОбновлениеИнформационнойБазы.СпособВыборкиСсылки();
	
	ТекстЗапроса =
	"ВЫБРАТЬ ПЕРВЫЕ 1000
	|	ВерсииФайлов.Ссылка КАК Ссылка,
	|	ВерсииФайлов.ДатаМодификацииУниверсальная КАК ДатаМодификацииУниверсальная
	|ИЗ
	|	Справочник.ВерсииФайлов КАК ВерсииФайлов
	|ГДЕ
	|	ВерсииФайлов.ТипХраненияФайла = ЗНАЧЕНИЕ(Перечисление.ТипыХраненияФайлов.ВТомахНаДиске)
	|	И (ВерсииФайлов.ДатаМодификацииУниверсальная < &ДатаМодификации
	|	ИЛИ ВерсииФайлов.ДатаМодификацииУниверсальная = &ДатаМодификации
	|	И ВерсииФайлов.Ссылка < &Ссылка)
	|
	|УПОРЯДОЧИТЬ ПО
	|	ДатаМодификацииУниверсальная УБЫВ,
	|	Ссылка УБЫВ";
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ДатаМодификации", Дата(3999, 12, 31));
	Запрос.УстановитьПараметр("Ссылка", Справочники.ВерсииФайлов.ПолучитьСсылку(
		Новый УникальныйИдентификатор("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")));
	
	Пока Истина Цикл
		
		//@skip-check query-in-loop - Порционная обработка данных
		ТаблицаВыборки = Запрос.Выполнить().Выгрузить();
		
		Если ТаблицаВыборки.Количество() = 0 Тогда
			Прервать;
		КонецЕсли;
		
		ВерсииДляОбработки = ТаблицаВыборки.ВыгрузитьКолонку("Ссылка");
		ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, ВерсииДляОбработки);

		Если ТаблицаВыборки.Количество() < 1000 Тогда
			Прервать;
		КонецЕсли;
		
		ПоследняяСтрока = ТаблицаВыборки[ТаблицаВыборки.Количество() - 1];
		Запрос.УстановитьПараметр("ДатаМодификации", ПоследняяСтрока.ДатаМодификацииУниверсальная);
		Запрос.УстановитьПараметр("Ссылка", ПоследняяСтрока.Ссылка);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ОбработатьДанныеДляПереходаНаНовуюВерсию(Параметры) Экспорт

	ВыбранныеДанные = ОбновлениеИнформационнойБазы.ДанныеДляОбновленияВМногопоточномОбработчике(Параметры);

	ПроблемныхОбъектов = 0;
	ОбъектовОбработано = 0;

	Для Каждого Строка Из ВыбранныеДанные Цикл
		
		Если ОбработатьВерсиюФайла(Строка.Ссылка) Тогда
			ОбъектовОбработано = ОбъектовОбработано + 1;
		Иначе
			ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
		КонецЕсли;

	КонецЦикла;

	Если ОбъектовОбработано = 0 И ПроблемныхОбъектов <> 0 Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось обработать файлы (пропущены): %1'"), 
			ПроблемныхОбъектов);
		ВызватьИсключение ТекстСообщения;
	КонецЕсли;

	ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), 
		УровеньЖурналаРегистрации.Информация, , ,
		СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Обработана очередная порция файлов: %1'"),
			ОбъектовОбработано));
	Параметры.ОбработкаЗавершена = ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, "Справочник.ВерсииФайлов");

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ОбработатьВерсиюФайла(ВерсияСсылка)

	Результат = Истина;
	ПредставлениеСсылки = Строка(ВерсияСсылка);
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.ВерсииФайлов");
	ЭлементБлокировки.УстановитьЗначение("Ссылка", ВерсияСсылка);

	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		
		ВерсияОбъект = Неопределено;
		ТребуетсяЗаписать = Ложь;
		
		// @skip-check query-in-loop - Порционная обработка большого объема данных.
		ПутьКФайлу = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ВерсияСсылка, "ПутьКФайлу");
		Если СтрНачинаетсяС(ПутьКФайлу, "/") Или СтрНачинаетсяС(ПутьКФайлу, "\") Тогда
			НовыйПутьКФайлу = Сред(ПутьКФайлу, 2);

			ВерсияОбъект = ВерсияСсылка.ПолучитьОбъект();
			Если ВерсияОбъект = Неопределено Тогда
				ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(ВерсияСсылка);
				ЗафиксироватьТранзакцию();
				Возврат Результат;
			КонецЕсли;
			ВерсияОбъект.ПутьКФайлу = НовыйПутьКФайлу;
			ТребуетсяЗаписать = Истина;
		КонецЕсли;
		
		Если ВерсияОбъект = Неопределено Тогда
			ВерсияОбъект = ВерсияСсылка.ПолучитьОбъект();
			Если ВерсияОбъект = Неопределено Тогда
				ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(ВерсияСсылка);
				ЗафиксироватьТранзакцию();
				Возврат Результат;
			КонецЕсли;
		КонецЕсли;
		
		ДвоичныеДанныеФайла = Неопределено;
		ХранилищеДвоичныхДанныхФайла = ВерсияОбъект.ФайлХранилище;
		ДвоичныеДанныеФайла = ?(ТипЗнч(ХранилищеДвоичныхДанныхФайла) = Тип("ХранилищеЗначения"),
			ХранилищеДвоичныхДанныхФайла.Получить(), Неопределено);
		
		Если ДвоичныеДанныеФайла <> Неопределено Тогда
			ВерсияОбъект.ФайлХранилище = Новый ХранилищеЗначения(Неопределено);
			ТребуетсяЗаписать = Истина;
		КонецЕсли;

		Если ТребуетсяЗаписать Тогда
			ВерсияОбъект.Записать();
		Иначе
			ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(ВерсияСсылка);
		КонецЕсли;

		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();

		Результат = Ложь;
		ОбновлениеИнформационнойБазы.ЗаписатьОшибкуВЖурналРегистрации(ВерсияСсылка,
			ПредставлениеСсылки, ИнформацияОбОшибке());

	КонецПопытки;

	Возврат Результат;

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

#КонецОбласти

#КонецЕсли

Связанные материалы