Версионирование объектов - отключение создания одинаковых версий + обработка по их удалению

Администрирование - Чистка базы

Стандартная процедура версионирования объектов создает одинаковые версии при перепроведении / перезаписи объекта без изменения реквизитов. Следовательно, база пухнет от пустых версий, особенно при закрытии месяца (проведение документов).

Но можно избавиться от создания клонов, реализация ниже (в Общем модуле ВерсионированиеОбъектов):

Процедура МеханизмВерсионированияОбъектов_ПриЗаписиОбъекта(Источник, Отказ) Экспорт
	
	Перем ЧислоВерсийОбъекта;
	
	Если ОбъектВерсионируется(Источник, ЧислоВерсийОбъекта) Тогда
		
		ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
		
		ЗаписьXML = Новый ЗаписьXML;
		ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла); 
		ЗаписьXML.ЗаписатьОбъявлениеXML();
		ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
		ЗаписьXML.Закрыть();
		
		ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
		//ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));       
		
		УдалитьФайлы(ИмяВременногоФайла);
		
		//ВерсионированиеОбъектовПривилегированный.ЗаписатьВерсиюОбъекта(Источник.Ссылка, ЧислоВерсийОбъекта, ХранилищеДанных);  

		// ++Владимир //вв // 06.08.2015 10:09:37
		Запрос = Новый Запрос;
		Запрос.Текст = "ВЫБРАТЬ
		|    ВерсииОбъектов.ВерсияОбъекта
		|ИЗ
		|    РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
		|ГДЕ
		|    ВерсииОбъектов.Объект = &Ссылка
		|    И ВерсииОбъектов.НомерВерсии = &НомерВерсии";
		Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
		Запрос.УстановитьПараметр("НомерВерсии", ЧислоВерсийОбъекта);
		Выборка = Запрос.Выполнить().Выбрать();
		Выборка.Следующий();
		
		ПредыдущаяВерсияОбъекта = ?(Выборка.ВерсияОбъекта = Неопределено, Неопределено, Выборка.ВерсияОбъекта.Получить());
		
		Если ЗначениеВСтрокуВнутр(ПредыдущаяВерсияОбъекта) <> ЗначениеВСтрокуВнутр(ДвоичныеДанные) Тогда //Сравниваем версии
			ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
			ВерсионированиеОбъектовПривилегированный.ЗаписатьВерсиюОбъекта(Источник.Ссылка, ЧислоВерсийОбъекта, ХранилищеДанных);
		КонецЕсли;
		// --Владимир // 06.08.2015 10:09:37    
		
	КонецЕсли;
	
КонецПроцедуры

В комментарии (6) предложен альтернативный способ проверки версий (для "тяжелых" документов).

Также предлагаю Вам обработку по удалению уже созданных клонов. В форме необходимо внести ограничение по количеству версий (для отбора), нажать кнопку "Удалить" (только дубли). Удаление 155 467 одинаковых версий заняло чуть более часа (база похудела на 1,5 GB).

Скачать файлы

Наименование Файл Версия Размер
Удаление одинаковых версий
.epf 8,59Kb
10.08.15
28
.epf 8,59Kb 28 Скачать

См. также

Комментарии
1. Максим Гончаров (maxx) 608 10.08.15 13:53 Сейчас в теме
В текущей версии БСП одинаковые версии на записываются при перепроведении/перезаписи.
u_n_k_n_o_w_n; +1 Ответить 1
2. Владимир Рютин (VovkaPutin) 26 10.08.15 13:58 Сейчас в теме
(1) maxx, не все сидят на текущей версии :)
3. Иван Петров (dgolovanov) 10.08.15 15:14 Сейчас в теме
Решал эту же проблему недавно. Сделал иначе:
http://infostart.ru/public/96713/, комментарий 23 - листинг кода получения хэша из строки.
В регистр добавил еще одно измерение и сравниваю не объекты, а хэши - работает быстрее. А в 8.3 поддержка хэширования реализована на уровне платформы. Ну да это я пишу чисто поделиться информацией.
4. Владимир Зленко (ZLENKO) 366 10.08.15 17:52 Сейчас в теме
На эту тему еще есть обработка сжатия версий http://infostart.ru/public/321131/
5. Дмитрий Бухалов (Re:аниматор) 391 18.08.15 07:27 Сейчас в теме
В ряде случаев выходит ошибка

Ошибка при выполнении обработчика - 'ПриЗаписи'
по причине:
{ОбщийМодуль.ВерсионированиеОбъектов.Модуль(36)}: Ошибка при вызове метода контекста (ЗначениеВСтрокуВнутр)

по причине:
Ошибка преобразования
по причине:
bad allocation


