Skip to content

Commit 761b571

Browse files
Merge remote-tracking branch 'origin/main' into issue-37
2 parents 3dcaedf + 11c38a4 commit 761b571

File tree

4 files changed

+52
-59
lines changed

4 files changed

+52
-59
lines changed

Diff for: cli/jq/cli.clj

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
(println summary))
2525

2626
(defn execute [jq-filter files _]
27-
(let [jq-processor (jq/flexible-processor jq-filter {:multi true, :output :json-node})]
27+
(let [jq-processor (jq/flexible-processor jq-filter {:output :json-node})]
2828
(if (seq files)
2929
(doseq [f files
3030
item (jq-processor (slurp f))]
3131
(println (jq/json-node->string item)))
3232
(when (.ready ^Reader *in*)
33-
(doseq [line (line-seq (BufferedReader. *in*))
33+
(doseq [^String line (line-seq (BufferedReader. *in*))
3434
item (jq-processor line)]
3535
(println (jq/json-node->string item)))))))
3636

Diff for: src/jq/api.clj

+11-15
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,35 @@
77
; required in common use cases, so moving out of impl space
88
(def json-node->string impl/json-node->string)
99

10-
(defn- container [opts]
11-
(when (:multi opts) (impl/NewMultiOutputContainer)))
12-
1310
; jq docs http://manpages.ubuntu.com/manpages/hirsute/man1/jq.1.html
1411
(defn execute
1512
"Given a JSON data string (1) and a JQ query string (2)
1613
returns a JSON string result of (2) applied on (1).
14+
Output stream is joined with the new-line symbol.
1715
Accepts optional options map.
18-
NOTE: if your query doesn't change the use the `processor`."
16+
NOTE: if your query doesn't change then use the `processor`."
1917
(^String [^String data ^String query]
2018
(execute data query {}))
2119
(^String [^String data ^String query opts]
2220
(impl/apply-json-query-on-string-data
2321
data
2422
(impl/compile-query query)
25-
(impl/new-scope opts)
26-
(container opts))))
23+
(impl/new-scope opts))))
2724

2825
(defn processor
2926
"Given a JQ query string (1) compiles it and returns a function that given
3027
a JSON string (2) will return a JSON string with (1) applied on (2).
28+
Output stream is joined with the new-line symbol.
3129
Accepts optional options map."
3230
([^String query] (processor query {}))
3331
([^String query opts]
3432
(let [^JsonQuery json-query (impl/compile-query query)
3533
^Scope scope (impl/new-scope opts)]
3634
(fn this
3735
(^String [^String data]
38-
(this data nil))
36+
(this data nil))
3937
(^String [^String data {:keys [vars]}]
40-
(impl/apply-json-query-on-string-data
41-
data json-query (impl/scope-with-vars scope vars) (container opts)))))))
38+
(impl/apply-json-query-on-string-data data json-query (impl/scope-with-vars scope vars)))))))
4239

4340
(defn flexible-processor
4441
"Given a JQ query string (1) compiles it and returns a function that given
@@ -49,8 +46,7 @@
4946
([^String query opts]
5047
(let [^JsonQuery query (impl/compile-query query)
5148
output-format (get opts :output :string)
52-
^Scope scope (impl/new-scope opts)
53-
container (container opts)]
49+
^Scope scope (impl/new-scope opts)]
5450
(fn this
5551
([json-data]
5652
(this json-data nil))
@@ -59,19 +55,19 @@
5955
(cond
6056
; string => string
6157
(and (string? json-data) (= :string output-format))
62-
(impl/apply-json-query-on-string-data json-data query call-scope container)
58+
(impl/apply-json-query-on-string-data json-data query call-scope)
6359

6460
; string => json-node
6561
(and (string? json-data) (not= :string output-format))
66-
(impl/apply-json-query-on-json-node (impl/string->json-node json-data) query call-scope container)
62+
(impl/apply-json-query-on-json-node (impl/string->json-node json-data) query call-scope)
6763

6864
; json-node => string
6965
(and (not (string? json-data)) (= :string output-format))
70-
(impl/apply-json-query-on-json-node-data json-data query call-scope container)
66+
(impl/apply-json-query-on-json-node-data json-data query call-scope)
7167

7268
; json-node => json-node
7369
(and (not (string? json-data)) (not= :string output-format))
74-
(impl/apply-json-query-on-json-node json-data query call-scope container))))))))
70+
(impl/apply-json-query-on-json-node json-data query call-scope))))))))
7571

