Get class property position in storage $lb
I have a classname and a property name. I want to know, when I get object value directly from a global, which property corresponds to which position in the $lb structure.
Here's what I got so far:
Class Utils.Storage { /// write ##class(Utils.Storage).GetPosition() ClassMethod GetPosition(class As %Dictionary.CacheClassname = "Sample.Address", property As %Dictionary.CacheIdentifier = "Zip") As %Integer { set strategy = $$$comClassKeyGet(class, $$$cCLASSstoragestrategy) set strategyId = class _ "||" _ strategy &sql(SELECT Name INTO :position FROM %Dictionary.StorageDataValueDefinition WHERE parent = (SELECT ID FROM %Dictionary.StorageDataDefinition WHERE parent = :strategyId AND Structure = 'listnode') AND Value = :property) quit position } /// do ##class(Utils.Storage).Test() ClassMethod Test() { set list = $lb("Street", "City", "State", "Zip") set obj = ##class(Sample.Address).%New() Do obj.%SetSerial(list) set list2 = obj.%GetSerial() zw obj, list2 } }
Work example:
write ##class(Utils.Storage).GetPosition("Sample.Address","City") >2
It should work for everything, except:
- Array Of properties in persistent classes with default array STORAGEDEFAULT
- List Of properties in persistent classes with non-default array STORAGEDEFAULT
- Custom storage
- SQL storage
- Relationships
And that's okay, I only really need it for serial classes. But is there maybe a better way to get it?
UPD: Should probably check how it works with inheritance.
Hi Eduard!
Without going too deep into your code and trying to enhance it, I can suggest you to:
Of course, if this is a one-time thing, you could simply implement number 2. Or you could simply forget about my suggestion at all if performance isn't an issue for this scenario. By using a method generator, you eliminates from the runtime any inefficiency of the code used to (pre)compute the positions.
Kind regards,
AS
Hello, Amir!
That said I do agree that idea with method generators is good, just not applicable in this exact case.
Hi Eduard,
I fail to follow your reasoning. If you are making other classes inherit from a class of yours, you are changing the class by definition. You are adding a new method to the class. Whether this method is a simple method or has its code computed during class compilation is transparent to whomever is calling that method.
And the resulting method could return the information in any format you choose, including $LB.
Kind regards,
AS
I'm not adding any method to existing classes or adding new superclass.
Got it! :)
Hi Eduard !
Being a little bit lazy I simplified the query (for less typing)
My example:
where id [ 'Sample.Person'
And it works fine for persistent and serial classes.
My hidden assumption: there is only 1 Storage Strategy.
The nice point about:

you get also storage locations of deleted (!!) properties
that eventually might be invisible in class definition.
Social networks
InterSystems resources
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue