jgrep 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/bin/jgrep +2 -1
  2. data/jgrep.gemspec +3 -2
  3. data/lib/jgrep.rb +125 -21
  4. data/lib/parser/scanner.rb +16 -0
  5. metadata +17 -6
data/bin/jgrep CHANGED
@@ -8,7 +8,7 @@ options = {:flat => false, :start => nil}
8
8
  begin
9
9
  OptionParser.new do |opts|
10
10
  opts.banner = "Usage: jgrep [options] \"expression\""
11
- opts.on("-s", "--simple FIELD[s]", "Display a single field from each of the resulting json documents") do |field|
11
+ opts.on("-s", "--simple [FIELDS]", "Display only one or more fields from each of the resulting json documents") do |field|
12
12
  if (field.split(" ")).size > 1
13
13
  options[:field] = field.split(" ")
14
14
  else
@@ -87,6 +87,7 @@ begin
87
87
  end
88
88
  end
89
89
  end
90
+
90
91
  rescue Exception => e
91
92
  STDERR.puts "Error - #{e}"
92
93
  exit 1
data/jgrep.gemspec CHANGED
@@ -1,10 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "jgrep"
3
- s.version = "1.2.1"
3
+ s.version = "1.3.0"
4
4
 
5
5
  s.authors = ["P Loubser"]
6
- s.date = %q{2011-08-01}
6
+ s.date = %q{2011-08-04}
7
7
  s.default_executable = "jgrep"
8
+ s.add_dependency('json')
8
9
  s.description = "Compare a list of json documents to a simple logical language and returns matches as output"
9
10
  s.email = ["ploubser@gmail.com"]
10
11
  s.executables = ["jgrep"]
data/lib/jgrep.rb CHANGED
@@ -4,6 +4,7 @@ require 'parser/parser.rb'
4
4
  require 'parser/scanner.rb'
5
5
  require 'rubygems'
6
6
  require 'json'
7
+ #require 'yajl/json_gem'
7
8
 
8
9
  module JGrep
9
10
  @verbose = false
@@ -17,7 +18,10 @@ module JGrep
17
18
  @flatten = true
18
19
  end
19
20
 
20
- #Method parses json and returns documents that match the logical expression
21
+ #Parse json and return documents that match the logical expression
22
+ #Filters define output by limiting it to only returning a the listed keys.
23
+ #Start allows you to move the pointer indicating where parsing starts.
24
+ #Default is the first key in the document heirarchy
21
25
  def self.jgrep(json, expression, filters = nil, start = nil)
22
26
  errors = ""
23
27
  begin
@@ -66,6 +70,78 @@ module JGrep
66
70
  STDERR.puts "Error. Invalid JSON given"
67
71
  exit 1
68
72
  end
73
+ end
74
+
75
+ #Convert a specific hash inside a JSON document to an array
76
+ #Mark is a string in the format foo.bar.baz that points to
77
+ #the array in the document.
78
+ def self.hash_to_array(documents, mark)
79
+
80
+ begin
81
+ documents = JSON.parse(documents)
82
+ rescue JSON::ParserError => e
83
+ STDERR.puts "Error. Invalid JSON given"
84
+ exit 1
85
+ end
86
+
87
+ result = []
88
+
89
+ begin
90
+ for i in 0..(documents.size - 1) do
91
+ tmp = documents[i]
92
+ unless mark == ""
93
+ mark.split(".").each_with_index do |m,i|
94
+ tmp = tmp[m] unless i == mark.split(".").size - 1
95
+ end
96
+ end
97
+
98
+ tmp[mark.split.last].each{|d| result << {"value" => d[1], "key" => d[0]}}
99
+ tmp[mark.split.last] = result
100
+
101
+ end
102
+ rescue Exception => e
103
+ STDERR.puts "Error. Invalid position specified in JSON document"
104
+ exit!
105
+ end
106
+
107
+ puts JSON.pretty_generate(documents)
108
+
109
+ end
110
+
111
+ #Convert a specific array inside a JSON document to a hash
112
+ #Mark is a string in the format foo.bar.baz that points to
113
+ #the hash in the document. Each element in the array will
114
+ #be turned into a hash in the format key => array[x]
115
+ def self.array_to_hash(documents, mark, key)
116
+
117
+ begin
118
+ documents = JSON.parse(documents)
119
+ rescue JSON::ParserError => e
120
+ STDERR.puts "Error. Invalid JSON given"
121
+ exit 1
122
+ end
123
+
124
+ result = {}
125
+
126
+ begin
127
+ for i in 0..(documents.size - 1) do
128
+ tmp = documents[i]
129
+ unless mark == ""
130
+ mark.split(".").each_with_index do |m,i|
131
+ tmp = tmp[m] unless i == mark.split(".").size - 1
132
+ end
133
+ end
134
+
135
+ tmp[mark.split(".").last].each{|d| result[d[key]] = d}
136
+ tmp[mark.split(".").last] = result
137
+
138
+ end
139
+ rescue Exception => e
140
+ STDERR.puts "Error. Invalid position specified in JSON document"
141
+ exit!
142
+ end
143
+
144
+ puts JSON.pretty_generate(documents)
69
145
 
70
146
  end
71
147
 
@@ -128,6 +204,8 @@ module JGrep
128
204
  end
