powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Хранение истории изменений объектов
25 сообщений из 57, страница 1 из 3
Хранение истории изменений объектов
    #37458232
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Хотелось бы узнать способы хранения истории изменений. Поделитесь, плиз, кто как хранит историю изменений объектов, как это реализовано. В поиске на форуме находил пару тем, но они древние и не отвечают на все вопросы.

Задача такова: при изменении какого-то свойства объекта надо сохранять в базе запись об этом изменении с новым значением, именем юзера, под которым изменилось это свойство, ну и с датой и временем изменения, естественно. Отсюда возникают вопросы: как отследить, когда изменилось конкретное свойство? В чём хранить эти изменения? (в смысле, пользоваться классами или напрямую лучше писать в глобалы)

Сейчас на событии OnAfterSave пробегаюсь по свойствам, ищу в базе последнее изменение свойства, сравниваю их и если они не равны, записываю новую запись. Причём такой поиск с использованием классов (ClassHistoryObject) оказался довольно долгим, поэтому думаю писать прямо в глобалы. Проблема ещё и в том, что если свойство представляет ссылку на объект, то его тоже надо как-то разобрать, чтобы хранить не просто айдишник (который со временем может быть удалён и не поймёшь потом, а что было в этом объекте), а описание его полей. Но с этим я как-то ещё разобрался, у всех персистент и сериал обжект классов должен быть обязательным метод ToString(), который возвращает описание объекта. А вот как быть со списками и отношениями...

В общем, если кто с этим сталкивался, подскажите, если не трудно, как это лучше организовать.
Спасибо.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37458322
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vixlerесли кто с этим сталкивался, подскажите, если не трудно, как это лучше организовать
Применяем свою "обёртку" для изменения данных в БД...
Т.е. ничего из стандартного не трогаем, оставляя возможность его использования но при этом никакие изменения не запишутся никуда... Делаем свои процедурки/функции/методы, коими все должны пользоваться при стандартной модификации БД. Вот эти-то процедурки/функции/методы и ведут "учёт" всех изменений.

Всё новое предпочитаем хранить в классах, дабы была возможность работы sql и zen...
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37458442
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в одном из проектов в котором я участвовал, хранение истории было построено довольно просто в ущерб занимаемому месту в бд
при изменении объекта будь то через объект или через SQL, в специальном глобале, это был так же как имена глобалов для хранения данных объекта, только на конце "H" и в него хранилось в разрезе каждого ID, времени изменения копия $LB() с данными и именем пользователя под которым произошло изменение, в дальнейшем когда требовалось просмотреть историю изменения то или иного объекта, через интерфейс системы, выводилась таблица с наиболее интересующими полями, где каждая строчка отдельное изменение. и можно всю проследить историю изменения сразу. вроде использовалось %OnAfterSave и триггеры для отлова изменений через SQL.

в другом проекте, используется журнал, куда регистрируются события разного вида в том числе и изменения документа, и на каждое поле своя запись в журнале, и когда пользователь хочет просмотреть историю, он видит всю историю по этому объекту хронологически, и для каждого изменения отображается какое значение было до изменения и какое стало после. для всех событий и всех объектов используется один журнал. с таким журналом, администратор может просматривать изменения по одному документу или например, что изменял пользователь в указанный период, так же и попытки авторизации и прочее. только %OnAfterSave, через SQL изменений не происходит.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37459572
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vixler, если позволяет логика приложения, можно выгружать перед изменением версию на диск

