#1 2015-05-28 11:34:03

CycleSoft
Member
Registered: 2013-01-18
Posts: 34

Interface service with Legacy DB

First of all I want to thanks the man who made my job easier and enjoyable: Thanks Arnaud!

I'm writing an interface based service to provide a REST access to a legacy DB (so no ORM here), using DTO as parameters to move data around, and everything is fine.

Since some DTO is quite complex (with nested objects and array of objects), I'd like to execute updates  and/or inserts on the underling DB only if strictly needed, that is only if the client has really modified a certain sub-property.

So for example if in a DTO there is an array property, and I call a service using PUT passing a JSON representation of that DTO with this property 'missing' (not an empty array, [], but nothing at all), this should be interpreted as 'leave that property/array as is, don't touch it', avoiding maybe a lot of SQL statements.
The JSON object is deserialized into my DTO, but I lose the knowledge of the existence or not of the property in the original JSON object

Since mORMot is a really smart pet,  I suspect there is some way to achieve that goal.... or am I missing something?

Many thanks!

Guido

Offline

#2 2015-05-28 15:48:38

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Interface service with Legacy DB

You may be able to put the exact JSON representation using either RawJSON or a TDocVariant kind of variant.

Or, you could use sicClientDriven kind of interface service, then use the methods to maintain a state of the modifications.

Offline

#3 2015-06-05 13:05:36

CycleSoft
Member
Registered: 2013-01-18
Posts: 34

Re: Interface service with Legacy DB

Tanks ab!
It took me a while to experiment a little. Here is how I done it:

The method is defined as

MyInterface.MyMethod(MyParam: RawJSON);

in the implemetation I have

var
  MyVariable: variant;
begin
  MyVariable := _Json(MyParam);
  // now I can do thing like
  if MyVariable.Exists('PropertyName') then;

end;

and thus run only needed SQL statements. Great!

Offline

#4 2015-06-05 13:25:54

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Interface service with Legacy DB

Or you may use a TDocVariantData variable, which may be preferred in your case: MyVariable.Exists() is a pseudo-method, using late binding.

Offline

#5 2015-06-09 12:22:53

CycleSoft
Member
Registered: 2013-01-18
Posts: 34

Re: Interface service with Legacy DB

Do you mean something like this ?

var
  MyVariable: TDocVariantData;
begin
  MyVariable :=  TDocVariantData.InitJSON(MyParam);
  // now I can do thing like
  if MyVariable.GetValueIndex('PropertyName') <> -1 then;

end;

Offline

#6 2015-06-09 13:13:00

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Interface service with Legacy DB

Indeed!

Offline

#7 2015-06-10 08:24:55

CycleSoft
Member
Registered: 2013-01-18
Posts: 34

Re: Interface service with Legacy DB

An edit for the readers: the correct initialization code for MyVariable  is

MyVariable.InitJSON(MyParam);

Offline

#8 2015-06-10 08:40:19

CycleSoft
Member
Registered: 2013-01-18
Posts: 34

Re: Interface service with Legacy DB

I converted the code as suggested by you, but I can't figure out how handle the case of a property of kind array, without passing to another string/json initialization:

For example in the case of a JSON object like this:

{
"OrderNo": "123",
"Items2: [
    {"Description": "Item 1", "Quantity": 10},
    {"Description": "Item 2", "Quantity": 20}
  ]
}

I check if the property Items is present with

  if MyVariable.GetValueIndex('Items') > -1 then ...

and then how I can access each single Item?

So far the only solution I found is to assign the value of the property Items to a string variable, obtaining the JSON representation of the array, and then initialize another TDocVariantData variable with that string.

Is it the only way or there is something smarter?

Last edited by CycleSoft (2015-06-10 08:40:48)

Offline

#9 2015-06-10 09:10:18

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Interface service with Legacy DB

The Variants[] property would give direct access, from its index, to the corresponding TDocVariantData storing the nested array.

Offline

Board footer

Powered by FluxBB