← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/jsoniq-library-functions into lp:zorba

 

Ghislain Fourny has proposed merging lp:~zorba-coders/zorba/jsoniq-library-functions into lp:zorba.

Requested reviews:
  Chris Hillery (ceejatec)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/jsoniq-library-functions/+merge/119347

Adding missing JSONiq library functions.
-- 
https://code.launchpad.net/~zorba-coders/zorba/jsoniq-library-functions/+merge/119347
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/org/jsoniq/www/functions.xq'
--- modules/org/jsoniq/www/functions.xq	2012-07-11 15:38:39 +0000
+++ modules/org/jsoniq/www/functions.xq	2012-08-13 13:24:24 +0000
@@ -135,3 +135,108 @@
  :)
 declare function jn:flatten($a as array()) as item()* external;
 
+(:~
+ : This function allows dynamic object construction by merging all
+ : its object parameters into a single object with a so-called "simple
+ : object union". A simple object union creates a new object, the pairs
+ : property of which is obtained by accumulating the pairs of all operand
+ : objects. An error jerr:JNDY0003 is raised if two pairs with the same
+ : name are encountered.
+ :
+ : @param $o A sequence of objects.
+ : @return The simple object union.
+ :)
+declare function jn:object($o as object()*) as object()
+{
+  {| $o |}
+};
+
+(:~
+ : This function dynamically builds an object, like jn:object, except that
+ : it does not throw an error upon pair collision. Instead, it aggregates them
+ : into an array.
+ :
+ : @param $o A sequence of objects.
+ : @return The accumulated object.
+ :)
+declare function jn:accumulate($o as object()*) as object()
+{
+  {[ $o ]}
+};
+
+(:~
+ : This function returns all Objects contained within a JSON item, regardless of
+ : depth.
+ :
+ : @param A JSON item.
+ : @return Its descendant objects.
+ :)
+declare function jn:descendant-objects($i as json-item()) as object()*
+{
+  if ($i instance of object())
+  then
+    (
+      $i,
+      for $v in jn:values($i)
+      where $v instance of json-item()
+      return jn:descendant-objects($v)
+    )
+  else if ($i instance of array())
+  then
+    (
+      for $v in jn:members($i)
+      where $v instance of json-item()
+      return jn:descendant-objects($v)
+    )
+  else
+    ()
+};
+
+(:~
+ : This function returns all pairs contained within an object, recursively.
+ :
+ : @param An object.
+ : @return All direct and indirect descendant pairs.
+ :)
+declare function jn:descendant-pairs($o as object())
+{
+  for $k in jn:keys($o)
+  return (
+    { $k : $o($k) },
+    if ($o($k) instance of object())
+    then
+      jn:descendant-pairs($o($k))
+    else ()
+  )
+};
+
+(:~ This function returns the intersection of two objects, and aggregates
+ : values corresponding to the same name into an array.
+ :
+ : @param $o A sequence of objects.
+ : @return Their insersection.
+ :)
+declare function jn:intersect($o as object()*)
+{
+  {|
+    let $common-keys := jn:keys($o[1])[ every $object in $o[position() > 1]
+                                           satisfies jn:keys($object) = . ]
+    for $key in $common-keys
+    let $values := $o($key)
+    return
+      if (count($values) eq 1)
+      then { $key : $values }
+      else { $key : [ $values ] }
+  |}
+};
+
+(:~
+ : This functions returns all values in an Object.
+ : @param $i An object.
+ : @return Its values.
+ :)
+declare function jn:values($i as object()) as item()*
+{
+  for $k in jn:keys($i)
+  return $i($k)
+};
\ No newline at end of file

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2012-07-24 08:48:48 +0000
+++ src/context/static_context.cpp	2012-08-13 13:24:24 +0000
@@ -467,6 +467,9 @@
 #ifndef ZORBA_NO_FULL_TEXT
             ns == ZORBA_FULL_TEXT_FN_NS ||
 #endif /* ZORBA_NO_FULL_TEXT */
+#ifndef ZORBA_WITH_JSON
+            ns == JSONIQ_FN_NS ||
+#endif /* ZORBA_WITH_JSON */
             ns == ZORBA_XML_FN_NS);
   } 
   else if (ns == W3C_FN_NS || ns == XQUERY_MATH_FN_NS)