Код: plaintext
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.
/// Выгрузка при изменении
Class test.version Extends (%Persistent, %Populate, %XML.Adaptor) {

/// VERSIONPROPERTY = <property> means that the <property> in memory will be compared to
/// the <property> on disk during an update. If different a concurrency conflict
/// error will be reported and the save will fail.
Parameter VERSIONPROPERTY As STRING = "Version";
/// Свойство - Версия объекта - на него указывает системе параметр класса <parameter>VERSIONPROPERTY</parameter>
Property Version As %Integer [ InitialExpression =  1 ,Private ]; 


/// Директория для истории изменений 
Parameter DIR As %String = "c:\temp\";

/// Свойство
Property Name As %String;

/// This callback method is invoked by the <METHOD>%Save</METHOD> method to 
/// provide notification that the object is being saved. It is called before 
/// any data is written to disk.
/// 
/// <P><VAR>insert</VAR> will be set to  1  if this object is being saved for the first time.
/// 
/// <P>If this method returns an error then the call to <METHOD>%Save</METHOD> will fail.
Method %OnBeforeSave(insert As %Boolean) As %Status [ Private, ServerOnly =  1  ] {
 if ('insert) && (..%Id()'="") && (..%IsModified()) {
  JOB ..OnChangeExport(..%Id())
 }
 Quit $$$OK
}

/// Выгрузка перед сохранением
ClassMethod OnChangeExport(id As %String) As %Status [CodeMode = generator ] {
 s %code($i(%code))="  s stored=..%OpenId(id) Q:'$IsObject(stored) $$$OK "
 s %code($i(%code))="  s file="""_%parameter("DIR")_%class_".""_stored.%Id()_"".""_stored.Version_"".""_$USERNAME_"".xml"" "
 s %code($i(%code))="  o file:""WNU"" u file d stored.XMLExport() k stored c file "
 s %code($i(%code))="  Q $$$OK "
 Q $$$OK
}

}
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460143
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DAiMorв другом проекте, используется журнал, куда регистрируются события разного вида в том числе и изменения документа, и на каждое поле своя запись в журнале, и когда пользователь хочет просмотреть историю, он видит всю историю по этому объекту хронологически, и для каждого изменения отображается какое значение было до изменения и какое стало после. для всех событий и всех объектов используется один журнал. с таким журналом, администратор может просматривать изменения по одному документу или например, что изменял пользователь в указанный период, так же и попытки авторизации и прочее. только %OnAfterSave, через SQL изменений не происходит.

Вот так же хочу сделать. А как у вас выглядела вообще структура классов или глобалов для хранения истории? Сейчас стоит проблема сравнения текущего значения поля с предыдущим ранее сохранённым значением. Если пробегаться по журналу в поисках последней версии, то чем больше было изменений, тем дольше будет поиск. Как у вас это решалось? И как происходило хранение изменений полей-ссылок, отношений и списков? Ну к примеру. В классе есть поле-отношение один-ко-многим Users, описывающее список юзеров, причём каждый объект списка-отношения - это объект класса User. В какой-то момент список пополняется новым юзером. Как в таком случае у вас бы хранилась информация об этом изменении?

Кстати, почему может не работать <propertyName>GetStored? Пишет ошибку:

>w a.IsBlockedGetStored()