7672
(comment
7773
(jq.api/execute "{\"a\":[1,2,3,4,5],\"b\":\"hello\"}" ".")

Diff for: src/jq/api/api_impl.clj

+30-33
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
(ns ^{:doc "Internal implementation details."
22
:no-doc true}
33
jq.api.api-impl
4+
(:require [clojure.string :as str])
45
(:import (java.util ArrayList)
56
(net.thisptr.jackson.jq JsonQuery Versions Scope BuiltinFunctionLoader Output)
67
(com.fasterxml.jackson.databind ObjectMapper JsonNode)
7-
(com.fasterxml.jackson.databind.node JsonNodeFactory)
8+
(com.fasterxml.jackson.databind.node ArrayNode JsonNodeFactory)
89
(net.thisptr.jackson.jq.module.loaders ChainedModuleLoader BuiltinModuleLoader FileSystemModuleLoader)
910
(net.thisptr.jackson.jq.module ModuleLoader)
1011
(java.nio.file Path)
@@ -63,60 +64,56 @@
6364
scope)
6465
old-scope))
6566

67+
(defn string->json-node ^JsonNode [^String data]
68+
(.readTree mapper data))
69+
70+
(defn json-node->string ^String [^JsonNode data]
71+
(.writeValueAsString mapper data))
72+
6673
; Helper interface that specifies a method to get a string value.
6774
(definterface IContainer
6875
; net.thisptr.jackson.jq/Output
69-
(^com.fasterxml.jackson.databind.JsonNode getValue []))
76+
(^java.lang.Iterable getValue []))
7077

7178
; Container class helper that implements the net.thisptr.jackson.jq.Output
7279
; interface that enables the class to be used as a callback for JQ and exposes the
7380
; unsynchronized-mutable container field for the result of the JQ transformation.
74-
(deftype SingleOutputContainer [^:unsynchronized-mutable ^JsonNode container]
81+
(deftype JsonNodeOutputContainer [^ArrayNode container]
7582
Output
76-
(emit [_ json-node] (set! container json-node))
83+
(emit [_ json-node] (.add container json-node))
7784
IContainer
7885
(getValue [_] container))
7986

80-
(deftype MultiOutputContainer [^ArrayList container]
87+
(defn json-node-output-container []
88+
(JsonNodeOutputContainer. (.arrayNode JsonNodeFactory/instance)))
89+
90+
(deftype StringOutputContainer [^ArrayList container]
8191
Output
82-
(emit [_ json-node]
83-
(.add container json-node))
92+
(emit [_ json-node] (.add container (json-node->string json-node)))
8493
IContainer
85-
(getValue [_]
86-
(let [jsonArray (.arrayNode JsonNodeFactory/instance (.size container))]
87-
(doseq [^JsonNode item container]
88-
(.add jsonArray item))
89-
(.clear container)
90-
jsonArray)))
94+
(getValue [_] container))
9195

92-
(defn NewMultiOutputContainer []
93-
(MultiOutputContainer. (ArrayList.)))
96+
(defn string-output-container []
97+
(StringOutputContainer. (ArrayList.)))
9498

9599
(defn apply-json-query-on-json-node
96100
"Given a JSON data string and a JsonQuery object applies the query
97101
on the JSON data string and return JsonNode; may be given a custom IContainer"
98-
(^JsonNode [^JsonNode json-node ^JsonQuery json-query ^Scope scope ^IContainer output-container]
99-
(let [^IContainer output-container (or output-container (SingleOutputContainer. nil))]
100-
(.apply json-query (Scope/newChildScope scope) json-node output-container)
101-
(.getValue output-container)))
102-
(^JsonNode [^JsonNode json-node ^JsonQuery json-query ^Scope scope]
103-
(apply-json-query-on-json-node json-node json-query scope nil)))
102+
([^JsonNode json-node ^JsonQuery json-query ^Scope scope ^IContainer container]
103+
(.apply json-query (Scope/newChildScope scope) json-node container)
104+
(.getValue container))
105+
([^JsonNode json-node ^JsonQuery json-query ^Scope scope]
106+
(apply-json-query-on-json-node json-node json-query scope (json-node-output-container))))
104107

