omf_oml 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/omf_oml/csv_table.rb +80 -0
- data/lib/omf_oml/endpoint.rb +3 -3
- data/lib/omf_oml/network.rb +4 -4
- data/lib/omf_oml/schema.rb +2 -2
- data/lib/omf_oml/sequel/sequel_server.rb +3 -3
- data/lib/omf_oml/sql_row.rb +53 -41
- data/lib/omf_oml/sql_source.rb +84 -36
- data/lib/omf_oml/table.rb +5 -2
- data/lib/omf_oml/tuple.rb +2 -2
- data/lib/omf_oml/version.rb +1 -1
- data/omf_oml.gemspec +1 -0
- data/test/data/brooklynDemo.sq3 +0 -0
- metadata +23 -5
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
require 'csv'
|
3
|
+
require 'omf_oml'
|
4
|
+
require 'omf_oml/table'
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
module OMF::OML
|
9
|
+
|
10
|
+
# This class represents a table whose content is initially stored in a
|
11
|
+
# CSV file.
|
12
|
+
#
|
13
|
+
class OmlCsvTable < OmlTable
|
14
|
+
|
15
|
+
# @param opts
|
16
|
+
#
|
17
|
+
def self.create(tname, file_name, opts = {}, &on_before_row_added)
|
18
|
+
self.new(tname, file_name, opts, &on_before_row_added)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# tname - Name of table
|
23
|
+
# schema - OmlSchema or Array containing [name, type*] for every column in table
|
24
|
+
# Table adds a '__id__' column at the beginning which keeps track of the rows unique id
|
25
|
+
# @params opts
|
26
|
+
# @opts :max_size - keep table to that size by dropping older rows
|
27
|
+
# @opts :index - only keep the latest inserted row for a unique col value - messes with row order
|
28
|
+
# @opts :has_csv_header If true use first row in file as schema descriptor
|
29
|
+
# @opts :schema Schema associated with this table
|
30
|
+
#
|
31
|
+
def initialize(tname, file_name, opts = {}, &on_before_row_added)
|
32
|
+
unless File.readable?(file_name)
|
33
|
+
raise "Can't read CSV file '#{file_name}'"
|
34
|
+
end
|
35
|
+
csv_opts = {}
|
36
|
+
csv_opts[:headers] = (opts.delete(:has_csv_header) == true)
|
37
|
+
unless csv_opts[:headers]
|
38
|
+
raise "Current implementation only works with CSV files which inlcude a schema description in the first line"
|
39
|
+
end
|
40
|
+
|
41
|
+
encoding = opts.delete(:encoding)
|
42
|
+
mode = "rb"
|
43
|
+
mode << ":#{encoding}" if encoding
|
44
|
+
csv = CSV.open(file_name, mode, csv_opts)
|
45
|
+
|
46
|
+
unless schema = opts.delete(:schema)
|
47
|
+
unless csv_opts[:headers]
|
48
|
+
raise "No schema given and ':has_csv_header' not set to capture schema from file header"
|
49
|
+
end
|
50
|
+
first_row = csv.shift.fields # force reading the first row to have the header parsed
|
51
|
+
#csv.shift.each do |h, v| puts "#{h} => #{v.class}" end
|
52
|
+
schema = csv.headers.map do |c|
|
53
|
+
c = c.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
|
54
|
+
name, type = c.split(':')
|
55
|
+
[name, type || 'string']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
super tname, schema, opts
|
59
|
+
|
60
|
+
if first_row # from getting the CSV header
|
61
|
+
first_row.insert(0, @row_id += 1) if @add_index
|
62
|
+
@rows = [@schema.cast_row(first_row)]
|
63
|
+
end
|
64
|
+
|
65
|
+
# This assumes that CSV reader is setup with proper schema converters
|
66
|
+
csv.each do |r|
|
67
|
+
# Convert any strange strings into a clean ruby string
|
68
|
+
row = r.fields.map do |e|
|
69
|
+
e ? e.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?') : nil
|
70
|
+
end
|
71
|
+
row.insert(0, @row_id += 1) if @add_index
|
72
|
+
@rows << @schema.cast_row(row)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
end # class
|
80
|
+
end # module
|
data/lib/omf_oml/endpoint.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'omf_base/lobject'
|
3
3
|
require 'omf_oml'
|
4
4
|
|
5
5
|
require 'omf_oml/oml_tuple'
|
@@ -10,7 +10,7 @@ module OMF::OML
|
|
10
10
|
# be visualized. After creating the object, the @run@ method needs to be called to
|
11
11
|
# start processing the stream.
|
12
12
|
#
|
13
|
-
class OmlEndpoint < OMF::
|
13
|
+
class OmlEndpoint < OMF::Base::LObject
|
14
14
|
|
15
15
|
# Register a proc to be called when a new stream was
|
16
16
|
# discovered on this endpoint.
|
@@ -77,7 +77,7 @@ module OMF::OML
|
|
77
77
|
# and instance and then immediately calls the +run+ methods.
|
78
78
|
#
|
79
79
|
#
|
80
|
-
class OmlSession < OMF::
|
80
|
+
class OmlSession < OMF::Base::LObject # :nodoc
|
81
81
|
|
82
82
|
# Return the value for the respective @key@ in the protocol header.
|
83
83
|
#
|
data/lib/omf_oml/network.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
require 'json'
|
3
3
|
require 'set'
|
4
|
-
require '
|
4
|
+
require 'omf_base/lobject'
|
5
5
|
require 'omf_oml'
|
6
6
|
|
7
7
|
|
@@ -19,7 +19,7 @@ module OMF::OML
|
|
19
19
|
# This class represents a network consisting of nodes and links with their respective
|
20
20
|
# attributes.
|
21
21
|
#
|
22
|
-
class OmlNetwork < OMF::
|
22
|
+
class OmlNetwork < OMF::Base::LObject
|
23
23
|
include MonitorMixin
|
24
24
|
|
25
25
|
@@name2network = {}
|
@@ -310,7 +310,7 @@ module OMF::OML
|
|
310
310
|
|
311
311
|
# This class represents an abstract network element and shouldn't be used directly.
|
312
312
|
#
|
313
|
-
class NetworkElement < OMF::
|
313
|
+
class NetworkElement < OMF::Base::LObject
|
314
314
|
|
315
315
|
attr_reader :name
|
316
316
|
attr_reader :el_id
|
@@ -449,7 +449,7 @@ end
|
|
449
449
|
|
450
450
|
if $0 == __FILE__
|
451
451
|
require 'json'
|
452
|
-
include OMF::
|
452
|
+
include OMF::Base::OML
|
453
453
|
|
454
454
|
nw = OmlNetwork.new
|
455
455
|
|
data/lib/omf_oml/schema.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'omf_base/lobject'
|
3
3
|
require 'omf_oml'
|
4
4
|
|
5
5
|
module OMF::OML
|
6
6
|
|
7
7
|
# This class represents the schema of an OML measurement stream.
|
8
8
|
#
|
9
|
-
class OmlSchema < OMF::
|
9
|
+
class OmlSchema < OMF::Base::LObject
|
10
10
|
|
11
11
|
CLASS2TYPE = {
|
12
12
|
TrueClass => 'boolean',
|
@@ -4,7 +4,7 @@ require 'time'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'sequel'
|
6
6
|
|
7
|
-
require '
|
7
|
+
require 'omf_base/lobject'
|
8
8
|
require 'omf_oml'
|
9
9
|
|
10
10
|
# module OMF::OML
|
@@ -14,7 +14,7 @@ require 'omf_oml'
|
|
14
14
|
module OMF::OML::Sequel
|
15
15
|
module Server
|
16
16
|
|
17
|
-
class Query < OMF::
|
17
|
+
class Query < OMF::Base::LObject
|
18
18
|
|
19
19
|
def self.parse(xmls, repoFactory = RepositoryFactory.new, logger = Logger.new(STDOUT))
|
20
20
|
if xmls.kind_of? String
|
@@ -222,7 +222,7 @@ module OMF::OML::Sequel
|
|
222
222
|
|
223
223
|
end # Query
|
224
224
|
|
225
|
-
class RepositoryFactory < OMF::
|
225
|
+
class RepositoryFactory < OMF::Base::LObject
|
226
226
|
|
227
227
|
def initialize(opts = {})
|
228
228
|
@opts = opts
|
data/lib/omf_oml/sql_row.rb
CHANGED
@@ -1,52 +1,52 @@
|
|
1
1
|
|
2
|
-
require 'omf_oml/
|
2
|
+
require 'omf_oml/oml_tuple'
|
3
3
|
require 'omf_oml/table'
|
4
4
|
|
5
5
|
module OMF::OML
|
6
|
-
|
7
6
|
|
8
|
-
|
7
|
+
|
8
|
+
|
9
9
|
# Read the content of a table and feeds it out as a tuple store.
|
10
10
|
# After creation of the object. The actual tuple feed is started
|
11
11
|
# with a call to +run+.
|
12
12
|
#
|
13
13
|
class OmlSqlRow < OmlTuple
|
14
14
|
attr_reader :row
|
15
|
-
|
16
|
-
#
|
15
|
+
|
16
|
+
#
|
17
17
|
# Create a representation of a row in a database. Can be used to fill a table.
|
18
18
|
#
|
19
19
|
# @param [String] sql_table_name - name of SQL table in respective SQL database
|
20
20
|
# @param [OmlSchema] schema - the schema describing the tuple
|
21
|
-
# @param [Sequel]
|
22
|
-
# @param [Hash] opts:
|
21
|
+
# @param [Sequel::Dataset] query - Databasequery to execute
|
22
|
+
# @param [Hash] opts:
|
23
23
|
# - offset: Ignore first +offset+ rows. If negative or zero serve +offset+ rows initially
|
24
24
|
# - limit: Number of rows to fetch each time [1000]
|
25
|
-
# - check_interval: Interval in seconds when to check for new data. If 0, only run once.
|
25
|
+
# - check_interval: Interval in seconds when to check for new data. If < 0, only run once.
|
26
26
|
# - query_interval: Interval between consecutive queries when processing large result set.
|
27
27
|
#
|
28
|
-
def initialize(sql_table_name, schema,
|
28
|
+
def initialize(sql_table_name, schema, query, opts = {})
|
29
29
|
@sname = sql_table_name
|
30
30
|
@schema = schema
|
31
31
|
raise "Expected OmlSchema but got '#{schema.class}" unless schema.is_a? OmlSchema
|
32
|
-
@
|
33
|
-
|
32
|
+
@query = query
|
33
|
+
|
34
34
|
unless @offset = opts[:offset]
|
35
35
|
@offset = 0
|
36
36
|
end
|
37
37
|
@limit = opts[:limit]
|
38
38
|
@limit = 1000 unless @limit
|
39
|
-
|
39
|
+
|
40
40
|
@check_interval = opts[:check_interval]
|
41
|
-
@check_interval =
|
41
|
+
@check_interval = -1 unless @check_interval
|
42
42
|
@query_interval = opts[:query_interval]
|
43
|
-
|
43
|
+
|
44
44
|
@on_new_vector_proc = {}
|
45
45
|
|
46
|
-
super opts[:name] || sql_table_name, schema
|
46
|
+
super opts[:name] || sql_table_name, schema
|
47
47
|
end
|
48
|
-
|
49
|
-
|
48
|
+
|
49
|
+
|
50
50
|
# Return a specific element of the vector identified either
|
51
51
|
# by it's name, or its col index
|
52
52
|
#
|
@@ -56,18 +56,18 @@ module OMF::OML
|
|
56
56
|
else
|
57
57
|
unless @row.key? name_or_index
|
58
58
|
raise "Unknown column name '#{name_or_index}'"
|
59
|
-
end
|
59
|
+
end
|
60
60
|
@row[name_or_index]
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
64
|
-
# Return the elements of the row as an array using the
|
63
|
+
|
64
|
+
# Return the elements of the row as an array using the
|
65
65
|
# associated schema or 'schema' if non-nil.
|
66
66
|
#
|
67
67
|
def to_a(schema = nil)
|
68
68
|
a = (schema || @schema).hash_to_row(@row) # don't need type conversion as sequel is doing this for us
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
# Return an array including the values for the names elements
|
72
72
|
# given as parameters.
|
73
73
|
#
|
@@ -76,19 +76,19 @@ module OMF::OML
|
|
76
76
|
col_names.collect do |n|
|
77
77
|
unless @row.key? n
|
78
78
|
raise "Unknown column name '#{n}'"
|
79
|
-
end
|
79
|
+
end
|
80
80
|
@row[n]
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def ts
|
85
85
|
self[:oml_ts_server]
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
def seq_no
|
89
89
|
self[:oml_seq]
|
90
|
-
end
|
91
|
-
|
90
|
+
end
|
91
|
+
|
92
92
|
# Register a proc to be called when a new tuple arrived
|
93
93
|
# on this stream.
|
94
94
|
#
|
@@ -149,14 +149,14 @@ module OMF::OML
|
|
149
149
|
self.on_new_tuple(t) do |v|
|
150
150
|
r = v.to_a(schema)
|
151
151
|
#puts r.inspect
|
152
|
-
t.add_row(r)
|
152
|
+
t.add_row(r)
|
153
153
|
end
|
154
154
|
t
|
155
155
|
end
|
156
156
|
|
157
157
|
|
158
158
|
protected
|
159
|
-
|
159
|
+
|
160
160
|
def run(in_thread = true)
|
161
161
|
return if @running
|
162
162
|
if in_thread
|
@@ -172,16 +172,17 @@ module OMF::OML
|
|
172
172
|
_run
|
173
173
|
end
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
private
|
177
|
-
|
177
|
+
|
178
178
|
def _run
|
179
179
|
if @check_interval <= 0
|
180
|
-
while _run_once; end
|
180
|
+
#while _run_once; end
|
181
|
+
_run_once
|
181
182
|
else
|
182
183
|
@running = true
|
183
184
|
while (@running)
|
184
|
-
begin
|
185
|
+
begin
|
185
186
|
unless _run_once
|
186
187
|
# All rows read, wait a bit for news to show up
|
187
188
|
sleep @check_interval
|
@@ -190,22 +191,22 @@ module OMF::OML
|
|
190
191
|
warn ex
|
191
192
|
debug "\t", ex.backtrace.join("\n\t")
|
192
193
|
end
|
193
|
-
end
|
194
|
+
end
|
194
195
|
end
|
195
196
|
end
|
196
|
-
|
197
|
+
|
197
198
|
# Run a query on database an serve all rows found one at a time.
|
198
199
|
# Return true if there might be more rows in the database
|
199
200
|
def _run_once
|
200
201
|
row_cnt = 0
|
201
202
|
t = table_name = @sname
|
202
203
|
if (@offset < 0)
|
203
|
-
cnt = @
|
204
|
+
cnt = @query.count()
|
204
205
|
@offset = cnt + @offset # @offset was negative here
|
205
206
|
debug("Initial offset #{@offset} in '#{table_name}' with #{cnt} rows")
|
206
207
|
@offset = 0 if @offset < 0
|
207
208
|
end
|
208
|
-
@
|
209
|
+
@query.limit(@limit, @offset).each do |r|
|
209
210
|
@row = r
|
210
211
|
@on_new_vector_proc.each_value do |proc|
|
211
212
|
proc.call(self)
|
@@ -216,10 +217,10 @@ module OMF::OML
|
|
216
217
|
debug "Read #{row_cnt} (total #{@offset}) rows from '#{@sname}'" if row_cnt > 0
|
217
218
|
if more_to_read = row_cnt >= @limit # there could be more to read
|
218
219
|
sleep @query_interval if @query_interval # don't hammer database
|
219
|
-
end
|
220
|
-
more_to_read
|
220
|
+
end
|
221
|
+
more_to_read
|
221
222
|
end
|
222
|
-
|
223
|
+
|
223
224
|
end # OmlSqlRow
|
224
225
|
|
225
226
|
|
@@ -227,8 +228,19 @@ end
|
|
227
228
|
|
228
229
|
if $0 == __FILE__
|
229
230
|
|
231
|
+
OMF::Base::Loggable.init_log('sql_row_test')
|
232
|
+
|
233
|
+
require 'omf_oml/sql_source'
|
234
|
+
db_file = File.join(File.dirname(__FILE__), '../../test/data/brooklynDemo.sq3')
|
235
|
+
ss = OMF::OML::OmlSqlSource.new('sqlite://' + File.absolute_path(db_file))
|
236
|
+
|
237
|
+
r = ss.create_stream('wimaxmonitor_wimaxstatus')
|
238
|
+
puts r
|
239
|
+
|
240
|
+
exit
|
241
|
+
|
230
242
|
require 'omf_oml/table'
|
231
|
-
ep = OMF::OML::OmlSqlSource.new('brooklynDemo.sq3')
|
243
|
+
ep = OMF::OML::OmlSqlSource.new(File.join(File.dirname(__FILE__), '../../test/data/brooklynDemo.sq3'))
|
232
244
|
ep.on_new_stream() do |s|
|
233
245
|
puts ">>>>>>>>>>>> New stream #{s.stream_name}: #{s.names.join(', ')}"
|
234
246
|
case s.stream_name
|
@@ -239,7 +251,7 @@ if $0 == __FILE__
|
|
239
251
|
end
|
240
252
|
|
241
253
|
s.on_new_vector() do |v|
|
242
|
-
puts "New vector(#{s.stream_name}): #{v.select(*select).join('|')}"
|
254
|
+
puts "New vector(#{s.stream_name}): #{v.select(*select).join('|')}"
|
243
255
|
end
|
244
256
|
end
|
245
257
|
ep.run()
|
data/lib/omf_oml/sql_source.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
require 'sequel'
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'omf_base/lobject'
|
5
5
|
require 'omf_oml/endpoint'
|
6
6
|
require 'omf_oml/tuple'
|
7
7
|
require 'omf_oml/sql_row'
|
@@ -14,12 +14,12 @@ module OMF::OML
|
|
14
14
|
# After creating the object, the @run@ method needs to be called to
|
15
15
|
# start producing the streams.
|
16
16
|
#
|
17
|
-
class OmlSqlSource < OMF::
|
18
|
-
|
17
|
+
class OmlSqlSource < OMF::Base::LObject
|
18
|
+
|
19
19
|
# Sequel adaptors sometimes don't return a :type identifier,
|
20
20
|
# but always return the :db_type. This is a list of maps which may not work
|
21
21
|
# for all adaptors
|
22
|
-
#
|
22
|
+
#
|
23
23
|
FALLBACK_MAPPING = {
|
24
24
|
'UNSIGNED INTEGER' => :integer
|
25
25
|
}
|
@@ -49,42 +49,44 @@ module OMF::OML
|
|
49
49
|
@on_new_stream_procs.delete key
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
53
|
-
# Return a table (more precisely an OmlTable instance) fed from
|
52
|
+
|
53
|
+
# Return a table (more precisely an OmlTable instance) fed from
|
54
54
|
# the content of a table 'table_name' in this database.
|
55
55
|
#
|
56
56
|
# table_name - Name of table in the SQL database
|
57
|
-
# opts -
|
58
|
-
# :include_oml_internals - Include OML 'header' columns [true]
|
57
|
+
# opts -
|
59
58
|
# :name - name used for returned OML Table [table_name]
|
60
59
|
# All other options defined for OmlSqlRow#new
|
61
60
|
#
|
62
61
|
def create_table(table_name, opts = {})
|
63
62
|
tn = opts.delete(:name) || table_name
|
64
63
|
schema = _schema_for_table(table_name)
|
65
|
-
r = OmlSqlRow.new(table_name, schema,
|
64
|
+
r = OmlSqlRow.new(table_name, schema, _def_query_for_table(table_name), opts)
|
66
65
|
r.to_table(tn, opts)
|
67
66
|
end
|
68
|
-
|
67
|
+
|
69
68
|
# Call 'block' for every row in 'table_name' table.
|
70
69
|
#
|
71
70
|
# table_name - Name of table in the SQL database
|
72
|
-
# opts -
|
73
|
-
# :include_oml_internals[boolean] - Include OML 'header' columns [true]
|
71
|
+
# opts -
|
74
72
|
# :schema[Schema] Schema to use for creating row
|
75
73
|
# All other options defined for OmlSqlRow#new
|
74
|
+
# returns OmlSqlRow
|
76
75
|
#
|
77
76
|
def create_stream(table_name, opts = {}, &block)
|
78
77
|
rschema = opts.delete(:schema)
|
79
78
|
schema = _schema_for_table(table_name)
|
80
|
-
r = OmlSqlRow.new(table_name, schema,
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
r = OmlSqlRow.new(table_name, schema, _def_query_for_table(table_name), opts)
|
80
|
+
if block
|
81
|
+
ropts = {}
|
82
|
+
ropts[:schema] = rschema if rschema
|
83
|
+
r.to_stream(ropts, &block)
|
84
|
+
end
|
85
|
+
r
|
84
86
|
end
|
85
87
|
|
86
88
|
#
|
87
|
-
# Run a query on the database and return the result as an OmlTable. The provided schema
|
89
|
+
# Run a query on the database and return the result as an OmlTable. The provided schema
|
88
90
|
# needs to describe the SQL queries result set. Unfortunately we can only do very little
|
89
91
|
# sanity checks here
|
90
92
|
#
|
@@ -96,6 +98,33 @@ module OMF::OML
|
|
96
98
|
tbl
|
97
99
|
end
|
98
100
|
|
101
|
+
#
|
102
|
+
# Run a query on the database and return the result as an OmlTable. The provided schema
|
103
|
+
# needs to describe the SQL queries result set. Unfortunately we can only do very little
|
104
|
+
# sanity checks here. The query will be defined in the provided block which is passed in
|
105
|
+
# the Sequel Database object and is expected to return a Sequel Dataset instance.
|
106
|
+
#
|
107
|
+
def query2(table_name, schema, &block)
|
108
|
+
tbl = OmlTable.create(table_name, schema)
|
109
|
+
q = block.call(@db)
|
110
|
+
unless q.is_a? Sequel::Dataset
|
111
|
+
raise "Expected a Sequel::Dataset object, but got '#{q.class}'"
|
112
|
+
end
|
113
|
+
q.each do |row|
|
114
|
+
tbl << tbl.schema.hash_to_row(row)
|
115
|
+
end
|
116
|
+
tbl
|
117
|
+
end
|
118
|
+
|
119
|
+
# Return a Sequel Dataset from 'table_name'. See Sequel documentation on
|
120
|
+
# what one can do with that.
|
121
|
+
#
|
122
|
+
# db_table_name Name of table in database
|
123
|
+
#
|
124
|
+
def dataset(db_table_name)
|
125
|
+
@db.from(db_table_name)
|
126
|
+
end
|
127
|
+
|
99
128
|
# Start checking the database for tables and create a new stream
|
100
129
|
# by calling the internal +report_new_table+ method.
|
101
130
|
# If +check_every+ > 0 continue checking every +check_every+ seconds
|
@@ -130,11 +159,6 @@ module OMF::OML
|
|
130
159
|
report_new_table(table_name) unless table_name.start_with?('_')
|
131
160
|
end
|
132
161
|
@tables
|
133
|
-
|
134
|
-
# postgresql
|
135
|
-
# SELECT tablename FROM pg_tables
|
136
|
-
# WHERE tablename NOT LIKE �pg\\_%�
|
137
|
-
# AND tablename NOT LIKE �sql\\_%�;
|
138
162
|
end
|
139
163
|
|
140
164
|
|
@@ -158,7 +182,7 @@ module OMF::OML
|
|
158
182
|
end
|
159
183
|
table
|
160
184
|
end
|
161
|
-
|
185
|
+
|
162
186
|
def _schema_for_table(table_name)
|
163
187
|
begin
|
164
188
|
schema_descr = @db.schema(table_name).map do |col_name, cd|
|
@@ -173,30 +197,54 @@ module OMF::OML
|
|
173
197
|
raise "Problems reading schema of table '#{table_name}'. Does it exist? (#{@db.tables})"
|
174
198
|
end
|
175
199
|
end
|
200
|
+
|
201
|
+
def _def_query_for_table(table_name)
|
202
|
+
t = table_name
|
203
|
+
@db["SELECT _senders.name as oml_sender, a.* FROM #{t} AS a INNER JOIN _senders ON (_senders.id = a.oml_sender_id);"]
|
204
|
+
end
|
176
205
|
end
|
177
|
-
|
206
|
+
|
178
207
|
|
179
208
|
|
180
209
|
end
|
181
210
|
|
182
211
|
if $0 == __FILE__
|
212
|
+
OMF::Base::Loggable.init_log('sql_source_test')
|
183
213
|
|
184
214
|
require 'omf_oml/table'
|
185
|
-
|
186
|
-
ep.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
215
|
+
db_file = File.join(File.dirname(__FILE__), '../../test/data/brooklynDemo.sq3')
|
216
|
+
ep = OMF::OML::OmlSqlSource.new('sqlite://' + File.absolute_path(db_file), limit: 10)
|
217
|
+
|
218
|
+
def on_new_stream(ep)
|
219
|
+
ep.on_new_stream() do |s|
|
220
|
+
puts ">>>>>>>>>>>> New stream #{s.stream_name}: #{s.schema.names}"
|
221
|
+
case s.stream_name
|
222
|
+
when 'wimaxmonitor_wimaxstatus'
|
223
|
+
select = [:oml_ts_server, :sender_hostname, :frequency, :signal, :rssi, :cinr, :avg_tx_pwr]
|
224
|
+
when 'GPSlogger_gps_data'
|
225
|
+
select = [:oml_ts_server, :oml_sender_id, :lat, :lon]
|
226
|
+
end
|
194
227
|
|
195
|
-
|
196
|
-
|
228
|
+
s.on_new_tuple() do |v|
|
229
|
+
begin
|
230
|
+
puts "New vector(#{s.stream_name}): #{v.select(*select).join('|')}"
|
231
|
+
rescue Exception => ex
|
232
|
+
puts "ERROR: #{ex}"
|
233
|
+
abort
|
234
|
+
end
|
235
|
+
end
|
197
236
|
end
|
237
|
+
ep.run()
|
198
238
|
end
|
199
|
-
|
239
|
+
|
240
|
+
t = ep.query2('gps', [[:lat, :float], [:lon, :float]]) do |db|
|
241
|
+
db.from('GPSlogger_gps_data').select(:lat, :lon).limit(2)
|
242
|
+
end
|
243
|
+
puts t.rows.inspect
|
244
|
+
puts t.schema
|
245
|
+
|
246
|
+
# Raw query on database
|
247
|
+
puts ep.dataset('GPSlogger_gps_data').select(:lat, :lon).limit(2).all
|
200
248
|
|
201
249
|
end
|
202
250
|
|
data/lib/omf_oml/table.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
require 'monitor'
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'omf_base/lobject'
|
5
5
|
require 'omf_oml'
|
6
6
|
require 'omf_oml/schema'
|
7
7
|
|
@@ -12,8 +12,11 @@ module OMF::OML
|
|
12
12
|
# This class represents a database like table holding a sequence of OML measurements (rows) according
|
13
13
|
# a common schema.
|
14
14
|
#
|
15
|
-
class OmlTable < OMF::
|
15
|
+
class OmlTable < OMF::Base::LObject
|
16
16
|
|
17
|
+
# @param opts
|
18
|
+
# @opts :index Creates an index table (all rows have distinct values at column 'index')
|
19
|
+
#
|
17
20
|
def self.create(tname, schema, opts = {}, &on_before_row_added)
|
18
21
|
if (index = opts.delete(:index))
|
19
22
|
require 'omf_oml/indexed_table'
|
data/lib/omf_oml/tuple.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'omf_base/lobject'
|
3
3
|
require 'omf_oml'
|
4
4
|
require 'omf_oml/schema'
|
5
5
|
|
@@ -14,7 +14,7 @@ module OMF::OML
|
|
14
14
|
# Use +OmlTuple+ if the schema is an OML one. +OmlTuple+ has additional convenience
|
15
15
|
# methods.
|
16
16
|
#
|
17
|
-
class Tuple < OMF::
|
17
|
+
class Tuple < OMF::Base::LObject
|
18
18
|
|
19
19
|
# Return a specific element of the tuple identified either
|
20
20
|
# by it's name, or its col index
|
data/lib/omf_oml/version.rb
CHANGED
data/omf_oml.gemspec
CHANGED
@@ -23,5 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
# specify any dependencies here; for example:
|
24
24
|
# s.add_development_dependency "minitest", "~> 2.11.3"
|
25
25
|
#s.add_runtime_dependency "sqlite3", "~> 1.3.6"
|
26
|
+
s.add_runtime_dependency 'omf_base'
|
26
27
|
s.add_runtime_dependency 'sequel', '~> 3.45'
|
27
28
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omf_oml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: omf_base
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: sequel
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,6 +55,7 @@ files:
|
|
39
55
|
- Gemfile
|
40
56
|
- Rakefile
|
41
57
|
- lib/omf_oml.rb
|
58
|
+
- lib/omf_oml/csv_table.rb
|
42
59
|
- lib/omf_oml/endpoint.rb
|
43
60
|
- lib/omf_oml/indexed_table.rb
|
44
61
|
- lib/omf_oml/network.rb
|
@@ -51,6 +68,7 @@ files:
|
|
51
68
|
- lib/omf_oml/tuple.rb
|
52
69
|
- lib/omf_oml/version.rb
|
53
70
|
- omf_oml.gemspec
|
71
|
+
- test/data/brooklynDemo.sq3
|
54
72
|
homepage: https://www.mytestbed.net
|
55
73
|
licenses: []
|
56
74
|
post_install_message:
|
@@ -71,9 +89,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
89
|
version: '0'
|
72
90
|
requirements: []
|
73
91
|
rubyforge_project: omf_oml
|
74
|
-
rubygems_version: 1.8.
|
92
|
+
rubygems_version: 1.8.23
|
75
93
|
signing_key:
|
76
94
|
specification_version: 3
|
77
95
|
summary: Glue between OMF and OML.
|
78
|
-
test_files:
|
79
|
-
|
96
|
+
test_files:
|
97
|
+
- test/data/brooklynDemo.sq3
|