%session.Data with unlimited amount of indexes
Let's imagine you have to implement a method with a definition
/// Set value to %session.Data ClassMethod setValue(params...) As %Status { }
How it should work
do ..setValue("key1", "val")
is equal to
set %session.Data("key1") = "val"
and
do ..setValue("key1", "key2", "key3", "key4", "val")
is equal to
set %session.Data("key1", "key2", "key3", "key4") = "val"
so, quite simple, any amount of arguments, while the latest one is a value, and any previous is an index, should accept at least 2 arguments.
How would you implement this method?
/// Set value to %session.Data ClassMethod setValue(params...) As %Status { quit:params<2 0 set var="%session.Data(" for i=1:1:params-1 set var=var_""""_params(i)_"""," set $e(var,*)=")" set @var=params(params) quit $$$OK }
Quite simple, but could be even better, with no useless quotations
did you mean that ?
/// Set value to %session.Data ClassMethod setValue(params...) As %Status { quit:params<2 0 set var="%session.Data(" for i=1:1:params-1 set var=var_"params("_i_")," set $e(var,*)=")" set @var=params(params) quit $$$OK }
Nope, still not what I mean, I have a better solution, just would like to see if the community will find it.
it doesn' trap this cases yet
do ..setValue("key1", "key2", , "key4", "val") do ..setValue("key1", "key2", "", "key4", "val")
It's easier ?
```
ClassMethod setValue(params...) As %Status
{
quit:params<2 0
s name="%session.Data"
for i=1:1:params-1 set:$GET(params(i))'="" name=$NA(@name@(params(i)))
set @name=params(params)
quit $$$OK
}
```
Yes, this is better, I would even use this
@Sergey Mikhailenko
Check your code:
Do ..setValue() Do ..setValue("key1", "key2", , "key4", "val")
with error trapping
/// Set value to %session.Data ClassMethod setValue(params...) As %Status { try { set var=$name(%session.Data) for i=1:1:params-1 set var=$name(@var@(params(i))) set @var=$g(params(params)) set status=$$$OK } catch { set status=$system.Status.Error(710) } quit status }
I'm not sure about what you mean with "unlimited amount of indexes"...
first, there is a limit of 255 for the parameters, this means you can have
do ..setValue(key1,key2,...key254,value)
but you can't have
do ..setValue(key1,key2,...key254,key255,value)
second, if you meant to have many-many values (in sense of, we have to much data)
do ..setValue(key1,value1) do ..setValue(key2,value2) // etc.
then, at some point you will reach the and of the available RAM (incl. swap/paging space. Usually swap/paging space is much less then the space for the real data).
thirdly, if you meant variable number of indexes (in sense of variable number of parameters) then I can just refine Robert's solution to
ClassMethod setValue(params...) As %Status { set base=$name(%session.Data) for i=1:1:params-1 { set base=$name(@base@(params(i))) set @base=params(params) quit 1 }
In case, you have both, variable number of indices and too much data then you could use a mix of the above with data placed in a temp file.
Somewhere, at the program start, let you point %sessionData to a temp file
set %sessionData=$nam(^||SessionTemp)
and then consider this in the setValue method
ClassMethod setValue(params...) As %Status { set bas=%sessionData ... }
Of course, in your application, you have to change only those %session.Data(...) to @%sessionData@(...) which uses the "variable-big-data" part of %session.Data(). All other (the standard ones) stay unchanged.
For sure, you have good points, but some points just out of scope at all. Yes, it's limited anyway.
My main point is to not have a limited number of parameters like below
ClassMethod setValue(key1, key2, key3, key4, value) As %Status
And I was just curious if the community knows how to deal with MultiDimensional property, in such a case.
Sorry, I don't quite get you.
One used to say, if I don't understand something, then this something is either too complicated or very simple. So where belongs your case?
Sorry, it's just for discussion, to see how people would do some simple task.
I'd mimic %DispatchSetMultidimProperty signature. Shame local cannot be casted into a multi-argument call. Wrap in $g if values can be skipped.
/// do ##class().Test() ClassMethod Test() { kill ^data do ..setValue("val", "key1") do ..setValue("val", "key1", "key2", "key3", "key4") zw ^data } ClassMethod setValue(val, args...) { if args=1 { set ^data(args(1)) = val } elseif args=2 { set ^data(args(1), args(2)) = val } elseif args=3 { set ^data(args(1), args(2), args(3)) = val } elseif args=4 { set ^data(args(1), args(2), args(3), args(4)) = val } }
Another option just for the fun: