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 +4 -4
- data/lib/influxparser.rb +30 -21
- data/test/test_parse_point_from_docs.rb +41 -10
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a35192cf489f487d8a42343384e1528d5168047
|
4
|
+
data.tar.gz: fa965f4209d17c97bf4bde7508c5cc9fe07cfcd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 870efd15c7c9df408b15a2da2dc11134c6c2bd45ff69bdd213b30a3913fb402b0d992626c42bfee7a944dbbfe4624a922baffe6e0c6d5c2cb995170c9a6c74d5
|
7
|
+
data.tar.gz: 194488b6bcb2ed5ce444c603789c6db5ce8b321f2ed15b70567f19b35afd7a0fb5e15cc78be828bf99d30809f0f23ea845a10d5b9da5d0949fe53db4ac43eae6
|
data/lib/influxparser.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
36
|
+
last_value_raw = value[1]
|
36
37
|
last_key = unescape_tag value[0]
|
37
|
-
# puts "
|
38
|
-
point['values'][last_key] =
|
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 =
|
45
|
+
has_space = last_value_raw.rindex(/ /)
|
45
46
|
if has_space
|
46
|
-
time_stamp =
|
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
|
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
|
-
|
68
|
+
def unescape_point(s,options)
|
69
|
+
# puts "unescape:#{s}"
|
70
|
+
# s = s.gsub(/\\\\/,'\\').gsub(/\\"/,'""') # handle escaped characters if present
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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(
|
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(
|
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(
|
75
|
+
assert_equal(82,point['values']['temperature'])
|
76
76
|
|
77
77
|
assert_equal(true,point['values'].key?('humidity'))
|
78
|
-
assert_equal(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|