Пример программирования web-сервиса на VIP |
Приведенный ниже пример предоставляет web-клиентам список названий имеющихся матценностей. Список матценностей хранится в таблице KatMc.
#include ISetData.vih #include IModify.vih #component 'CGoods' //************************************************************ web objInterface IGoods; property al_date : date; // atl_lastDate, atl_lastTime и atl_lastUser property al_time : time; // нужны для того, что бы отслеживать property al_user : comp; // пассивные блокировки в doSetData property id : comp; // это на самом деле NRec property name : string; // ограничимся наименованием // атрибут primary у индекса заставит web-сервисы // позиционироваться по Id перед вызовом DoSetData index byId = id(unique, primary); end; //************************************************************ web vipInterface VGoods implements ISetData, IGetHandle, IGoods, IModify; public: // конструктор по умолчанию constructor Init; // конструктор экземпляра constructor InitId(cId : comp); function ISetData.DoSetData(owner : ObjRef; positionExist : boolean) : longInt; end;
#include Goods.vih #component 'CGoods' //************************************************************ interface vGoods; var prev_date : date; // в этих переменных сохраняем var prev_time : time; // значения для последующего сравнения var prev_user : comp; // в doSetData // переменная нужна для реализации ISetData.modification var l_modification : boolean; // переменная нужна для реализации конструктора экземпляра InitId var l_id : comp; //------------------------------------------------------------ create view as select * from KatMc // понадобится когда будет использоваться конструктор экземпляра bounds byId = l_id == KatMc.NRec ; //------------------------------------------------------------ property ISetData.modification : boolean absolute l_modification; property IGoods.name : string absolute KatMc.Name; property IGoods.id : comp absolute KatMc.NRec; property IGoods.al_date : date read KatMc.atl_lastDate write prev_date := result; property IGoods.al_time : time read KatMc.atl_lastTime write prev_time := result; property IGoods.al_user : comp read KatMc.atl_lastUser write prev_user := result; index IGoods.byId auto; //------------------------------------------------------------ procedure IGetHandle.CreateHandle; { SetIfcHandleConstructorName('InitId'); AddIfcHandleParameter(l_Id); } //------------------------------------------------------------ procedure ISetData.OpenTransaction; { BeginTransaction(0); // поскольку OpenTransation вызывается только для заглавного объекта // нужно выставить modification в true, что бы DoSetData знала, что делать modification := true; } //------------------------------------------------------------ // сюда нам приходит код возврата, который мы вернем из DoSetData procedure ISetData.CloseTransaction (rCode : longInt); { if( rCode = tsOk ) EndTransaction else AbortTransaction; // делаем как было modification := false; } //------------------------------------------------------------ function ISetData.DoSetData (owner : ObjRef; positionExist : boolean) : longint; { // переменная l_modification выставляется в true в OpenTransaction для головного // объекта, или того подобъекта, который мы модифицируем. // Такая реализация позволяет использовать один и тот же объект как головной, // модифицируя его, так и как подобъект (ссылка) другого объекта. if (l_modification) { // Это наша внутренняя договоренность, если id = 0, то insert, иначе update if (id = 0) result := DoInsert; // вызываем стандарный insert else if ( prev_date = KatMc.atl_lastDate // так проверяем and prev_time = KatMc.atl_lastTime // пассивные блокировки and prev_user = KatMc.atl_lastUser) if (positionExist) result := DoUpdate; // вызываем стандарный update else result := tsInvalidPositioning; // уже удалили else result := tsConflict; // уже изменили // Это нужно, если был использован конструктор экземпляра, // или в нашем примере для работы createHandle if (result = tsOk) l_id := id; } // Если есть primary key - запись найдется автоматически, иначе можно искать // по какому-либо полю. Либо по договоренности (например наименование) // либо по тому, которое <> '' или 0, тогда можно будет указывать любой // уникальный атрибут, не зная id else { result := 0; if (not positionExist) id := 0; // лучше пусть будет нулевая ссылка, чем кривая } } //------------------------------------------------------------ constructor InitId( cId : comp ); { l_id := cId; pushBounds(tbbyId); result := true; } //------------------------------------------------------------ constructor Init; { id := 0; result := true; } //------------------------------------------------------------ function IModify.DoInsert : word; { result := insert current KatMc; } //------------------------------------------------------------ function IModify.DoUpdate : word; { result := update current KatMc; } //------------------------------------------------------------ function IModify.DoDelete : word; { result := delete current KatMc; } //------------------------------------------------------------ implementation IModify.DoFlush abstract; end.