metric_system 0.1.2 → 0.1.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/metric_system.rb +1 -1
- data/lib/metric_system/database.rb +9 -6
- data/lib/metric_system/version.rb +1 -1
- data/lib/metric_system/web.rb +28 -12
- data/lib/metric_system/web/dashboard.erb +3 -7
- data/lib/sqlite3/database_extension.rb +16 -17
- data/lib/sqlite3/query.rb +34 -1
- data/test/benchmark.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c313b1e1c7d585f73c1210c3fb3bc610268d804
|
4
|
+
data.tar.gz: 26cf80941ed294412d5afb60e79b883ae13e2fa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c2b87a70402f5f6090c33f39228c0762777abedbd9f0d27caee1092442a6943a782576a45a48e84b6aec0ce54b4db7080abb9dbbf1a0759575274f0262f847c
|
7
|
+
data.tar.gz: a8e41c77e9810bed3d53e7bbd6c3e30c167d1ffac75c09d41d7955e6b737534cf2f1d0e618d667e5fd979d0398002caf80fc9730c3a94fa6249cb504aa3ec317
|
data/lib/metric_system.rb
CHANGED
@@ -23,7 +23,7 @@ module MetricSystem
|
|
23
23
|
end
|
24
24
|
|
25
25
|
extend Forwardable
|
26
|
-
delegate [:aggregate, :select, :print, :run, :ask
|
26
|
+
delegate [:aggregate, :select, :print, :run, :ask] => :"@target"
|
27
27
|
delegate [:transaction] => :"@target"
|
28
28
|
delegate [:add_event] => :"@target"
|
29
29
|
delegate [:quit_server!] => :"@target"
|
@@ -1,12 +1,15 @@
|
|
1
1
|
class MetricSystem::Database
|
2
|
-
def initialize(path)
|
2
|
+
def initialize(path, readonly = false)
|
3
3
|
require_relative "./sqlite3_extensions"
|
4
4
|
open path
|
5
|
+
|
6
|
+
exec "PRAGMA query_only = 1" if readonly # This might or might not work.
|
7
|
+
@db.readonly = !!readonly
|
5
8
|
end
|
6
9
|
|
7
10
|
extend Forwardable
|
8
11
|
|
9
|
-
delegate [:exec, :select, :transaction, :rollback, :print, :run, :ask, :register] => :"@db"
|
12
|
+
delegate [:exec, :select, :transaction, :rollback, :print, :run, :ask, :register, :readonly?] => :"@db"
|
10
13
|
|
11
14
|
PERIODS = [
|
12
15
|
[ :year, 31536000, "strftime('%Y-01-01', starts_at, 'unixepoch')" ],
|
@@ -103,7 +106,7 @@ class MetricSystem::Database
|
|
103
106
|
aggregate_for_period :period => period, :source => :counters, :dest => :aggregated_counters, :aggregate => "sum"
|
104
107
|
end
|
105
108
|
|
106
|
-
|
109
|
+
exec "DELETE FROM counters"
|
107
110
|
end
|
108
111
|
|
109
112
|
transaction do
|
@@ -111,7 +114,7 @@ class MetricSystem::Database
|
|
111
114
|
aggregate_for_period :period => period, :source => :gauges, :dest => :aggregated_gauges, :aggregate => "CAST(sum AS FLOAT) / count"
|
112
115
|
end
|
113
116
|
|
114
|
-
|
117
|
+
exec "DELETE FROM gauges"
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
@@ -128,7 +131,7 @@ class MetricSystem::Database
|
|
128
131
|
# sql expression to calculate value from sum and count of event values
|
129
132
|
aggregate = source == :gauges ? "CAST(sum AS FLOAT) / count" : "sum"
|
130
133
|
|
131
|
-
|
134
|
+
exec <<-SQL
|
132
135
|
CREATE TEMPORARY TABLE batch AS
|
133
136
|
SELECT name, starts_at, SUM(sum) AS sum, SUM(count) AS count FROM
|
134
137
|
(
|
@@ -157,7 +160,7 @@ class MetricSystem::Database
|
|
157
160
|
FROM batch;
|
158
161
|
SQL
|
159
162
|
|
160
|
-
|
163
|
+
exec <<-SQL
|
161
164
|
DROP TABLE batch;
|
162
165
|
SQL
|
163
166
|
end
|
data/lib/metric_system/web.rb
CHANGED
@@ -1,27 +1,43 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'to_js'
|
3
|
-
|
4
|
-
module GoogleCharts
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def convert(results)
|
8
|
-
results.description.to_js
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
end
|
3
|
+
require 'metric_system/database'
|
14
4
|
|
15
5
|
class MetricSystem::Web < Sinatra::Base
|
16
6
|
set :environment, :development
|
17
7
|
set :raise_errors, true
|
18
8
|
set :views, "#{File.dirname(__FILE__)}/web"
|
19
9
|
set :dump_errors, true
|
10
|
+
set :database, nil
|
11
|
+
|
12
|
+
def self.register_query(name, query)
|
13
|
+
registry[name] = query
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.registry
|
17
|
+
@registry ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# return a database for the current thread
|
21
|
+
def self.connection
|
22
|
+
Thread.current[:"MetricSystem::Web.database"] ||= MetricSystem::Database.new(self.database, :readonly)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.select(query, *args)
|
26
|
+
expect! query => [ String, Symbol ]
|
27
|
+
|
28
|
+
if query.is_a?(Symbol)
|
29
|
+
expect! query => registry.keys
|
30
|
+
query = registry.fetch(query)
|
31
|
+
end
|
32
|
+
|
33
|
+
result = connection.select query, *args #period: "month"
|
34
|
+
result.data_table.to_js
|
35
|
+
end
|
20
36
|
|
21
37
|
helpers do
|
22
38
|
def select(query, *args)
|
23
39
|
@result_cache ||= {}
|
24
|
-
@result_cache[query] ||=
|
40
|
+
@result_cache[[query, args]] ||= self.class.select(query, *args, params)
|
25
41
|
end
|
26
42
|
end
|
27
43
|
|
@@ -116,22 +116,18 @@
|
|
116
116
|
<div>
|
117
117
|
<h3>Table</h3>
|
118
118
|
<div class="google-visualization">
|
119
|
-
<%=
|
120
|
-
select "SELECT date(starts_at), value FROM aggregates WHERE period='day'"
|
121
|
-
%>
|
119
|
+
<%= select "SELECT date(starts_at), value FROM aggregates WHERE period=:period" %>
|
122
120
|
</div>
|
123
121
|
</div>
|
124
122
|
<div>
|
125
123
|
<h3>Pie Chart</h3>
|
126
|
-
<div class="google-visualization" data-src="/value_by_day_name.js" data-chart="pie">
|
124
|
+
<div class="google-visualization" data-src="/value_by_day_name.js?period=month" data-chart="pie">
|
127
125
|
</div>
|
128
126
|
</div>
|
129
127
|
<div>
|
130
128
|
<h3>Area Chart</h3>
|
131
129
|
<div class="google-visualization" data-chart="area">
|
132
|
-
<%=
|
133
|
-
select "SELECT date(starts_at), value FROM aggregates WHERE period='day'"
|
134
|
-
%>
|
130
|
+
<%= select "SELECT date(starts_at), value FROM aggregates WHERE period=:period" %>
|
135
131
|
</div>
|
136
132
|
</div>
|
137
133
|
<div>
|
@@ -1,6 +1,16 @@
|
|
1
1
|
class SQLite3::Database
|
2
|
+
def readonly?
|
3
|
+
@readonly
|
4
|
+
end
|
5
|
+
|
6
|
+
def readonly=(readonly)
|
7
|
+
@readonly = readonly
|
8
|
+
end
|
9
|
+
|
2
10
|
# execute multiple SQL statements at once.
|
3
11
|
def exec(sql, *args)
|
12
|
+
raise "Cannot run nondestructive query: #{sql}" if readonly?
|
13
|
+
|
4
14
|
args = prepare_arguments(args)
|
5
15
|
|
6
16
|
while sql =~ /\S/ do
|
@@ -22,15 +32,14 @@ class SQLite3::Database
|
|
22
32
|
private
|
23
33
|
|
24
34
|
def query(sql)
|
25
|
-
expect! sql =>
|
26
|
-
|
27
|
-
if sql.is_a?(Symbol)
|
28
|
-
expect! sql => registry.keys
|
29
|
-
sql = registry.fetch(sql)
|
30
|
-
end
|
35
|
+
expect! sql => String
|
31
36
|
|
32
37
|
@queries ||= {}
|
33
|
-
@queries[sql] ||=
|
38
|
+
query = @queries[sql] ||= begin
|
39
|
+
query = SQLite3::Query.new sql, prepare(sql)
|
40
|
+
raise "Cannot run nondestructive query: #{sql}" if readonly? && query.destructive?
|
41
|
+
query
|
42
|
+
end
|
34
43
|
end
|
35
44
|
|
36
45
|
def prepare_arguments(args)
|
@@ -72,14 +81,4 @@ class SQLite3::Database
|
|
72
81
|
end
|
73
82
|
puts "=" * log_sql.length
|
74
83
|
end
|
75
|
-
|
76
|
-
# -- query registry
|
77
|
-
|
78
|
-
def registry
|
79
|
-
@registry ||= {}
|
80
|
-
end
|
81
|
-
|
82
|
-
def register(name, query)
|
83
|
-
registry[name] = query
|
84
|
-
end
|
85
84
|
end
|
data/lib/sqlite3/query.rb
CHANGED
@@ -1,12 +1,43 @@
|
|
1
|
+
class SQLite3::MissingParameters < RuntimeError
|
2
|
+
end
|
3
|
+
|
1
4
|
class SQLite3::Query
|
5
|
+
|
6
|
+
# all parameters in the query, as Symbols.
|
7
|
+
attr :parameters
|
8
|
+
|
2
9
|
def initialize(sql, statement)
|
3
10
|
expect! statement => SQLite3::Statement
|
4
11
|
|
5
12
|
@sql, @statement = sql, statement
|
13
|
+
@parameters = @sql.scan(/:([a-z]+)/).map(&:first).map(&:to_sym)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destructive?
|
17
|
+
@sql !~ /\A\S*SELECT/i
|
6
18
|
end
|
7
19
|
|
8
20
|
def run(*args)
|
9
|
-
|
21
|
+
if parameters.length > 0
|
22
|
+
named_args = {}
|
23
|
+
|
24
|
+
if args.last.is_a?(Hash)
|
25
|
+
args.pop.each do |name, value|
|
26
|
+
named_args[name.to_sym] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
missing = parameters - named_args.keys
|
31
|
+
unless missing.empty?
|
32
|
+
raise SQLite3::MissingParameters, "Missing parameter(s): #{missing.inspect}"
|
33
|
+
end
|
34
|
+
|
35
|
+
named_args = named_args.select do |name, value|
|
36
|
+
parameters.include?(name)
|
37
|
+
end
|
38
|
+
args << named_args
|
39
|
+
end
|
40
|
+
|
10
41
|
@statement.execute *args
|
11
42
|
end
|
12
43
|
|
@@ -44,6 +75,8 @@ class SQLite3::Query
|
|
44
75
|
{ cols: cols, rows: rows }
|
45
76
|
end
|
46
77
|
|
78
|
+
private
|
79
|
+
|
47
80
|
def convert_record(record, cols)
|
48
81
|
values = cols.map do |col|
|
49
82
|
id, type = col.values_at(:id, :type)
|
data/test/benchmark.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metric_system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expectation
|