129
205
  end
130
206
 
207
+
208
+ #Check if the json key that is defined by statement is defined in the json document
131
209
  def self.present?(document, statement)
132
210
  statement.split(".").each do |key|
133
211
  if document.is_a? Hash
@@ -167,25 +245,25 @@ module JGrep
167
245
  op = statement
168
246
  end
169
247
 
170
- tmp = document
248
+ tmp = dig_path(document, key)
171
249
 
172
- key.split(".").each_with_index do |item,i|
173
- tmp = tmp[item]
174
- if tmp.nil?
175
- if item == key.split(".").last
176
- tmp = "null"
177
- else
178
- return false
179
- end
180
- end
181
- result = false
182
- if tmp.is_a? Array
183
- return (is_object_in_array?(tmp, "#{key.split(".")[i+1]}#{op}#{value}"))
184
- end
250
+ if tmp.is_a?(Array) and tmp.size == 1
251
+ tmp = tmp.first
185
252
  end
186
253
 
187
254
  tmp, value = format(tmp, (value.gsub(/"|'/, "") unless value.nil?))
188
255
 
256
+ #Deal with null comparison
257
+ if tmp.nil? and value == "null"
258
+ return true
259
+ end
260
+
261
+ #Deal with regex matching
262
+ if ((value =~ /^\/.*\/$/) && tmp != nil)
263
+ (tmp.match(Regexp.new(value.gsub("/", "")))) ? (return true) : (return false)
264
+ end
265
+
266
+ #Deal with everything else
189
267
  case op
190
268
  when "="
191
269
  (tmp == value) ? (return true) : (return false)
@@ -292,24 +370,50 @@ module JGrep
292
370
  return eval(result.join(" "))
293
371
  end
294
372
 
373
+ #Digs to a specific path in the json document and returns the value
295
374
  def self.dig_path(json, path)
296
375
 
297
- json = json[path.split(".").first] if json.is_a? Hash
376
+ path = path.gsub(/^\./, "")
377
+
378
+ if path == ""
379
+ return json
380
+ end
381
+
382
+ if json.is_a? Hash
383
+ json.keys.each do |k|
384
+ if path.match(/^#{k}/) && k.match(/\./)
385
+ return dig_path(json[k], path.gsub(k, ""))
386
+ end
387
+ end
388
+ end
389
+
390
+ path_array=path.split(".")
391
+
392
+ if path_array.first == "*"
393
+ tmp = []
394
+ json.each do |j|
395
+ tmp << dig_path(j[1], path_array.drop(1).join("."))
396
+ end
397
+ return tmp
398
+
399
+ end
400
+
401
+ json = json[path_array.first] if json.is_a? Hash
298
402
 
299
- if json.is_a?(Hash)
300
- if path == path.split(".").first
403
+ if json.is_a? Hash
404
+ if path == path_array.first
301
405
  return json
302
406
  else
303
- return dig_path(json, (path.match(/\./) ? path.split(".").drop(1).join(".") : path))
407
+ return dig_path(json, (path.match(/\./) ? path_array.drop(1).join(".") : path))
304
408
  end
305
409
 
306
410
  elsif json.is_a? Array
307
- if path == path.split(".").first && (json.first.is_a?(Hash) && !(json.first.keys.include?(path)))
411
+ if path == path_array.first && (json.first.is_a?(Hash) && !(json.first.keys.include?(path)))
308
412
  return json
309
413
  else
310
414
  tmp = []
311
415
  json.each do |j|
312
- tmp_path = dig_path(j, (path.match(/\./) ? path.split(".").drop(1).join(".") : path))
416
+ tmp_path = dig_path(j, (path.match(/\./) ? path_array.drop(1).join(".") : path))
313
417
  unless tmp_path.nil?
314
418
  tmp << tmp_path
315
419
  end
@@ -46,6 +46,14 @@ module JGrep
46
46
  gen_statement
47
47
  end
48
48
 
49
+ when "&"
50
+ if(@arguments.split("")[@token_index +1] == "&")
51
+ @token_index +=1
52
+ return "and", "and"
53
+ else
54
+ gen_statement
55
+ end
56
+
49
57
  when "o"
50
58
  if (@arguments.split("")[@token_index + 1] == "r") && ((@arguments.split("")[@token_index + 2] == " ") || (@arguments.split("")[@token_index + 2] == "("))
51
59
  @token_index += 1
@@ -54,6 +62,14 @@ module JGrep
54
62
  gen_statement
55
63
  end
56
64
 
65
+ when "|"
66
+ if(@arguments.split("")[@token_index +1] == "|")
67
+ @token_index +=1
68
+ return "or", "or"
69
+ else
70
+ gen_statement
71
+ end
72
+
57
73
  when "+"
58
74
  value = ""
59
75
  i = @token_index + 1
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 2
8
- - 1
9
- version: 1.2.1
7
+ - 3
8
+ - 0
9
+ version: 1.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - P Loubser
@@ -14,10 +14,21 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-08-01 00:00:00 +01:00
17
+ date: 2011-08-04 00:00:00 +01:00
18
18
  default_executable: jgrep
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
21
32
  description: Compare a list of json documents to a simple logical language and returns matches as output
22
33
  email:
23
34
  - ploubser@gmail.com