influxparser 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 599f27d2ff8251400b2b593b79e0ca7facad4aff
4
- data.tar.gz: 84c2792855209669e2bc8e4a41aec43c393be2e1
3
+ metadata.gz: 8a35192cf489f487d8a42343384e1528d5168047
4
+ data.tar.gz: fa965f4209d17c97bf4bde7508c5cc9fe07cfcd0
5
5
  SHA512:
6
- metadata.gz: a5a8a3e29905ac2f31915e7be9dc2e7dcb987f5375a0a80f871720b8e859386397d70c1e73a2b58982db45946a04d0146a82660d6c95dd3f646a2460c3be4335
7
- data.tar.gz: 1f97c90e05e42b503ef03283f72cb22ba176f00564c18e356cd998a5dd587f78f2990aa732da1e1e985c8f3f054263149d306efaa15851641c8862c93952d365
6
+ metadata.gz: 870efd15c7c9df408b15a2da2dc11134c6c2bd45ff69bdd213b30a3913fb402b0d992626c42bfee7a944dbbfe4624a922baffe6e0c6d5c2cb995170c9a6c74d5
7
+ data.tar.gz: 194488b6bcb2ed5ce444c603789c6db5ce8b321f2ed15b70567f19b35afd7a0fb5e15cc78be828bf99d30809f0f23ea845a10d5b9da5d0949fe53db4ac43eae6
@@ -1,13 +1,13 @@
1
1
  # TODO: the tags hash should be absent when there are no tags
2
- # TODO: numbers shouldn't be strings
3
- # TODO: numbers which aren't strings are floats
4
- # TODO: numbers with a trailing i are integers -- ALERT this is actually broken
5
2
  # TODO: optional timestamp parsing
6
3
  # TODO: time key shouldn't exist if there is no time
7
4
  # TODO: deal with improper line protocol
8
5
  class InfluxParser
9
6
  class << self
10
- def parse_point(s)
7
+ def parse_point(s, options = {})
8
+ default_options = {:parse_types => true}
9
+ options = default_options.merge(options)
10
+
11
11
  point = {}
12
12
  point['_raw'] = s
13
13
  s = s.strip # trim whitespace
@@ -26,29 +26,30 @@ class InfluxParser
26
26
  end
27
27
 
28
28
  # now iterate over the values
29
- last_value = ''
29
+ last_value_raw = ''
30
30
  last_key = ''
31
31
  point['values'] = {}
32
32
  vparts = s[measurement_end+1..-1].split(/(?<!\\),/)
33
+ # puts "vparts:#{vparts}"
33
34
  vparts.each do |v|
34
35
  value = v.split(/(?<!\\)=/)
35
- last_value = unescape_point value[1]
36
+ last_value_raw = value[1]
36
37
  last_key = unescape_tag value[0]
37
- # puts "kv:#{last_key}==#{last_value}"
38
- point['values'][last_key] = last_value
38
+ # puts "last k/v #{last_key}==#{last_value_raw}"
39
+ point['values'][last_key] = unescape_point(value[1],options)
39
40
  end
40
-
41
+ # puts "-----\n#{point['values'].to_yaml}\n"
41
42
  # check for a timestamp in the last value
42
43
  # TODO: I hate this, but it's late and I just want to move past it for now
43
44
  # TODO: what happens if the last character of the last value is an escaped quote?
44
- has_space = last_value.rindex(/ /)
45
+ has_space = last_value_raw.rindex(/ /)
45
46
  if has_space