105-
(defn string->json-node ^JsonNode [^String data]
106-
(.readTree mapper data))
107-
108-
(defn json-node->string ^String [^JsonNode data]
109-
(.writeValueAsString mapper data))
108+
(defn apply-json-query-on-json-node-data
109+
"Passes a JsonNode to the query executor."
110+
^String [^JsonNode data ^JsonQuery query ^Scope scope]
111+
(str/join "\n" (apply-json-query-on-json-node data query scope (string-output-container))))
110112

111113
(defn apply-json-query-on-string-data
112114
"Reads data JSON string into a JsonNode and passes to the query executor."
113-
^String [^String data ^JsonQuery query ^Scope scope ^IContainer output-container]
114-
(json-node->string (apply-json-query-on-json-node (string->json-node data) query scope output-container)))
115-
116-
(defn apply-json-query-on-json-node-data
117-
"Reads data JSON string into a JsonNode and passes to the query executor."
118-
^String [^JsonNode data ^JsonQuery query ^Scope scope ^IContainer output-container]
119-
(json-node->string (apply-json-query-on-json-node data query scope output-container)))
115+
^String [^String data ^JsonQuery query ^Scope scope]
116+
(apply-json-query-on-json-node-data (string->json-node data) query scope))
120117

121118
(defn new-scope
122119
(^Scope [] (Scope/newChildScope root-scope))

Diff for: test/jq/api_test.clj

+9-9
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,14 @@
6262
(let [data-1 "[1,2,3]"
6363
data-2 "[4,5,6]" ;; testing two calls ensures we aren't retaining extra state
6464
script ".[] | {\"out\": .}"
65-
processor-fn (jq/flexible-processor script {:output :string
66-
:multi true})]
67-
(is (= "[{\"out\":1},{\"out\":2},{\"out\":3}]" (processor-fn data-1)))
68-
(is (= "[{\"out\":4},{\"out\":5},{\"out\":6}]" (processor-fn data-2)))))
65+
processor-fn (jq/flexible-processor script {:output :string})]
66+
(is (= "{\"out\":1}\n{\"out\":2}\n{\"out\":3}" (processor-fn data-1)))
67+
(is (= "{\"out\":4}\n{\"out\":5}\n{\"out\":6}" (processor-fn data-2)))))
6968
(testing "checking that queries can choose not to return any output given an input"
7069
(let [data "[9,10,11]"
7170
script ".[] | select(. >= 10)"
72-
processor-fn (jq/flexible-processor script {:output :string
73-
:multi true})]
74-
(is (= "[10,11]" (processor-fn data))))))
71+
processor-fn (jq/flexible-processor script {:output :string})]
72+
(is (= "10\n11" (processor-fn data))))))
7573

7674
(deftest string-to-string-execution
7775
(testing "mapping function onto values"
@@ -89,13 +87,15 @@
8987
(is (= result-string (processor-fn string-data)))))
9088

9189
(testing "String to JsonNode"
92-
(let [processor-fn (jq/flexible-processor query {:output :json-node})
90+
(let [result-string "[[2,3,4]]"
91+
processor-fn (jq/flexible-processor query {:output :json-node})
9392
resp (processor-fn string-data)]
9493
(is (instance? JsonNode resp))
9594
(is (= result-string (utils/json-node->string resp)))))
9695

9796
(testing "JsonNode to JsonNode"
98-
(let [processor-fn (jq/flexible-processor query {:output :json-node})
97+
(let [result-string "[[2,3,4]]"
98+
processor-fn (jq/flexible-processor query {:output :json-node})
9999
resp (processor-fn json-node-data)]
100100
(is (instance? JsonNode resp))
101101
(is (= result-string (utils/json-node->string resp)))))

0 commit comments

Comments
 (0)