influxparser 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|