46
- time_stamp = last_value[has_space+1..-1] # take everything from the space to the end
47
+ time_stamp = last_value_raw[has_space+1..-1] # take everything from the space to the end
47
48
  if time_stamp.index(/"/)
48
49
  point['time'] = nil
49
50
  else
50
51
  # it was a timestamp, strip it from the last value and set the timestamp
51
- point['values'][last_key] = unescape_point last_value[0..has_space-1]
52
+ point['values'][last_key] = unescape_point(last_value_raw[0..has_space-1],options)
52
53
  point['time'] = time_stamp
53
54
  end
54
55
  else
@@ -64,16 +65,24 @@ class InfluxParser
64
65
  t = unescape_measurement s
65
66
  t.gsub(/\\=/,'=')
66
67
  end
67
- def unescape_point(s)
68
- if s[-1,1] == '"'
68
+ def unescape_point(s,options)
69
+ # puts "unescape:#{s}"
70
+ # s = s.gsub(/\\\\/,'\\').gsub(/\\"/,'""') # handle escaped characters if present
69
71
 
70
- # it's a quoted string and should be unescaped
71
- s = s[1..-2] # take the wrapping quotes off
72
- return s.gsub(/\\\\/,'\\').gsub(/\\"/,',')
73
- else
74
- # it's a number and if it's trailing an i we need to strip it because we're not handling precision here
75
- return s.chomp('i')
76
- end
72
+ # it is a string, return it
73
+ return s[1..-2].gsub(/\\\\/,'\\').gsub(/\\"/,'""') if s[0,1] == '"'
74
+
75
+ return s.sub(/(?<=\d)i/,'') if (!options[:parse_types]) # the customer doesn't care about types so just return it, but strip the trailing i from an integer because we care
76
+
77
+ # handle the booleans
78
+ return true if ['t','T','true','True','TRUE'].include?(s)
79
+ return false if ['f','F','false','False','FALSE'].include?(s)
80
+
81
+ # by here we have either an unquoted string or some numeric
82
+
83
+ return s.to_f if s =~ /^(\d|\.)+$/ # floats are only digits and dots
84
+ return s.chomp('i').to_i if s[0..-2] =~ /^(\d)+$/ # trailing i is an integer remove it
85
+ return s.gsub(/\\\\/,'\\').gsub(/\\"/,'"')
77
86
  end
78
87
  end
79
88
  end
@@ -30,7 +30,7 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
30
30
 
31
31
  # value
32
32
  assert_equal(true,point['values'].key?('temperature'))
33
- assert_equal('82',point['values']['temperature'])
33
+ assert_equal(82,point['values']['temperature'])
34
34
 
35
35
  # time
36
36
  assert_equal('1465839830100400200',point['time'])
@@ -50,7 +50,7 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
50
50
 
51
51
  # value
52
52
  assert_equal(true,point['values'].key?('temperature'))
53
- assert_equal('82',point['values']['temperature'])
53
+ assert_equal(82,point['values']['temperature'])
54
54
 
55
55
  # time
56
56
  assert_equal('1465839830100400200',point['time'])
@@ -72,10 +72,10 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
72
72
  assert_equal(2,point['values'].length)
73
73
 
74
74
  assert_equal(true,point['values'].key?('temperature'))
75
- assert_equal('82',point['values']['temperature'])
75
+ assert_equal(82,point['values']['temperature'])
76
76
 
77
77
  assert_equal(true,point['values'].key?('humidity'))
78
- assert_equal('71',point['values']['humidity'])
78
+ assert_equal(71,point['values']['humidity'])
79
79
 
80
80
  # time
81
81
  assert_equal('1465839830100400200',point['time'])
@@ -90,12 +90,12 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
90
90
  def test_float
91
91
  point = InfluxParser.parse_point('weather,location=us-midwest temperature=82 1465839830100400200')
92
92
  assert_not_equal(false,point) # a straight up parse error will false
93
- assert_equal('82',point['values']['temperature'])
93
+ assert_equal(82.0,point['values']['temperature'])
94
94
  end
95
95
  def test_integer
96
96
  point = InfluxParser.parse_point('weather,location=us-midwest temperature=82i 1465839830100400200')
97
97
  assert_not_equal(false,point) # a straight up parse error will false
98
- assert_equal('82',point['values']['temperature'])
98
+ assert_equal(82,point['values']['temperature'])
99
99
  end
100
100
 
101
101
  def test_string
@@ -118,36 +118,45 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
118
118
  end
119
119
 
120
120
  def test_boolean
121
- # TODO: validate the parsed booleans are bools and expected
122
121
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=t 1465839830100400200")
123
122
  assert_not_equal(false,point) # a straight up parse error will false
123
+ assert_equal(true,point['values']['temperature'])
124
124
 
125
125
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=T 1465839830100400200")
126
126
  assert_not_equal(false,point) # a straight up parse error will false
127
+ assert_equal(true,point['values']['temperature'])
127
128
 
128
129
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=true 1465839830100400200")
129
130
  assert_not_equal(false,point) # a straight up parse error will false
131
+ assert_equal(true,point['values']['temperature'])
130
132
 
131
133
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=True 1465839830100400200")
132
134
  assert_not_equal(false,point) # a straight up parse error will false
135
+ assert_equal(true,point['values']['temperature'])
133
136
 
134
137
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=TRUE 1465839830100400200")
135
138
  assert_not_equal(false,point) # a straight up parse error will false
139
+ assert_equal(true,point['values']['temperature'])
136
140
 
137
141
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=f 1465839830100400200")
138
142
  assert_not_equal(false,point) # a straight up parse error will false
143
+ assert_equal(false,point['values']['temperature'])
139
144
 
140
145
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=F 1465839830100400200")
141
146
  assert_not_equal(false,point) # a straight up parse error will false
147
+ assert_equal(false,point['values']['temperature'])
142
148
 
143
149
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=false 1465839830100400200")
144
150
  assert_not_equal(false,point) # a straight up parse error will false
151
+ assert_equal(false,point['values']['temperature'])
145
152
 
146
153
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=False 1465839830100400200")
147
154
  assert_not_equal(false,point) # a straight up parse error will false
155
+ assert_equal(false,point['values']['temperature'])
148
156
 
149
157
  point = InfluxParser.parse_point("weather,location=us-midwest temperature=FALSE 1465839830100400200")
150
158
  assert_not_equal(false,point) # a straight up parse error will false
159
+ assert_equal(false,point['values']['temperature'])
151
160
 
152
161
  end
153
162
  def test_ridiculous_quotes
@@ -165,7 +174,7 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
165
174
  # check values
166
175
 
167
176
  assert_equal(true,point['values'].key?('"temperature"'))
168
- assert_equal('82',point['values']['"temperature"'])
177
+ assert_equal(82,point['values']['"temperature"'])
169
178
 
170
179
  # time
171
180
  assert_equal('1465839830100400200',point['time'])
@@ -186,7 +195,7 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
186
195
  # check values
187
196
 
188
197
  assert_equal(true,point['values'].key?("'temperature'"))
189
- assert_equal('82',point['values']["'temperature'"])
198
+ assert_equal(82,point['values']["'temperature'"])
190
199
 
191
200
  # time
192
201
  assert_equal('1465839830100400200',point['time'])
@@ -200,7 +209,7 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
200
209
 
201
210
  point = InfluxParser.parse_point('weather,location=us-midwest temp\=rature=82 1465839830100400200')
202
211
  assert_not_equal(false,point) # a straight up parse error will false
203
- assert_equal('82',point['values']['temp=rature'])
212
+ assert_equal(82,point['values']['temp=rature'])
204
213
 
205
214
  point = InfluxParser.parse_point('weather,location\ place=us-midwest temperature=82 1465839830100400200')
206
215
  assert_not_equal(false,point) # a straight up parse error will false
@@ -214,6 +223,11 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
214
223
  assert_not_equal(false,point) # a straight up parse error will false
215
224
  assert_equal('wea ther',point['measurement'])
216
225
 
226
+ point = InfluxParser.parse_point('weather temperature=toohot\"')
227
+ assert_not_equal(false,point) # a straight up parse error will false
228
+ assert_equal('toohot"',point['values']['temperature'])
229
+
230
+
217
231
  # so many slashes -- note they're extra terrible because I need to escape ruby slashes in the test strings
218
232
 
219
233
  # forward slash
@@ -247,4 +261,21 @@ class TestParsePointFromDocs < Test::Unit::TestCase # def setup
247
261
  assert_equal("too hot\\\\\\cold",point['values']['temperature_str'])
248
262
 
249
263
  end
264
+ def test_types
265
+ point = InfluxParser.parse_point('weather float=82,integer=82i,impliedstring=helloworld,explicitstring="hello world" 1465839830100400200')
266
+ assert_not_equal(false,point) # a straight up parse error will false
267
+ assert_equal(82.0,point['values']['float'])
268
+ assert_equal(82,point['values']['integer'])
269
+ assert_equal('helloworld',point['values']['impliedstring'])
270
+ assert_equal('hello world',point['values']['explicitstring'])
271
+
272
+ # do it again but this time without type parsing
273
+ point = InfluxParser.parse_point('weather float=82,integer=82i,impliedstring=helloworld,explicitstring="hello world" 1465839830100400200',{:parse_types => false})
274
+ assert_not_equal(false,point) # a straight up parse error will false
275
+ assert_equal('82',point['values']['float'])
276
+ assert_equal('82',point['values']['integer'])
277
+ assert_equal('helloworld',point['values']['impliedstring'])
278
+ assert_equal('hello world',point['values']['explicitstring'])
279
+
280
+ end
250
281
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: influxparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Labrie