skydb 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +165 -1
- data/lib/skydb.rb +18 -61
- data/lib/skydb/client.rb +186 -186
- data/lib/skydb/event.rb +47 -76
- data/lib/skydb/property.rb +34 -67
- data/lib/skydb/table.rb +121 -41
- data/lib/skydb/version.rb +1 -1
- data/test/integration/client_test.rb +88 -0
- data/test/test_helper.rb +3 -51
- data/test/unit/client_test.rb +135 -32
- metadata +17 -278
- data/bin/sky +0 -89
- data/lib/ext/hash.rb +0 -11
- data/lib/ext/string.rb +0 -11
- data/lib/ext/treetop.rb +0 -19
- data/lib/skydb/action.rb +0 -76
- data/lib/skydb/import.rb +0 -7
- data/lib/skydb/import/importer.rb +0 -435
- data/lib/skydb/import/transforms/apache.yml +0 -4
- data/lib/skydb/import/transforms/sky.yml +0 -28
- data/lib/skydb/import/transforms/snowplow.yml +0 -1
- data/lib/skydb/import/translator.rb +0 -119
- data/lib/skydb/message.rb +0 -146
- data/lib/skydb/message/add_action.rb +0 -53
- data/lib/skydb/message/add_event.rb +0 -72
- data/lib/skydb/message/add_property.rb +0 -55
- data/lib/skydb/message/create_table.rb +0 -64
- data/lib/skydb/message/delete_table.rb +0 -66
- data/lib/skydb/message/get_action.rb +0 -55
- data/lib/skydb/message/get_actions.rb +0 -38
- data/lib/skydb/message/get_properties.rb +0 -38
- data/lib/skydb/message/get_property.rb +0 -55
- data/lib/skydb/message/get_table.rb +0 -74
- data/lib/skydb/message/get_tables.rb +0 -43
- data/lib/skydb/message/lookup.rb +0 -79
- data/lib/skydb/message/lua/aggregate.rb +0 -63
- data/lib/skydb/message/multi.rb +0 -57
- data/lib/skydb/message/next_actions.rb +0 -55
- data/lib/skydb/message/ping.rb +0 -32
- data/lib/skydb/property/type.rb +0 -40
- data/lib/skydb/query.rb +0 -183
- data/lib/skydb/query/after_condition.rb +0 -104
- data/lib/skydb/query/ast/selection_field_syntax_node.rb +0 -26
- data/lib/skydb/query/ast/selection_fields_syntax_node.rb +0 -16
- data/lib/skydb/query/ast/selection_group_syntax_node.rb +0 -16
- data/lib/skydb/query/ast/selection_groups_syntax_node.rb +0 -16
- data/lib/skydb/query/condition.rb +0 -113
- data/lib/skydb/query/on_condition.rb +0 -53
- data/lib/skydb/query/selection.rb +0 -398
- data/lib/skydb/query/selection_field.rb +0 -99
- data/lib/skydb/query/selection_fields_grammar.treetop +0 -46
- data/lib/skydb/query/selection_fields_parse_error.rb +0 -30
- data/lib/skydb/query/selection_group.rb +0 -78
- data/lib/skydb/query/selection_groups_grammar.treetop +0 -31
- data/lib/skydb/query/selection_groups_parse_error.rb +0 -30
- data/lib/skydb/query/validation_error.rb +0 -8
- data/lib/skydb/timestamp.rb +0 -22
- data/test/integration/query_test.rb +0 -102
- data/test/unit/event_test.rb +0 -32
- data/test/unit/import/importer_test.rb +0 -208
- data/test/unit/import/translator_test.rb +0 -88
- data/test/unit/message/add_action_message_test.rb +0 -34
- data/test/unit/message/add_event_message_test.rb +0 -35
- data/test/unit/message/add_property_message_test.rb +0 -41
- data/test/unit/message/create_table_message_test.rb +0 -34
- data/test/unit/message/delete_table_message_test.rb +0 -34
- data/test/unit/message/get_action_message_test.rb +0 -34
- data/test/unit/message/get_actions_message_test.rb +0 -18
- data/test/unit/message/get_properties_message_test.rb +0 -18
- data/test/unit/message/get_property_message_test.rb +0 -34
- data/test/unit/message/get_table_message_test.rb +0 -19
- data/test/unit/message/get_tables_message_test.rb +0 -18
- data/test/unit/message/lookup_message_test.rb +0 -27
- data/test/unit/message/lua_aggregate_message_test.rb +0 -19
- data/test/unit/message/multi_message_test.rb +0 -22
- data/test/unit/message/next_action_message_test.rb +0 -34
- data/test/unit/message/ping_message_test.rb +0 -18
- data/test/unit/message_test.rb +0 -15
- data/test/unit/query/after_test.rb +0 -89
- data/test/unit/query/on_test.rb +0 -71
- data/test/unit/query/selection_test.rb +0 -273
- data/test/unit/query_test.rb +0 -182
- data/test/unit/skydb_test.rb +0 -20
@@ -1,99 +0,0 @@
|
|
1
|
-
class SkyDB
|
2
|
-
# The selection field is a single field in the selection part of the query.
|
3
|
-
# This can include a simple property or it can be the aggregation of a
|
4
|
-
# property. Fields can also be aliased to a different name that is returned.
|
5
|
-
# This is typically useful when naming aggregated fields.
|
6
|
-
class Query
|
7
|
-
class SelectionField
|
8
|
-
##########################################################################
|
9
|
-
#
|
10
|
-
# Constructor
|
11
|
-
#
|
12
|
-
##########################################################################
|
13
|
-
|
14
|
-
def initialize(options={})
|
15
|
-
self.expression = options[:expression]
|
16
|
-
self.alias_name = options[:alias_name]
|
17
|
-
self.aggregation_type = options[:aggregation_type]
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
##########################################################################
|
22
|
-
#
|
23
|
-
# Attributes
|
24
|
-
#
|
25
|
-
##########################################################################
|
26
|
-
|
27
|
-
# The name of the property to select.
|
28
|
-
attr_accessor :expression
|
29
|
-
|
30
|
-
# The field name that is actually returned.
|
31
|
-
attr_accessor :alias_name
|
32
|
-
|
33
|
-
# The type of the aggregation used to process the property.
|
34
|
-
attr_accessor :aggregation_type
|
35
|
-
|
36
|
-
# The final computed name of the field. It is named after the alias name
|
37
|
-
# if provided, otherwise defaults to the expression. If neither the
|
38
|
-
# expression or alias are provided then the aggregation type is used.
|
39
|
-
def target_name
|
40
|
-
return alias_name || expression || aggregation_type.to_s
|
41
|
-
end
|
42
|
-
|
43
|
-
# The string used to access the expression.
|
44
|
-
def accessor(options={})
|
45
|
-
prefix = options.delete(:prefix) || 'cursor.event.'
|
46
|
-
|
47
|
-
if ["action_id", "timestamp"].index(expression)
|
48
|
-
return "#{prefix}#{expression}"
|
49
|
-
else
|
50
|
-
return "#{prefix}#{expression}()"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
##########################################################################
|
56
|
-
#
|
57
|
-
# Methods
|
58
|
-
#
|
59
|
-
##########################################################################
|
60
|
-
|
61
|
-
####################################
|
62
|
-
# Validation
|
63
|
-
####################################
|
64
|
-
|
65
|
-
# Validates that the field is valid.
|
66
|
-
def validate!
|
67
|
-
# Expression must be present unless this is a COUNT().
|
68
|
-
if expression.to_s.length == 0 && aggregation_type != :count
|
69
|
-
raise SkyDB::Query::ValidationError.new("Invalid expression for selection field: '#{expression.to_s}'")
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
####################################
|
74
|
-
# Serialization
|
75
|
-
####################################
|
76
|
-
|
77
|
-
# Serializes the selection field object into a JSON string.
|
78
|
-
def to_json(*a); to_hash.to_json(*a); end
|
79
|
-
|
80
|
-
# Serializes the selection field object into a hash.
|
81
|
-
def to_hash(*a)
|
82
|
-
{
|
83
|
-
'expression' => expression.to_s,
|
84
|
-
'aliasName' => alias_name.to_s,
|
85
|
-
'aggregationType' => aggregation_type.to_s
|
86
|
-
}.delete_if {|k,v| v == ''}
|
87
|
-
end
|
88
|
-
|
89
|
-
# Deserializes the selection field object from a hash.
|
90
|
-
def from_hash(hash, *a)
|
91
|
-
return nil if hash.nil?
|
92
|
-
self.expression = hash['expression']
|
93
|
-
self.alias_name = hash['aliasName']
|
94
|
-
self.aggregation_type = hash['aggregationType'].to_s != '' ? hash['aggregationType'].to_s.to_sym : nil
|
95
|
-
return self
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
grammar SelectionFieldsGrammar
|
2
|
-
rule root
|
3
|
-
fields <SkyDB::Query::Ast::SelectionFieldsSyntaxNode>
|
4
|
-
end
|
5
|
-
|
6
|
-
# Matches all selection fields.
|
7
|
-
rule fields
|
8
|
-
ws field (ws ',' ws field)* ws
|
9
|
-
end
|
10
|
-
|
11
|
-
# Matches a single field name as well as additional options such as an alias
|
12
|
-
# or an aggregation method.
|
13
|
-
rule field
|
14
|
-
aggregation_type '(' ws ')' ws alias_name <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
15
|
-
/
|
16
|
-
aggregation_type '(' ws ')' <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
17
|
-
/
|
18
|
-
aggregation_type '(' ws expression ws ')' ws alias_name <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
19
|
-
/
|
20
|
-
aggregation_type '(' ws expression ws ')' <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
21
|
-
/
|
22
|
-
expression ws alias_name <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
23
|
-
/
|
24
|
-
expression <SkyDB::Query::Ast::SelectionFieldSyntaxNode>
|
25
|
-
end
|
26
|
-
|
27
|
-
rule expression
|
28
|
-
identifier
|
29
|
-
end
|
30
|
-
|
31
|
-
rule alias_name
|
32
|
-
identifier
|
33
|
-
end
|
34
|
-
|
35
|
-
rule aggregation_type
|
36
|
-
([a-zA-Z]+)
|
37
|
-
end
|
38
|
-
|
39
|
-
rule identifier
|
40
|
-
([a-zA-Z_] [a-zA-Z0-9_]*)
|
41
|
-
end
|
42
|
-
|
43
|
-
rule ws
|
44
|
-
(' ' / "\t" / "\n" / "\r")*
|
45
|
-
end
|
46
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
class SkyDB
|
2
|
-
class Query
|
3
|
-
class SelectionFieldsParseError < StandardError
|
4
|
-
##########################################################################
|
5
|
-
#
|
6
|
-
# Constructor
|
7
|
-
#
|
8
|
-
##########################################################################
|
9
|
-
|
10
|
-
def initialize(message, options={})
|
11
|
-
super(message)
|
12
|
-
@line = options[:line].to_i
|
13
|
-
@column = options[:column].to_i
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
##########################################################################
|
18
|
-
#
|
19
|
-
# Attributes
|
20
|
-
#
|
21
|
-
##########################################################################
|
22
|
-
|
23
|
-
# The line number that the error occurred on.
|
24
|
-
attr_reader :line
|
25
|
-
|
26
|
-
# The column number that the error occurred on.
|
27
|
-
attr_reader :column
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
class SkyDB
|
2
|
-
# The selection group contains an expression by which to group selected
|
3
|
-
# data.
|
4
|
-
class Query
|
5
|
-
class SelectionGroup
|
6
|
-
##########################################################################
|
7
|
-
#
|
8
|
-
# Constructor
|
9
|
-
#
|
10
|
-
##########################################################################
|
11
|
-
|
12
|
-
def initialize(options={})
|
13
|
-
self.expression = options[:expression]
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
##########################################################################
|
18
|
-
#
|
19
|
-
# Attributes
|
20
|
-
#
|
21
|
-
##########################################################################
|
22
|
-
|
23
|
-
# The name of the expression to group by.
|
24
|
-
attr_accessor :expression
|
25
|
-
|
26
|
-
# The string used to access the expression.
|
27
|
-
def accessor(options={})
|
28
|
-
prefix = options.delete(:prefix) || 'cursor.event.'
|
29
|
-
|
30
|
-
if ["action_id", "timestamp"].index(expression)
|
31
|
-
return "#{prefix}#{expression}"
|
32
|
-
else
|
33
|
-
return "#{prefix}#{expression}()"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
##########################################################################
|
39
|
-
#
|
40
|
-
# Methods
|
41
|
-
#
|
42
|
-
##########################################################################
|
43
|
-
|
44
|
-
####################################
|
45
|
-
# Validation
|
46
|
-
####################################
|
47
|
-
|
48
|
-
# Validates that the field is valid.
|
49
|
-
def validate!
|
50
|
-
# Expression must be present.
|
51
|
-
if expression.to_s.length == 0
|
52
|
-
raise SkyDB::Query::ValidationError.new("Invalid expression for selection group: '#{expression.to_s}'")
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
####################################
|
57
|
-
# Serialization
|
58
|
-
####################################
|
59
|
-
|
60
|
-
# Serializes the selection group into a JSON string.
|
61
|
-
def to_json(*a); to_hash.to_json(*a); end
|
62
|
-
|
63
|
-
# Serializes the selection group into a hash.
|
64
|
-
def to_hash(*a)
|
65
|
-
{
|
66
|
-
'expression' => expression.to_s
|
67
|
-
}.delete_if {|k,v| v == ''}
|
68
|
-
end
|
69
|
-
|
70
|
-
# Deserializes the selection field object from a hash.
|
71
|
-
def from_hash(hash, *a)
|
72
|
-
return nil if hash.nil?
|
73
|
-
self.expression = hash['expression']
|
74
|
-
return self
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
grammar SelectionGroupsGrammar
|
2
|
-
rule root
|
3
|
-
groups <SkyDB::Query::Ast::SelectionGroupsSyntaxNode>
|
4
|
-
end
|
5
|
-
|
6
|
-
# Matches all selection groups.
|
7
|
-
rule groups
|
8
|
-
ws group (ws ',' ws group)* ws
|
9
|
-
end
|
10
|
-
|
11
|
-
# Matches a single group name and optional alias.
|
12
|
-
rule group
|
13
|
-
expression <SkyDB::Query::Ast::SelectionGroupSyntaxNode>
|
14
|
-
end
|
15
|
-
|
16
|
-
rule expression
|
17
|
-
identifier
|
18
|
-
end
|
19
|
-
|
20
|
-
rule alias_name
|
21
|
-
identifier
|
22
|
-
end
|
23
|
-
|
24
|
-
rule identifier
|
25
|
-
([a-zA-Z_] [a-zA-Z0-9_]*)
|
26
|
-
end
|
27
|
-
|
28
|
-
rule ws
|
29
|
-
(' ' / "\t" / "\n" / "\r")*
|
30
|
-
end
|
31
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
class SkyDB
|
2
|
-
class Query
|
3
|
-
class SelectionGroupsParseError < StandardError
|
4
|
-
##########################################################################
|
5
|
-
#
|
6
|
-
# Constructor
|
7
|
-
#
|
8
|
-
##########################################################################
|
9
|
-
|
10
|
-
def initialize(message, options={})
|
11
|
-
super(message)
|
12
|
-
@line = options[:line].to_i
|
13
|
-
@column = options[:column].to_i
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
##########################################################################
|
18
|
-
#
|
19
|
-
# Attributes
|
20
|
-
#
|
21
|
-
##########################################################################
|
22
|
-
|
23
|
-
# The line number that the error occurred on.
|
24
|
-
attr_reader :line
|
25
|
-
|
26
|
-
# The column number that the error occurred on.
|
27
|
-
attr_reader :column
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/lib/skydb/timestamp.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
class SkyDB
|
2
|
-
class Timestamp
|
3
|
-
##########################################################################
|
4
|
-
#
|
5
|
-
# Static Methods
|
6
|
-
#
|
7
|
-
##########################################################################
|
8
|
-
|
9
|
-
# Converts a Time object to a Sky timestamp value.
|
10
|
-
#
|
11
|
-
# @param [Time] time the time object.
|
12
|
-
#
|
13
|
-
# @return [Fixnum] the number of microseconds since the epoch (1970-01-01T00:00:00.000000Z).
|
14
|
-
def self.to_timestamp(time)
|
15
|
-
if time.nil?
|
16
|
-
return nil
|
17
|
-
else
|
18
|
-
return time.to_time.utc.to_i * 1_000_000
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class TestQuery < MiniTest::Unit::TestCase
|
4
|
-
##############################################################################
|
5
|
-
#
|
6
|
-
# Setup / Teardown
|
7
|
-
#
|
8
|
-
##############################################################################
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@query = SkyDB::Query.new()
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
##############################################################################
|
16
|
-
#
|
17
|
-
# Tests
|
18
|
-
#
|
19
|
-
##############################################################################
|
20
|
-
|
21
|
-
######################################
|
22
|
-
# Aggregation
|
23
|
-
######################################
|
24
|
-
|
25
|
-
def test_select_count
|
26
|
-
import("integration/query/count.json")
|
27
|
-
results = SkyDB.select('count()').execute()
|
28
|
-
assert_equal ({"count" => 7}), results
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_select_count_by_action_id
|
32
|
-
import("integration/query/count.json")
|
33
|
-
results = SkyDB.select('count()').group_by("action_id").execute()
|
34
|
-
assert_equal({
|
35
|
-
1=>{"count"=>2}, # /
|
36
|
-
2=>{"count"=>1}, # /signup
|
37
|
-
3=>{"count"=>2}, # /login
|
38
|
-
4=>{"count"=>1}, # /about
|
39
|
-
5=>{"count"=>1} # /cancel_account
|
40
|
-
}, results)
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
######################################
|
45
|
-
# Sessions
|
46
|
-
######################################
|
47
|
-
|
48
|
-
def test_select_count_by_action_id_on_enter
|
49
|
-
import("integration/query/count.json")
|
50
|
-
results = SkyDB.select('count()')
|
51
|
-
.group_by("action_id")
|
52
|
-
.on(:enter)
|
53
|
-
.execute()
|
54
|
-
assert_equal ({1 => {"count" => 2}}), results
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_select_count_by_action_id_on_enter_and_after
|
58
|
-
import("integration/query/count.json")
|
59
|
-
results = SkyDB.select('count()')
|
60
|
-
.group_by("action_id")
|
61
|
-
.on(:enter)
|
62
|
-
.after("/")
|
63
|
-
.execute()
|
64
|
-
assert_equal ({2=>{"count"=>1}, 3=>{"count"=>1}}), results
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_select_count_by_action_id_on_enter_and_after_sessionized
|
68
|
-
import("integration/query/count.json")
|
69
|
-
query = SkyDB.query.session(7200)
|
70
|
-
results = query.select('count()')
|
71
|
-
.group_by("action_id")
|
72
|
-
.on(:enter)
|
73
|
-
.after("/login")
|
74
|
-
.execute()
|
75
|
-
assert_equal ({"exit"=>{"count"=>1}, 5=>{"count"=>1}}), results
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_select_count_by_action_id_on_enter_and_after_within_sessionized
|
79
|
-
import("integration/query/count.json")
|
80
|
-
query = SkyDB.query.session(7200)
|
81
|
-
results = query.select('count()')
|
82
|
-
.group_by("action_id")
|
83
|
-
.on(:enter)
|
84
|
-
.after(:action => "/", :within => {:quantity => 1, :unit => 'step'})
|
85
|
-
.after(:action => "/login", :within => {:quantity => 1, :unit => 'step'})
|
86
|
-
.execute()
|
87
|
-
assert_equal ({5=>{"count"=>1}}), results
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_double_after
|
91
|
-
import("integration/query/double_after.json")
|
92
|
-
query = SkyDB.query.session(7200)
|
93
|
-
results = query.select('count()')
|
94
|
-
.group_by("action_id")
|
95
|
-
.on(:enter)
|
96
|
-
.after(:action => "/", :within => {:quantity => 1, :unit => 'step'})
|
97
|
-
.after(:action => "/login", :within => {:quantity => 1, :unit => 'step'})
|
98
|
-
.after(:action => "/login", :within => {:quantity => 1, :unit => 'step'})
|
99
|
-
.execute()
|
100
|
-
assert_equal ({"exit"=>{"count"=>1}}), results
|
101
|
-
end
|
102
|
-
end
|