Погуглив, нашел
Как правило, "bad allocation" происходит, когда производится попытка получить внутренее представление объекта с типом ХранилищеЗначения большого размера (большая картинка, таблица, документ и т.д.)..


Данное решение не работает с большими документами. В моем случае документ содержит 68 287 строк
VovkaPutin; +1 Ответить
6. Дмитрий Бухалов (Re:аниматор) 391 18.08.15 09:27 Сейчас в теме
Сделал, всё работает


			//Если ЗначениеВСтрокуВнутр(ПредыдущаяВерсияОбъекта) <> ЗначениеВСтрокуВнутр(ДвоичныеДанные) Тогда //Сравниваем версии
			Если КонтрольнаяСумма(СериализоватьОбъект(ДвоичныеДанные)) <> КонтрольнаяСумма(СериализоватьОбъект(ПредыдущаяВерсияОбъекта)) Тогда

...

// Возвращает сериализованный объект в виде двоичных данных.
//
// Параметры:
//  Объект - Любой - сериализуемый объект.
//
// Возвращаемое значение:
//  ДвоичныеДанные - сериализованный объект.
Функция СериализоватьОбъект(Объект) Экспорт
	
	ЗаписьXML = Новый ЗаписьFastInfoset;
	ЗаписьXML.УстановитьДвоичныеДанные();
	ЗаписьXML.ЗаписатьОбъявлениеXML();
	
	ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);
	
	Возврат ЗаписьXML.Закрыть();

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

// Контрольная сумма по алгоритму MD5.
Функция КонтрольнаяСумма(Данные) Экспорт
	
	ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
	ХешированиеДанных.Добавить(Данные);
	Возврат СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
	
КонецФункции



...Показать Скрыть