Quit $Select(id'="":$listget($g(^User(id)),18),1:"") }
^
<UNDEFINED>zIsBlockedGetStored+1^User.1 *id


doublefintVixler, если позволяет логика приложения, можно выгружать перед изменением версию на диск +

Код: plaintext
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.
/// Выгрузка при изменении
Class test.version Extends (%Persistent, %Populate, %XML.Adaptor) {

/// VERSIONPROPERTY = <property> means that the <property> in memory will be compared to
/// the <property> on disk during an update. If different a concurrency conflict
/// error will be reported and the save will fail.
Parameter VERSIONPROPERTY As STRING = "Version";
/// Свойство - Версия объекта - на него указывает системе параметр класса <parameter>VERSIONPROPERTY</parameter>
Property Version As %Integer [ InitialExpression =  1 ,Private ]; 


/// Директория для истории изменений 
Parameter DIR As %String = "c:\temp\";

/// Свойство
Property Name As %String;

/// This callback method is invoked by the <METHOD>%Save</METHOD> method to 
/// provide notification that the object is being saved. It is called before 
/// any data is written to disk.
/// 
/// <P><VAR>insert</VAR> will be set to  1  if this object is being saved for the first time.
/// 
/// <P>If this method returns an error then the call to <METHOD>%Save</METHOD> will fail.
Method %OnBeforeSave(insert As %Boolean) As %Status [ Private, ServerOnly =  1  ] {
 if ('insert) && (..%Id()'="") && (..%IsModified()) {
  JOB ..OnChangeExport(..%Id())
 }
 Quit $$$OK
}

/// Выгрузка перед сохранением
ClassMethod OnChangeExport(id As %String) As %Status [CodeMode = generator ] {
 s %code($i(%code))="  s stored=..%OpenId(id) Q:'$IsObject(stored) $$$OK "
 s %code($i(%code))="  s file="""_%parameter("DIR")_%class_".""_stored.%Id()_"".""_stored.Version_"".""_$USERNAME_"".xml"" "
 s %code($i(%code))="  o file:""WNU"" u file d stored.XMLExport() k stored c file "
 s %code($i(%code))="  Q $$$OK "
 Q $$$OK
}

}


Попробовал сделать экспорт объекта в XML-файл функцией XMLExport, когда дошло до поля-отношения, вывалилась ошибка. Не хочет что-то функа эта работать с отношениями.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460150
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vixler,

Мы сделали класс, от которого унаследованы все хранимые объекты системы, в нем перегрузили %OnBeforeSave, %OnDelete и %OnAfterSave.
В зависимости от типа изменения (создание, изменение, удаление), пишем содержание изменения в историю.
Потом можно просмотреть требуемую информацию и выполнить откаты в случае необходимости (простые откаты, разумеется).
Вот так примерно:
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460165
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2kolesov:

Пара вопросов, если можно:

1. Открыли объект через %OpenId, изменили одно/несколько полей, делаем %Save(). Теперь нужно сделать запись в журнал, для этого надо узнать, какие поля были изменены. Каким образом вы это делаете? Через метод <propertyName>GetStored() или через sql-запрос?

2. В приложенном вами скрине, насколько я понял, два поля простых типов %String и %TimeStamp. А как вы обрабатываете поля-ссылки, поля-отношения и поля-списки?

Спасибо.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460219
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vixler2kolesov:

Пара вопросов, если можно:

1. Открыли объект через %OpenId, изменили одно/несколько полей, делаем %Save(). Теперь нужно сделать запись в журнал, для этого надо узнать, какие поля были изменены. Каким образом вы это делаете? Через метод <propertyName>GetStored() или через sql-запрос?

2. В приложенном вами скрине, насколько я понял, два поля простых типов %String и %TimeStamp. А как вы обрабатываете поля-ссылки, поля-отношения и поля-списки?

Спасибо.
1. Через метод <propertyName>GetStored()

2. В примере первое поле - ссылка на объект. В том же суперклассе (где пишется история) есть метод, представляющий этот объект в текстовом виде. В данном случае описание нефтепродукта - это результат работы такого метода, а квадратных скобочках в конце - его айди в БД. По-умолчанию этот метод возвращает "[ID]" а для некоторых наиболее полезных объектов он перегружен, как на картинке - другой пример: "т/х Нарьянмар, рейс 2120, ETA 12-12-11 [1232]", "а там - объект" ;)
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460232
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ага, спасибо за ответы.

А что насчёт списков и отношений один-ко-многим? Как у вас тогда происходит запись? Допустим поле представляет список из 350 ссылок на объекты какого-либо класса. В определённый момент одна ссылка удаляется(/добавляется/изменяется). Какая запись тогда вносится в журнал? Перечисление всех этих объектов в текстовом виде? Просто такая строка будет огромной и анализировать её наверное будет сложновато. Я тут думаю может писать что-то вроде "field = listOfSomeObjects, operation = 'добавление элемента в список', value = obj.ToString()"
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460240
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VixlerАга, спасибо за ответы.

А что насчёт списков и отношений один-ко-многим? Как у вас тогда происходит запись? Допустим поле представляет список из 350 ссылок на объекты какого-либо класса. В определённый момент одна ссылка удаляется(/добавляется/изменяется). Какая запись тогда вносится в журнал? Перечисление всех этих объектов в текстовом виде? Просто такая строка будет огромной и анализировать её наверное будет сложновато. Я тут думаю может писать что-то вроде "field = listOfSomeObjects, operation = 'добавление элемента в список', value = obj.ToString()"

- Изменения отношений записывается со стороны "много"

- Поля-списки, отношения "родитель-потомок" и прочие нестабильные артефакты не используем - система должна быть как риск-процессор (минимум сущностей при максимуме эффективности) и облегчение работы с историей - тому лишнее подтверждение ;)
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460288
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VixlerПопробовал сделать экспорт объекта в XML-файл функцией XMLExport, когда дошло до поля-отношения, вывалилась ошибка. Не хочет что-то функа эта работать с отношениями.
Что за ошибка? Не настроен экспорт связанных объектов в XML?
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460305
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А списки строк? :)

Ну так вроде всё понятно, спасибо, начинает что-то вырисовываться. Списки ссылок мы тоже решили не юзать, но так, на всякий случай, думал обрабатывать и эту ситуацию. К тому же есть ещё %SerialObject-классы, у которых нет функции %Save(), и не получится со стороны таких объектов (в отношениях "один-ко-многим") записать изменение в журнал. Или вы и их не юзаете? )
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460370
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VixlerА списки строк? :)

