Skip to content

Commit ca7954c

Browse files
committed
Add GetNextIndex method and enhance SetValueAt for array handling; update tests for new functionality
1 parent 0ea4148 commit ca7954c

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/iop/cls/IOP/Message.cls

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Class IOP.Message Extends (Ens.MessageBody, %CSP.Page, %XML.Adaptor, Ens.VDoc.Interface)
1+
Class IOP.Message Extends (Ens.MessageBody, %CSP.Page, Ens.VDoc.Interface)
22
{
33

44
Parameter DOCCLASSNAME = "JSON Document";
@@ -27,6 +27,19 @@ Property jstr As %Stream.GlobalCharacter [ Internal, Private ];
2727

2828
Property type As %String(MAXLEN = 6) [ ReadOnly ];
2929

30+
/// Gets the next index in an array
31+
Method GetNextIndex(
32+
pPath As %String,
33+
pIndex As %String,
34+
ByRef pStatus As %Status = {$$$OK}) As %String
35+
{
36+
Set f=$F(pPath,"()") If 'f Set pStatus=$$$ERROR($$$EnsErrGeneral,"Can't iterate on no-array type '"_pPath_"'") Quit ""
37+
if pIndex="" Set pIndex=1
38+
Set tValue = ..GetValueAt($EXTRACT(pPath, 1, $LENGTH(pPath)-2))
39+
if pIndex>$LENGTH(tValue) Quit ""
40+
Quit pIndex+1
41+
}
42+
3043
Method GetValueAt(
3144
pPropertyPath As %String = "",
3245
pFormat As %String,
@@ -152,13 +165,20 @@ Method SetValueAt(
152165
Set tSC = $$$OK
153166
// if pAction is set, use jsonpath to set the value
154167
Try {
168+
if pAction = "append" {
169+
// trinm () from the end of the path
170+
if $EXTRACT(pPropertyPath, *) = ")" {
171+
Set pPropertyPath = $EXTRACT(pPropertyPath, 1, $LENGTH(pPropertyPath)-2)
172+
}
173+
}
155174
// Convert pPropertyPath to a a jsonpath
156175
Set tPath = ..ConvertPath(pPropertyPath)
157176

158177
Set pyjson = ##class(%SYS.Python).Import("json")
159178
Set jp = ##class(%SYS.Python).Import("jsonpath_ng")
160179
Set builtins = ##class(%SYS.Python).Builtins()
161180

181+
// By default, if json is empty, set it to an empty object
162182
if ..json = "" {
163183
Set ..json = "{}"
164184
}
@@ -168,6 +188,18 @@ Method SetValueAt(
168188
if pAction = "set" {
169189
Set tJSON = parser."update_or_create"(tJSON, pValue)
170190
}
191+
ElseIf pAction = "append" {
192+
Set tFindValue = parser."find"(tJSON)
193+
if tFindValue."__len__"() = 0 {
194+
Set tList = builtins.list()
195+
Do tList.append(pValue)
196+
Set tJSON = parser."update_or_create"(tJSON,tList)
197+
}
198+
Else {
199+
Do tFindValue."__getitem__"(0)."value".append(pValue)
200+
Set tJSON = parser."update"(tJSON, tFindValue."__getitem__"(0)."value")
201+
}
202+
}
171203

172204
Set tResult = pyjson.dumps(tJSON)
173205
Set ..json = tResult

src/tests/test_iop_dtl.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ def test_get_value_at(iop_message, json_data, path, expected):
4141

4242
@pytest.mark.parametrize("json_data,path,value,action,key,expected_json", [
4343
('{"string":"Foo", "integer":42}', 'string', 'Bar', 'set', None, '{"string":"Bar", "integer":42}'),
44-
(r'{"post":{"Title":"Foo"}}', 'post.Title', 'Bar', 'set', None, r'{"post":{"Title":"Bar"}}')
44+
(r'{"post":{"Title":"Foo"}}', 'post.Title', 'Bar', 'set', None, r'{"post":{"Title":"Bar"}}'),
45+
(r'{}', 'post.Title', 'Bar', 'set', None, r'{"post":{"Title":"Bar"}}'),
46+
(r'{}', 'post()', 'Bar', 'append', None, r'{"post":["Bar"]}'),
47+
(r'{"post":["Foo"]}', 'post()', 'Bar', 'append', None, r'{"post":["Foo","Bar"]}'),
4548
])
4649
def test_set_value_at(iop_message, json_data, path, value, action, key, expected_json):
4750
iop_message.json = json_data
4851
iop_message.classname = 'foo'
49-
iop_message.SetValueAt(value, path, action, key)
52+
_Utils.raise_on_error(iop_message.SetValueAt(value, path, action, key))
5053
assert json.loads(iop_message.json) == json.loads(expected_json)
5154

5255
@pytest.mark.parametrize("json_data,classname,transform_class,expected_value", [

0 commit comments

Comments
 (0)