Is there a way to map a $lb() to its data model ?

Hi all,

 

We faced a problem where we would like to map a $lb object to its corresponding data model structure in order to later on export it as JSON.

 

So imagin that we have something like this that actually maps to a persistent table with its structure. 

$lb("",,,,,"",,,"BOOLEAN","0",2,2,"1",,"bla",$lb(,,"bla","20050502123400"),"",1,"bla",,0)   

Is there a way to transform this $lb (without the need of openig the object itself) to a JSON object with the proper table fields as properties?

 

Many thanks

Answers

l=$lb("",,,,,"",,,"BOOLEAN","0",2,2,"1",,"bla",$lb(,,"bla","20050502123400"),"",1,"bla",,0)
jsonStr=[(l)].%ToJSON()
jsonStr,!!
   
obj=[].%FromJSON(jsonStr)
list=obj."0"
zw list

Result:
["\u0002\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0001\u0001\t\u0001BOOLEAN\u0003\u00010\u0003\u0004\u0002\u0003\u0004\u0002\u0003\u00011\u0001\u0005\u0001bla\u0019\u0001\u0001\u0001\u0005\u0001bla\u0010\u000120050502123400\u0002\u0001\u0003\u0004\u0001\u0005\u0001bla\u0001\u0002\u0004"]
 
list=$lb("",,,,,"",,,"BOOLEAN","0",2,2,"1",,"bla",$lb(,,"bla","20050502123400"),"",1,"bla",,0)

Object serialized to $lb does not contain metainformation about properties, etc.

You can write a method generator that would iterate over storage schema and generate a method that gets id of object as an input, retrieves $lb value and outputs it as JSON.

Comments

Jose,

how would you determine names of properties / keys for a JSON name:value pairs without opening an object instance or retrieving those names from somewhere else?

or are you happy to express it as JSON ARRAY ?

Well...  I meant that maybe this $lb object is not longer the current value of the object instance so opening that ID may not return the same as the $lb, that's the reason...

 

I don't understand what do you mean with JSON ARRAY... As long as we are able to to se a key:value object of the data on $lb...

 

Thnks

Jose, $lb() holds STORED values of you object instance. If your opened instance modified property(ies) then I see no point of looking into stored data, just serialize you IN-MEMORY values to JSON.

On the other hand, if a process A opened and modified instance of the object and without saving and you want to serialize the same instance from process B, then again, there is no difference between opening an object instance or using some custom serialization directly from stored data.

It is not good practice anyway to keep objects opened for a long time without saving their new values.

lastly, my comment about JSON array was that JSON array doesn't need to know the name in the name:value pair so you can easily write a custom JSON serializer to serialize directly $lb() into JSON array.

 

 

maybe I missed your original business case need, can you explain why current implementation is not good enough for you?

Hi Daniel,

I would try to explain better:

The $lb it's an old value of one register of my table "Table" that is:  SQLUser^TableD(1) = $lb("",,,,,"",,,"BOOLEAN","0",2,2,"1",,"bla",$lb(,,"bla","20050502123400"),"",1,"bla",,0)  

 

As you can imagin, my table "Table" has its properties (Fields) that match the $lb fields. What I would like is to get a JSON object of those properties and the values of my old $lb so I have something like:

{

Field1:"",

Field2:,

....

Field7:"BOOLEAN",

Field12:

{

Field121:"bla",

...

}

...

}

 

Kind regards

You can use value positioning to match their $list index according to their property definition index. But you will need to describe each property to detect their types and if they are instantiable. In case they do, you can use the value to open the instance and the property type. E.g:

set properties = ##class(%Dictionary.CompiledClass).%OpenId("SQLUser.Table").Properties

for i=1:1:propeties.Count() {
    set listValue = $lg(SQLUser^TableD(1) , i)

    set property = propeties.GetAt(i)
   // if property.Type  inherits from %RegisteredObject
   set value = $System.OBJ.OpenId(property.Type, listValue)
  // else 
   set value = listValue
}

If you don't want to open the class descriptor instance you can also use macros from %occReference.inc. But you will have to deal with $order.

My suggestion takes the longest path. You will need a method that supports each property type behavior,  like that lb(,,"bla","20050502123400").

But why can't you use an instance? Is it because the structure is too old and there isn't any %Persistent class to represent it?

Can you provide your system $ZV version?

>Is there a way to transform this $lb (without the need of openig the object itself) to a JSON object with the proper table fields as properties?

Is there a good reason for not wanting to open the object?

If not, there are several ways to spin the object into JSON.