Ну так вроде всё понятно, спасибо, начинает что-то вырисовываться. Списки ссылок мы тоже решили не юзать, но так, на всякий случай, думал обрабатывать и эту ситуацию. К тому же есть ещё %SerialObject-классы, у которых нет функции %Save(), и не получится со стороны таких объектов (в отношениях "один-ко-многим") записать изменение в журнал. Или вы и их не юзаете? )
Списки строк конечно используем. Как и всяческие другие коллекции. Но не как свойства хранимых классов. То есть вообще ни одного хранимого свойства типа *List* или *Array* в системе за последних 4 года не появилось. А если бы появилось - программист бы огрёб ;)

А "на всякий случай" мы в подобной ситуации просто не запишем изменение - вреда от этого чуть (ну не узнаем мы кто в списке подменил элемент и как). Если решение эффективно на 99,9 процентов, то на оставшуюся десятую долю можно забить - в конце концов есть видео, пыточная комната, полиграф и прочие вполне эффективные и недорогие айти-инструменты - незачем лишать себя разнообразия и удовольствий ;)
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37460412
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VixlerВот так же хочу сделать. А как у вас выглядела вообще структура классов или глобалов для хранения истории? Сейчас стоит проблема сравнения текущего значения поля с предыдущим ранее сохранённым значением. Если пробегаться по журналу в поисках последней версии, то чем больше было изменений, тем дольше будет поиск. Как у вас это решалось? И как происходило хранение изменений полей-ссылок, отношений и списков? Ну к примеру. В классе есть поле-отношение один-ко-многим Users, описывающее список юзеров, причём каждый объект списка-отношения - это объект класса User. В какой-то момент список пополняется новым юзером. Как в таком случае у вас бы хранилась информация об этом изменении?

дело в том что у нас поля несколько иного вида, они хранятся в глобале объекта, имеют не стандартный тип а наш, и поэтому мы у себя контролируем что из полей изменилось а что нет, и добавляем соответствующее событие в журнал.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37515480
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Опять вернулся к этой многострадальной истории...

Никак не могу разобраться как сравнивать два значения, новое и сохранённое. Если это простой тип (строка, число) - это ладно. Пофик, если это ссылка на другой объект, сравниваем айдишники. Но если это список (простых типов) или ссылка на объект типа %SerialObject?

Например,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
s a.SomePeriod.DateBegin = "2011-01-01"
s a.SomePeriod.DateEnd = "2040-01-01"
w a.%Save()
 1 
w a.SomePeriodGetStored(a.%Id())
 2011 - 01 - 01   00 : 00 : 00  2040 - 01 - 01   00 : 00 : 00 
w a.SomePeriod
 3 @VSCCMS.Blank.DatePeriod

SomePeriodGetStored возвращает одно представление объекта, а SomePeriod - другое. Как их привести к одинаковому виду?

В документации пишут что-то про StorageToLogical, но её нету у этого класса, как и у всех других...

То же самое со списком простых классов. Никак не могу привести два значения к одному виду. Можно конечно использовать вычисляемые поля, которые будут описывать списки и объекты SerialObject, но это надо будет в каждом классе самому отслеживать такие поля.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37519337
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И всё-таки. Как преобразовать значение к хранимому виду? Вот здесь про функцию LogicalToStorage() сказано, что оно опционально. Но не написано, где эта опция включается, чтобы эта функция была доступна. Может кто-нибудь знает?
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37519383
ser_shu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VixlerИ всё-таки. Как преобразовать значение к хранимому виду? Вот здесь про функцию LogicalToStorage() сказано, что оно опционально. Но не написано, где эта опция включается, чтобы эта функция была доступна. Может кто-нибудь знает?
Опционально - можете добавить методы с этими именами в описание класса и они будут исполняться.
Обычно все хранят значения Logical, поэтому никто эти методы не использует.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37519385
Vixler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ладно, но как тогда корректно сравнить ранее сохранённое значение, полученное по GetStored и текущее значение, когда %Save() ещё не выполнен? Для случая со списком или ссылкой на %SerialObject?
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671878
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подниму темку...

Решил хранить историю модификации классов таким образом:
- создал абстрактный класс

