Add json_object_update_{existing,missing}
authorPetri Lehtinen <petri@digip.org>
Tue, 24 Jan 2012 19:03:36 +0000 (21:03 +0200)
committerPetri Lehtinen <petri@digip.org>
Tue, 24 Jan 2012 19:03:36 +0000 (21:03 +0200)
Closes #37.

doc/apiref.rst
src/jansson.h
src/value.c
test/suites/api/check-exports
test/suites/api/test_object.c

index 3820b3f..f65dc5d 100644 (file)
@@ -564,6 +564,21 @@ Unicode string and the value is any JSON value.
    Update *object* with the key-value pairs from *other*, overwriting
    existing keys. Returns 0 on success or -1 on error.
 
+.. function:: int json_object_update_existing(json_t *object, json_t *other)
+
+   Like :func:`json_object_update()`, but only the values of existing
+   keys are updated. No new keys are created. Returns 0 on success or
+   -1 on error.
+
+   .. versionadded:: 2.3
+
+.. function:: int json_object_update_missing(json_t *object, json_t *other)
+
+   Like :func:`json_object_update()`, but only new keys are created.
+   The value of any existing key is not changed. Returns 0 on success
+   or -1 on error.
+
+   .. versionadded:: 2.3
 
 The following macro can be used to iterate through all key-value pairs
 in an object.
index 274dbad..55c618d 100644 (file)
@@ -130,6 +130,8 @@ int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
 int json_object_del(json_t *object, const char *key);
 int json_object_clear(json_t *object);
 int json_object_update(json_t *object, json_t *other);
+int json_object_update_existing(json_t *object, json_t *other);
+int json_object_update_missing(json_t *object, json_t *other);
 void *json_object_iter(json_t *object);
 void *json_object_iter_at(json_t *object, const char *key);
 void *json_object_key_to_iter(const char *key);
index eadf596..2018c4d 100644 (file)
@@ -149,6 +149,38 @@ int json_object_update(json_t *object, json_t *other)
     return 0;
 }
 
+int json_object_update_existing(json_t *object, json_t *other)
+{
+    const char *key;
+    json_t *value;
+
+    if(!json_is_object(object) || !json_is_object(other))
+        return -1;
+
+    json_object_foreach(other, key, value) {
+        if(json_object_get(object, key))
+            json_object_set_nocheck(object, key, value);
+    }
+
+    return 0;
+}
+
+int json_object_update_missing(json_t *object, json_t *other)
+{
+    const char *key;
+    json_t *value;
+
+    if(!json_is_object(object) || !json_is_object(other))
+        return -1;
+
+    json_object_foreach(other, key, value) {
+        if(!json_object_get(object, key))
+            json_object_set_nocheck(object, key, value);
+    }
+
+    return 0;
+}
+
 void *json_object_iter(json_t *json)
 {
     json_object_t *object;
index 0af0dd0..a7c87a9 100755 (executable)
@@ -1,7 +1,6 @@
 #!/bin/sh
 
-# This tests checks that the libjansson.so exports the correct
-# symbols.
+# This test checks that libjansson.so exports the correct symbols.
 
 # The list of symbols that the shared object should export
 sort >$test_log/exports <<EOF
@@ -38,6 +37,8 @@ json_object_set_new_nocheck
 json_object_del
 json_object_clear
 json_object_update
+json_object_update_existing
+json_object_update_missing
 json_object_iter
 json_object_iter_at
 json_object_iter_next
index 4a19016..e7ffd0d 100644 (file)
@@ -139,6 +139,48 @@ static void test_update()
     json_decref(object);
 }
 
+static void test_conditional_updates()
+{
+    json_t *object, *other;
+
+    object = json_pack("{sisi}", "foo", 1, "bar", 2);
+    other = json_pack("{sisi}", "foo", 3, "baz", 4);
+
+    if(json_object_update_existing(object, other))
+        fail("json_object_update_existing failed");
+
+    if(json_object_size(object) != 2)
+        fail("json_object_update_existing added new items");
+
+    if(json_integer_value(json_object_get(object, "foo")) != 3)
+        fail("json_object_update_existing failed to update existing key");
+
+    if(json_integer_value(json_object_get(object, "bar")) != 2)
+        fail("json_object_update_existing updated wrong key");
+
+    json_decref(object);
+
+    object = json_pack("{sisi}", "foo", 1, "bar", 2);
+
+    if(json_object_update_missing(object, other))
+        fail("json_object_update_missing failed");
+
+    if(json_object_size(object) != 3)
+        fail("json_object_update_missing didn't add new items");
+
+    if(json_integer_value(json_object_get(object, "foo")) != 1)
+        fail("json_object_update_missing updated existing key");
+
+    if(json_integer_value(json_object_get(object, "bar")) != 2)
+        fail("json_object_update_missing updated wrong key");
+
+    if(json_integer_value(json_object_get(object, "baz")) != 4)
+        fail("json_object_update_missing didn't add new items");
+
+    json_decref(object);
+    json_decref(other);
+}
+
 static void test_circular()
 {
     json_t *object1, *object2;
@@ -460,6 +502,7 @@ static void run_tests()
     test_misc();
     test_clear();
     test_update();
+    test_conditional_updates();
     test_circular();
     test_set_nocheck();
     test_iterators();