=== removed directory 'src/runtime/spec/json.moved'
=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/jn_accumulate.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/jn_accumulate.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/jn_accumulate.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+{ "n1" : { "JSONiq XDM node" : "<node>10</node>" }, "n2" : { "JSONiq XDM node" : "<node>20</node>" } }

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_objects.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_objects.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_objects.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar", "bar" : { "foo" : [ 1 ] }, "foobar" : "foo" }{ "foo" : [ 1 ] }

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_pairs.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_pairs.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/jn_descendant_pairs.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar" }{ "bar" : { "foo" : [ 1 ] } }{ "foo" : [ 1 ] }{ "foobar" : "foo" }
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/jn_intersect.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/jn_intersect.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/jn_intersect.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+{ "bar" : [ { "foo" : [ 1 ] }, { "bar" : [ 2 ] }, [ "this" ] ] }
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/jn_values.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/jn_values.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/jn_values.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+bar{ "foo" : [ 1 ] } foo

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/object_03.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/object_03.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/object_03.xml.res	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+{ "toaster" : 200, "blender" : 250, "shirt" : 10, "socks" : 510, "broiler" : 20 }

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_accumulate.spec'
--- test/rbkt/Queries/zorba/jsoniq/jn_accumulate.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_accumulate.spec	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+Serialization: method=json jsoniq-extensions=yes

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_accumulate.xq'
--- test/rbkt/Queries/zorba/jsoniq/jn_accumulate.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_accumulate.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,16 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+declare variable $xdoc :=
+<nodes>
+<node>10</node>
+<node>20</node>
+</nodes>;
+
+variable $obj :=  
+jn:accumulate( 
+  for $node at $pos in $xdoc//node 
+  return { concat("n", $pos) : $node } 
+);
+
+$obj
+

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.spec'
--- test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.spec	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+Serialization: method=json jsoniq-multiple-items=appended

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.xq'
--- test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_descendant_objects.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,10 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+let $object :=
+{
+ "foo" : "bar",
+ "bar" : { "foo" : [1] },
+ "foobar" : "foo" 
+}
+return jn:descendant-objects($object)
+

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.spec'
--- test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.spec	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+Serialization: method=json jsoniq-multiple-items=appended

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.xq'
--- test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_descendant_pairs.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,10 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+let $object :=
+{
+ "foo" : "bar",
+ "bar" : { "foo" : [1] },
+ "foobar" : "foo" 
+}
+return jn:descendant-pairs($object)
+

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_intersect.xq'
--- test/rbkt/Queries/zorba/jsoniq/jn_intersect.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_intersect.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,20 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+let $object :=
+{
+ "foo" : "bar",
+ "bar" : { "foo" : [1] },
+ "foobar" : "foo" 
+}
+let $object2 :=
+{
+ "bar" : { "bar" : [2] },
+ "foobar" : "foo" 
+}
+let $object3 :=
+{
+ "foo" : "bar",
+ "bar" : [ "this" ]
+}
+return jn:intersect(($object, $object2, $object3))
+

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_values.spec'
--- test/rbkt/Queries/zorba/jsoniq/jn_values.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_values.spec	2012-08-13 13:24:24 +0000
@@ -0,0 +1,1 @@
+Serialization: jsoniq-allow-mixed-xdm-jdm=yes jsoniq-multiple-items=appended

=== added file 'test/rbkt/Queries/zorba/jsoniq/jn_values.xq'
--- test/rbkt/Queries/zorba/jsoniq/jn_values.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/jn_values.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,10 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+let $object :=
+{
+ "foo" : "bar",
+ "bar" : { "foo" : [1] },
+ "foobar" : "foo" 
+}
+return jn:values($object)
+

=== added file 'test/rbkt/Queries/zorba/jsoniq/object_03.xq'
--- test/rbkt/Queries/zorba/jsoniq/object_03.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/object_03.xq	2012-08-13 13:24:24 +0000
@@ -0,0 +1,18 @@
+import module namespace jn = "http://www.jsoniq.org/functions";;
+
+let $j := ({ "product" : "broiler", "store number" : 1, "quantity" : 20  },
+{ "product" : "toaster", "store number" : 2, "quantity" : 100 },
+{ "product" : "toaster", "store number" : 2, "quantity" : 50 },
+{ "product" : "toaster", "store number" : 3, "quantity" : 50 },
+{ "product" : "blender", "store number" : 3, "quantity" : 100 },
+{ "product" : "blender", "store number" : 3, "quantity" : 150 },
+{ "product" : "socks", "store number" : 1, "quantity" : 500 },
+{ "product" : "socks", "store number" : 2, "quantity" : 10 },
+{ "product" : "shirt", "store number" : 3, "quantity" : 10 })
+return
+jn:object(
+  for $sales in $j
+  let $pname := $sales("product")
+  group by $pname
+  return { $pname : sum(for $s in $sales return $s("quantity")) }
+)


Follow ups