Код: vbnet
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.
/// Расширение для класса с данными
Class mvr.sys.cls.data [ Abstract ]
{

/// Дата модификации
Property changeDate As %Date(FORMAT = 3)[ 
	SqlComputeCode = { 
		Set {changeDate}=+$h 
	}, SqlComputed 
];

/// Время модификации
Property changeTime As %Time[ 
	SqlComputeCode = { 
		Set {changeTime}=$p($h,",",2)
	}, SqlComputed 
];

/// Сотрудник выполневший модификацию данных
Property changeEmployee As %String[ 
	SqlComputeCode = { 
		Set {changeEmployee}= ##class({%%CLASSNAME}).saveEmployee() 
	}, SqlComputed 
];

/// Записать пользователя
ClassMethod saveEmployee() As %String
{
	s val=$g(%session.Data("userId"))
	q ""
	s val=##class(mvr.data.employee).%OpenId(val).name
	q val
}

}



- Применяю наследование

Код: vbnet
1.
2.
/// Пользователи
Class mvr.data.employee Extends (%Persistent, mvr.sys.cls.data)



Когда делаю insetr через SQL - данные записываются.
Но при update или манипуляций классом ничего не меняется и не записывается...

Как бы победить еще и это?
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671887
Фотография DirksDR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krvsa,

s val=$g(%session.Data("userId"))
q ""
;а будут ли выполняться нижние строки, вроде выход уже был?
s val=##class(mvr.data.employee).%OpenId(val).name
q val
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671890
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DirksDR , это тестовый вариант... Суть вопроса не в этом.
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671894
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пусть будет например так:

Код: vbnet
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.
/// Расширение для класса с данными
Class mvr.sys.cls.data [ Abstract ]
{

/// Дата модификации
Property changeDate As %Date(FORMAT = 3)[ 
	SqlComputeCode = { 
		Set {changeDate}=+$h 
	}, SqlComputed 
];

/// Время модификации
Property changeTime As %Time[ 
	SqlComputeCode = { 
		Set {changeTime}=$p($h,",",2)
	}, SqlComputed 
];

/// Сотрудник выполневший модификацию данных
Property changeEmployee As %String[ 
	SqlComputeCode = { 
		Set {changeEmployee}= ##class({%%CLASSNAME}).saveEmployee() 
	}, SqlComputed 
];

/// Записать пользователя
ClassMethod saveEmployee() As %String
{
	s val=$g(%session.Data("userId"))
	q:val="" ""
	s val=##class(mvr.data.employee).%OpenId(val).name
	q val
}

}
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671903
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё это срабатывает только при добавлении данных insert... Более ничего данных не меняет.

Меня даже устроит если будут изменения по update.
Т.к. при классовом подходе я просто создам медод, альтернативный %Save() и проблему т.о. решу...
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671928
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения Добавление работает и классовым методом, данные записываются

Код: vbnet
1.
2.
3.
MVR>s o=##class(mvr.data.employee).%New() zw o s o.name="test" s ok=o.%Save() zw ok k o
o=<OBJECT REFERENCE>[1@mvr.data.employee]
ok=1



Пришлось усложнить метод

Код: vbnet
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.
/// Расширение для класса с данными
Class mvr.sys.cls.data [ Abstract ]
{

/// Дата модификации
Property changeDate As %Date(FORMAT = 3)[ 
	SqlComputeCode = { 
		Set {changeDate}=+$h 
	}, SqlComputed 
];

/// Время модификации
Property changeTime As %Time[ 
	SqlComputeCode = { 
		Set {changeTime}=$p($h,",",2)
	}, SqlComputed 
];

/// Сотрудник выполневший модификацию данных
Property changeEmployee As %String[ 
	SqlComputeCode = { 
		Set {changeEmployee}= ##class({%%CLASSNAME}).saveEmployee() 
	}, SqlComputed 
];

/// Записать пользователя
ClassMethod saveEmployee() As %String
{
	q:'$d(%session) ""
	s val=$g(%session.Data("userId"))
	q:val="" ""
	s val=##class(mvr.data.employee).%OpenId(val).name
	q val
}

}



Осталось разобраться с модификацией экземпляра. Дабы всё обновлялось и тогда...
...
Рейтинг: 0 / 0
Хранение истории изменений объектов
    #37671945
andrew_tsw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Update a timestamp property on UPDATE and INSERT via SqlComputeOnChange
Отличие в SqlComputeOnChange = (%%INSERT, %%UPDATE)
При работе через объекты тоже должно обновляться.
...
Рейтинг: 0 / 0
25 сообщений из 57, страница 1 из 3
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Хранение истории изменений объектов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]