@@ -9,30 +9,42 @@ use sqlite::ResultCode;
9
9
use sqlite_nostd as sqlite;
10
10
use sqlite_nostd:: { Connection , Context , Value } ;
11
11
12
- use serde_json as json;
13
-
14
12
use crate :: create_sqlite_text_fn;
15
13
use crate :: error:: SQLiteError ;
16
14
17
15
/// Given any number of JSON TEXT arguments, merge them into a single JSON object.
18
16
///
19
- /// TODO: If we know these are all valid JSON objects, we could perhaps do string concatenation instead.
17
+ /// This assumes each argument is a valid JSON object, with no duplicate keys.
18
+ /// No JSON parsing or validation is performed - this performs simple string concatenation.
20
19
fn powersync_json_merge_impl (
21
20
_ctx : * mut sqlite:: context ,
22
21
args : & [ * mut sqlite:: value ] ,
23
22
) -> Result < String , SQLiteError > {
24
- let mut v_result = json:: Value :: Object ( json:: Map :: new ( ) ) ;
23
+ if args. is_empty ( ) {
24
+ return Ok ( "{}" . to_string ( ) ) ;
25
+ }
26
+ let mut result = String :: from ( "{" ) ;
25
27
for arg in args {
26
- let v: json:: Value = json:: from_str ( arg. text ( ) ) ?;
27
- if let json:: Value :: Object ( map) = v {
28
- for ( key, value) in map {
29
- v_result[ key] = value;
30
- }
31
- } else {
28
+ let chunk = arg. text ( ) ;
29
+ if chunk. is_empty ( ) || !chunk. starts_with ( '{' ) || !chunk. ends_with ( '}' ) {
32
30
return Err ( SQLiteError :: from ( ResultCode :: MISMATCH ) ) ;
33
31
}
32
+
33
+ // Strip outer braces
34
+ let inner = & chunk[ 1 ..( chunk. len ( ) - 1 ) ] ;
35
+
36
+ // If this is not the first chunk, insert a comma
37
+ if result. len ( ) > 1 {
38
+ result. push ( ',' ) ;
39
+ }
40
+
41
+ // Append the inner content
42
+ result. push_str ( inner) ;
34
43
}
35
- return Ok ( v_result. to_string ( ) ) ;
44
+
45
+ // Close the outer brace
46
+ result. push ( '}' ) ;
47
+ Ok ( result)
36
48
}
37
49
38
50
create_sqlite_text_fn ! (
0 commit comments