Работает и с большими объемами
VovkaPutin; +1 Ответить
7. Павел Конкин (PASAHAKA) 47 19.06.17 17:27 Сейчас в теме
Предлагаю вот такой режим версионирования.
ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl"); 
        ScrptCtrl.Language = "JScript"; 
        ScrptCtrl.AddCode(" 
        |/* 
		| * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 
		| * Digest Algorithm, as defined in RFC 1321.
		| * Version 2.1 Copyright © Paul Johnston 1999 - 2002.
		| * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 
		| * Distributed under the BSD License 
		| * See http://pajhome.org.uk/crypt/md5   http://pajhome.org.uk/crypt/md5 for more info.
		| */ 
		| 
		|/* 
		| * Configurable variables. You may need to tweak these to be compatible with 
		| * the server-side, but the defaults work in most cases. 
		| */ 
		|var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */ 
		|var b64pad  = """"; /* base-64 pad character. ""="" for strict RFC compliance   */
		|var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */ 
		| 
		|/* 
		| * These are the functions you'll usually want to call 
        | * They take string arguments and return either hex or base-64 encoded strings 
        | */ 
        |function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} 
        |function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} 
        |function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} 
        |function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } 
        |function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } 
        |function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } 
        | 
        |/* 
        | * Perform a simple self-test to see if the VM is working 
        | */ 
        |function md5_vm_test() 
        |{ 
        |  return hex_md5(""abc"") == ""900150983cd24fb0d6963f7d28e17f72""; 
        |} 
        | 
        |/* 
        | * Calculate the MD5 of an array of little-endian words, and a bit length 
        | */ 
        |function core_md5(x, len) 
        |{ 
        |  /* append padding */ 
        |  x[len >> 5] |= 0x80 << ((len) % 32); 
        |  x[(((len + 64) >>> 9) << 4) + 14] = len; 
        | 
        |  var a =  1732584193; 
        |  var b = -271733879; 
        |  var c = -1732584194; 
        |  var d =  271733878; 
        | 
        |  for(var i = 0; i < x.length; i += 16) 
        |  { 
        |    var olda = a; 
        |    var oldb = b; 
        |    var oldc = c; 
        |    var oldd = d; 
        | 
        |    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); 
        |    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); 
        |    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819); 
        |    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); 
        |    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); 
        |    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426); 
        |    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); 
        |    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); 
        |    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416); 
        |    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); 
        |    c = md5_ff(c, d, a, b, x[i+10], 17, -42063); 
        |    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); 
        |    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682); 
        |    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); 
        |    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); 
        |    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329); 
        | 
        |    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); 
        |    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); 
        |    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713); 
        |    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); 
        |    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); 
        |    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083); 
        |    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); 
        |    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); 
        |    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438); 
        |    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); 
        |    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); 
        |    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501); 
        |    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); 
        |    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); 
        |    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473); 
        |    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); 
        | 
        |    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); 
        |    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); 
        |    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562); 
        |    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); 
        |    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); 
        |    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353); 
        |    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); 
        |    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); 
        |    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174); 
        |    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); 
        |    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); 
        |    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189); 
        |    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); 
        |    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); 
        |    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520); 
        |    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); 
        | 
        |    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); 
        |    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415); 
        |    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); 
        |    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); 
        |    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571); 
        |    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); 
        |    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); 
        |    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); 
        |    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359); 
        |    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); 
        |    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); 
        |    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649); 
        |    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); 
        |    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); 
        |    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259); 
        |    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); 
        | 
        |    a = safe_add(a, olda); 
        |    b = safe_add(b, oldb); 
        |    c = safe_add(c, oldc); 
        |    d = safe_add(d, oldd); 
        |  } 
        |  return Array(a, b, c, d); 
        | 
        |} 
        | 
        |/* 
        | * These functions implement the four basic operations the algorithm uses. 
        | */ 
        |function md5_cmn(q, a, b, x, s, t) 
        |{ 
        |  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); 
        |} 
        |function md5_ff(a, b, c, d, x, s, t) 
        |{ 
        |  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 
        |} 
        |function md5_gg(a, b, c, d, x, s, t) 
        |{ 
        |  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 
        |} 
        |function md5_hh(a, b, c, d, x, s, t) 
        |{ 
        |  return md5_cmn(b ^ c ^ d, a, b, x, s, t); 
        |} 
        |function md5_ii(a, b, c, d, x, s, t) 
        |{ 
        |  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 
        |} 
        | 
        |/* 
        | * Calculate the HMAC-MD5, of a key and some data 
        | */ 
        |function core_hmac_md5(key, data) 
        |{ 
        |  var bkey = str2binl(key); 
        |  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); 
        | 
        |  var ipad = Array(16), opad = Array(16); 
        |  for(var i = 0; i < 16; i++) 
        |  { 
        |    ipad[i] = bkey[i] ^ 0x36363636; 
        |    opad[i] = bkey[i] ^ 0x5C5C5C5C; 
        |  } 
        | 
        |  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); 
        |  return core_md5(opad.concat(hash), 512 + 128); 
        |} 
        | 
        |/* 
        | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 
        | * to work around bugs in some JS interpreters. 
        | */ 
        |function safe_add(x, y) 
        |{ 
        |  var lsw = (x & 0xFFFF) + (y & 0xFFFF); 
        |  var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 
        |  return (msw << 16) | (lsw & 0xFFFF); 
        |} 
        | 
        |/* 
        | * Bitwise rotate a 32-bit number to the left. 
        | */ 
        |function bit_rol(num, cnt) 
        |{ 
        |  return (num << cnt) | (num >>> (32 - cnt)); 
        |} 
        | 
        |/* 
        | * Convert a string to an array of little-endian words 
        | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. 
        | */ 
        |function str2binl(str) 
        |{ 
        |  var bin = Array(); 
        |  var mask = (1 << chrsz) - 1; 
        |  for(var i = 0; i < str.length * chrsz; i += chrsz) 
        |    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); 
        |  return bin; 
        |} 
        | 
        |/* 
        | * Convert an array of little-endian words to a string 
        | */ 
        |function binl2str(bin) 
        |{ 
        |  var str = """"; 
        |  var mask = (1 << chrsz) - 1; 
        |  for(var i = 0; i < bin.length * 32; i += chrsz) 
        |    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); 
        |  return str; 
        |} 
        | 
        |/* 
        | * Convert an array of little-endian words to a hex string. 
        | */ 
        |function binl2hex(binarray) 
        |{ 
        |  var hex_tab = hexcase ? ""0123456789ABCDEF"" : ""0123456789abcdef""; 
        |  var str = """"; 
        |  for(var i = 0; i < binarray.length * 4; i++) 
        |  { 
        |    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + 
        |           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF); 
        |  } 
        |  return str; 
        |} 
        | 
        |/* 
        | * Convert an array of little-endian words to a base-64 string 
        | */ 
        |function binl2b64(binarray) 
        |{ 
        |  var tab = ""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345­6789+/""; 
        |  var str = """"; 
        |  for(var i = 0; i < binarray.length * 4; i += 3) 
        |  { 
        |    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16) 
        |                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) 
        |                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); 
        |    for(var j = 0; j < 4; j++) 
        |    { 
        |      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 
        |      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 
        |    } 
        |  } 
        |  return str; 
        |} 
        |"); 
         
        ЗначениеВозврата = ""; 
        ЗначениеВозврата = ScrptCtrl.Run("hex_md5", КодируемаяСтрока); 
    Исключение 
        ЗначениеВозврата = Неопределено; 
        Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное); 
    КонецПопытки; 
    ScrptCtrl = ""; 
     
    Возврат ЗначениеВозврата; 
     
КонецФункции // MD5()
...Показать Скрыть
Оставьте свое сообщение