Skip to content

Commit 80d8764

Browse files
committed
Enhance SetValueAt method for JSON manipulation; add error handling and support for insert, remove, and append actions. Introduce unit tests for ComplexTransform.
1 parent a0a93d1 commit 80d8764

File tree

2 files changed

+87
-23
lines changed

2 files changed

+87
-23
lines changed

src/iop/cls/IOP/Message.cls

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -157,58 +157,99 @@ Method CopyValues(
157157
Return tSC
158158
}
159159

160+
/// Sets a value at the specified property path in the JSON document
161+
/// @param pValue Value to set
162+
/// @param pPropertyPath Path to the property (e.g. "property1.property2" or "array()")
163+
/// @param pAction Action to perform ("set", "append", "remove", "insert")
164+
/// @param pKey Optional key for specialized operations, required for insert
165+
/// @returns %Status
160166
Method SetValueAt(
161167
pValue As %String = "",
162168
pPropertyPath As %String = "",
163169
pAction As %String = "set",
164170
pKey As %String = "") As %Status
165171
{
166172
Set tSC = $$$OK
167-
// if pAction is set, use jsonpath to set the value
168173
Try {
169-
if pAction = "append" {
170-
// trinm () from the end of the path
171-
if $EXTRACT(pPropertyPath, *) = ")" {
172-
Set pPropertyPath = $EXTRACT(pPropertyPath, 1, $LENGTH(pPropertyPath)-2)
173-
}
174-
}
175-
// Convert pPropertyPath to a a jsonpath
176-
Set tPath = ..ConvertPath(pPropertyPath)
174+
// Validate input parameters
175+
If pPropertyPath = "" Return $$$ERROR($$$GeneralError, "Property path cannot be empty")
176+
If '$LISTFIND($LISTBUILD("set","append","remove","insert"), pAction) Return $$$ERROR($$$GeneralError, "Invalid action: "_pAction)
177+
If (pAction = "insert") && (pKey = "") Return $$$ERROR($$$GeneralError, "Key is required for insert action")
177178

179+
// Initialize Python objects
178180
Set pyjson = ##class(%SYS.Python).Import("json")
179181
Set jp = ##class(%SYS.Python).Import("jsonpath_ng")
180182
Set builtins = ##class(%SYS.Python).Builtins()
181183

182-
// By default, if json is empty, set it to an empty object
183-
if ..json = "" {
184-
Set ..json = "{}"
184+
// Handle append operations
185+
Set tAppend = (pAction = "append")
186+
If tAppend, $EXTRACT(pPropertyPath, *-1, *) = "()" {
187+
Set pPropertyPath = $EXTRACT(pPropertyPath, 1, *-2)
185188
}
186-
Set tJSON = pyjson.loads(..json)
187189

190+
// Initialize empty JSON if needed
191+
Set:..json="" ..json = "{}"
192+
193+
// Parse JSON and prepare path
194+
Set tJSON = pyjson.loads(..json)
195+
Set tPath = ..ConvertPath(pPropertyPath)
188196
Set parser = jp.parse(tPath)
189-
if pAction = "set" {
197+
198+
If pAction = "set" {
199+
// Simple set operation
190200
Set tJSON = parser."update_or_create"(tJSON, pValue)
191201
}
192-
ElseIf pAction = "append" {
202+
ElseIf pAction = "remove" {
203+
// Remove operation
204+
Set matches = parser.find(tJSON)
205+
If matches."__len__"() > 0 {
206+
// Not yet implemented
207+
Set tSC = $$$ERROR($$$GeneralError, "Remove operation not yet implemented")
208+
}
209+
}
210+
ElseIf pAction = "insert" {
211+
// Handle dictionary insert/update
212+
Set matches = parser.find(tJSON)
213+
If matches."__len__"() = 0 {
214+
// Create new dictionary if path doesn't exist
215+
Set tDict = builtins.dict()
216+
Do tDict."__setitem__"(pKey, pValue)
217+
Set tJSON = parser."update_or_create"(tJSON, tDict)
218+
}
219+
Else {
220+
// Update existing dictionary
221+
Set tDict = matches."__getitem__"(0)."value"
222+
Do tDict."__setitem__"(pKey, pValue)
223+
Set tJSON = parser."update"(tJSON, tDict)
224+
}
225+
}
226+
ElseIf tAppend {
227+
// Handle append operation
193228
Set tFindValue = parser."find"(tJSON)
194-
if tFindValue."__len__"() = 0 {
195-
Set tList = builtins.list()
196-
Do tList.append(pValue)
197-
Set tJSON = parser."update_or_create"(tJSON,tList)
229+
If tFindValue."__len__"() = 0 {
230+
// Create new array if path doesn't exist
231+
Set:(tAppend) tValue = builtins.list()
232+
Do:tAppend tValue.append(pValue)
233+
Set tJSON = parser."update_or_create"(tJSON, $Select(tAppend: tValue, 1: pValue))
198234
}
199235
Else {
236+
// Append to existing array
200237
Do tFindValue."__getitem__"(0)."value".append(pValue)
201238
Set tJSON = parser."update"(tJSON, tFindValue."__getitem__"(0)."value")
202239
}
203240
}
204241

205-
Set tResult = pyjson.dumps(tJSON)
206-
Set ..json = tResult
242+
// Update JSON storage
243+
Set ..json = pyjson.dumps(tJSON)
207244
Set ..classname = ..DocType
208-
209-
} Catch ex {
245+
246+
}
247+
Catch ex {
210248
Set tSC = ex.AsStatus()
249+
// Log error details
250+
$$$LOGWARNING("Error in SetValueAt: "_$System.Status.GetErrorText(tSC))
211251
}
252+
212253
Return tSC
213254
}
214255

src/tests/cls/ComplexTransform.cls

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Class UnitTest.ComplexTransform Extends Ens.DataTransformDTL [ DependsOn = IOP.Message ]
2+
{
3+
4+
Parameter IGNOREMISSINGSOURCE = 1;
5+
6+
Parameter REPORTERRORS = 1;
7+
8+
Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;
9+
10+
XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
11+
{
12+
<transform sourceClass='IOP.Message' targetClass='IOP.Message' sourceDocType='registerFilesIop.message.ComplexMessage' targetDocType='registerFilesIop.message.ComplexMessage' create='new' language='objectscript' >
13+
<assign value='source.{post}' property='target.{post}' action='set' />
14+
<foreach property='source.{list_str()}' key='k1' >
15+
<assign value='source.{list_str(k1)}_"foo"' property='target.{list_str()}' action='append' />
16+
</foreach>
17+
<foreach property='source.{list_post()}' key='k2' >
18+
<assign value='source.{list_post().Title}' property='target.{list_post(k2).Title}' action='append' />
19+
</foreach>
20+
</transform>
21+
}
22+
23+
}

0 commit comments

Comments
 (0)