skydb 0.2.1 → 0.2.2
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.
- data/bin/sky +85 -0
- data/lib/ext/hash.rb +11 -0
- data/lib/ext/treetop.rb +19 -0
- data/lib/skydb.rb +10 -3
- data/lib/skydb/client.rb +92 -28
- data/lib/skydb/import.rb +7 -0
- data/lib/skydb/import/importer.rb +258 -0
- data/lib/skydb/import/transforms/sky.yml +20 -0
- data/lib/skydb/import/transforms/snowplow.yml +1 -0
- data/lib/skydb/import/translator.rb +119 -0
- data/lib/skydb/message.rb +17 -12
- data/lib/skydb/message/create_table.rb +64 -0
- data/lib/skydb/message/delete_table.rb +66 -0
- data/lib/skydb/message/get_table.rb +74 -0
- data/lib/skydb/message/lookup.rb +79 -0
- data/lib/skydb/property.rb +5 -5
- data/lib/skydb/query.rb +198 -0
- data/lib/skydb/query/after.rb +103 -0
- data/lib/skydb/query/ast/selection_field_syntax_node.rb +26 -0
- data/lib/skydb/query/ast/selection_fields_syntax_node.rb +16 -0
- data/lib/skydb/query/ast/selection_group_syntax_node.rb +16 -0
- data/lib/skydb/query/ast/selection_groups_syntax_node.rb +16 -0
- data/lib/skydb/query/selection.rb +268 -0
- data/lib/skydb/query/selection_field.rb +74 -0
- data/lib/skydb/query/selection_fields_grammar.treetop +46 -0
- data/lib/skydb/query/selection_fields_parse_error.rb +30 -0
- data/lib/skydb/query/selection_group.rb +57 -0
- data/lib/skydb/query/selection_groups_grammar.treetop +31 -0
- data/lib/skydb/query/selection_groups_parse_error.rb +30 -0
- data/lib/skydb/query/validation_error.rb +8 -0
- data/lib/skydb/table.rb +69 -0
- data/lib/skydb/version.rb +1 -1
- data/test/import/importer_test.rb +42 -0
- data/test/import/translator_test.rb +88 -0
- data/test/message/add_event_message_test.rb +1 -1
- data/test/message/add_property_message_test.rb +2 -2
- data/test/message/create_table_message_test.rb +34 -0
- data/test/message/delete_table_message_test.rb +34 -0
- data/test/message/get_table_message_test.rb +19 -0
- data/test/message/lookup_message_test.rb +27 -0
- data/test/message_test.rb +1 -1
- data/test/query/after_test.rb +71 -0
- data/test/query/selection_test.rb +273 -0
- data/test/query_test.rb +156 -0
- data/test/test_helper.rb +3 -0
- metadata +129 -3
@@ -12,7 +12,7 @@ class TestMessageAddEvent < MiniTest::Unit::TestCase
|
|
12
12
|
|
13
13
|
def test_encode
|
14
14
|
buffer = StringIO.new
|
15
|
-
@message.
|
15
|
+
@message.table_name = "users"
|
16
16
|
@message.event = SkyDB::Event.new(
|
17
17
|
object_id: 12,
|
18
18
|
timestamp:DateTime.parse('2010-01-02T10:30:20Z'),
|
@@ -27,14 +27,14 @@ class TestMessageAddProperty < MiniTest::Unit::TestCase
|
|
27
27
|
|
28
28
|
def test_encode_object_property
|
29
29
|
buffer = StringIO.new
|
30
|
-
@message.property = SkyDB::Property.new(
|
30
|
+
@message.property = SkyDB::Property.new(:type => :object, :data_type => 'Int', :name => 'foo')
|
31
31
|
@message.encode(buffer)
|
32
32
|
assert_bytes "\x93\x01\xacadd_property\xa0\x84\xa2id\x00\xa4type\x01\xa8dataType\xa3Int\xa4name\xa3foo", buffer
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_encode_action_property
|
36
36
|
buffer = StringIO.new
|
37
|
-
@message.property = SkyDB::Property.new(
|
37
|
+
@message.property = SkyDB::Property.new(:type => :action, :data_type => 'Boolean', :name => 'foo')
|
38
38
|
@message.encode(buffer)
|
39
39
|
assert_bytes "\x93\x01\xacadd_property\xa0\x84\xa2id\x00\xa4type\x02\xa8dataType\xa7Boolean\xa4name\xa3foo", buffer
|
40
40
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class TestMessageCreateTable < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@message = SkyDB::Message::CreateTable.new()
|
7
|
+
end
|
8
|
+
|
9
|
+
######################################
|
10
|
+
# Action
|
11
|
+
######################################
|
12
|
+
|
13
|
+
def test_table
|
14
|
+
@message.table = SkyDB::Table.new('foo')
|
15
|
+
refute_nil @message.table
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_invalid_table
|
19
|
+
@message.table = "foo"
|
20
|
+
assert_nil @message.table
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
######################################
|
25
|
+
# Encoding
|
26
|
+
######################################
|
27
|
+
|
28
|
+
def test_encode
|
29
|
+
buffer = StringIO.new
|
30
|
+
@message.table = SkyDB::Table.new("foo", :tablet_count => 8)
|
31
|
+
@message.encode(buffer)
|
32
|
+
assert_bytes "\x93\x01\xaccreate_table\xa0\x82\xa4name\xa3foo\xactablet_count\x08", buffer
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class TestMessageDeleteTable < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@message = SkyDB::Message::DeleteTable.new()
|
7
|
+
end
|
8
|
+
|
9
|
+
######################################
|
10
|
+
# Action
|
11
|
+
######################################
|
12
|
+
|
13
|
+
def test_table
|
14
|
+
@message.table = SkyDB::Table.new('foo')
|
15
|
+
refute_nil @message.table
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_invalid_table
|
19
|
+
@message.table = "foo"
|
20
|
+
assert_nil @message.table
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
######################################
|
25
|
+
# Encoding
|
26
|
+
######################################
|
27
|
+
|
28
|
+
def test_encode
|
29
|
+
buffer = StringIO.new
|
30
|
+
@message.table = SkyDB::Table.new("foo")
|
31
|
+
@message.encode(buffer)
|
32
|
+
assert_bytes "\x93\x01\xacdelete_table\xa0\x81\xa4name\xa3foo", buffer
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class TestMessageGetTable < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@message = SkyDB::Message::GetTable.new()
|
7
|
+
end
|
8
|
+
|
9
|
+
######################################
|
10
|
+
# Encoding
|
11
|
+
######################################
|
12
|
+
|
13
|
+
def test_encode
|
14
|
+
buffer = StringIO.new
|
15
|
+
@message.name = "foo"
|
16
|
+
@message.encode(buffer)
|
17
|
+
assert_bytes "\x93\x01\xa9get_table\xa0\x81\xa4name\xa3foo", buffer
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class TestMessageLookup < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@message = SkyDB::Message::Lookup.new()
|
7
|
+
end
|
8
|
+
|
9
|
+
######################################
|
10
|
+
# Encoding
|
11
|
+
######################################
|
12
|
+
|
13
|
+
def test_encode
|
14
|
+
buffer = StringIO.new
|
15
|
+
@message.actions = [
|
16
|
+
SkyDB::Action.new(:name => 'foo'),
|
17
|
+
SkyDB::Action.new(:name => 'bar'),
|
18
|
+
]
|
19
|
+
@message.properties = [
|
20
|
+
SkyDB::Property.new(:name => 'xxx'),
|
21
|
+
SkyDB::Property.new(:name => 'yyy'),
|
22
|
+
SkyDB::Property.new(:name => 'zzz'),
|
23
|
+
]
|
24
|
+
@message.encode(buffer)
|
25
|
+
assert_bytes "\x93\x01\xa6lookup\xa0\x82\xabactionNames\x92\xa3foo\xa3bar\xadpropertyNames\x93\xa3xxx\xa3yyy\xa3zzz", buffer
|
26
|
+
end
|
27
|
+
end
|
data/test/message_test.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestQueryAfter < MiniTest::Unit::TestCase
|
4
|
+
##############################################################################
|
5
|
+
#
|
6
|
+
# Setup / Teardown
|
7
|
+
#
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@after = SkyDB::Query::After.new()
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
##############################################################################
|
16
|
+
#
|
17
|
+
# Tests
|
18
|
+
#
|
19
|
+
##############################################################################
|
20
|
+
|
21
|
+
######################################
|
22
|
+
# Validation
|
23
|
+
######################################
|
24
|
+
|
25
|
+
def test_validate_action
|
26
|
+
e = assert_raises(SkyDB::Query::ValidationError) do
|
27
|
+
SkyDB::Query::After.new(:function_name => "foo").validate!
|
28
|
+
end
|
29
|
+
assert_match /^Action with non-zero identifier required/, e.message
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_validate_function_name
|
33
|
+
e = assert_raises(SkyDB::Query::ValidationError) do
|
34
|
+
SkyDB::Query::After.new(:action => 10).validate!
|
35
|
+
end
|
36
|
+
assert_match /^Invalid function name ''/, e.message
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
######################################
|
41
|
+
# Code Generation
|
42
|
+
######################################
|
43
|
+
|
44
|
+
def test_codegen
|
45
|
+
@after = SkyDB::Query::After.new(:action => 10, :function_name => "foo")
|
46
|
+
expected =
|
47
|
+
<<-BLOCK.unindent
|
48
|
+
function foo(cursor, data)
|
49
|
+
repeat
|
50
|
+
if cursor.event.action_id == 10 then
|
51
|
+
cursor:next()
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
until not cursor:next()
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
BLOCK
|
58
|
+
assert_equal expected, @after.codegen()
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_codegen_enter
|
62
|
+
@after = SkyDB::Query::After.new(:action => :enter, :function_name => "foo")
|
63
|
+
expected =
|
64
|
+
<<-BLOCK.unindent
|
65
|
+
function foo(cursor, data)
|
66
|
+
return (cursor.session_event_index == 0)
|
67
|
+
end
|
68
|
+
BLOCK
|
69
|
+
assert_equal expected, @after.codegen()
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,273 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestQuerySelection < MiniTest::Unit::TestCase
|
4
|
+
##############################################################################
|
5
|
+
#
|
6
|
+
# Setup / Teardown
|
7
|
+
#
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@selection = SkyDB::Query::Selection.new()
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
##############################################################################
|
16
|
+
#
|
17
|
+
# Tests
|
18
|
+
#
|
19
|
+
##############################################################################
|
20
|
+
|
21
|
+
######################################
|
22
|
+
# Field parsing
|
23
|
+
######################################
|
24
|
+
|
25
|
+
def test_parse_single_field
|
26
|
+
fields = SkyDB::Query::Selection.parse_fields("foo")
|
27
|
+
assert_equal 1, fields.length
|
28
|
+
assert_equal "foo", fields[0].expression
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_parse_multiple_fields
|
32
|
+
fields = SkyDB::Query::Selection.parse_fields(" foo , bar, baz_12 ")
|
33
|
+
assert_equal 3, fields.length
|
34
|
+
assert_equal "foo", fields[0].expression
|
35
|
+
assert_equal "bar", fields[1].expression
|
36
|
+
assert_equal "baz_12", fields[2].expression
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_parse_aliased_fields
|
40
|
+
fields = SkyDB::Query::Selection.parse_fields("foo bar, baz bat")
|
41
|
+
assert_equal 2, fields.length
|
42
|
+
assert_equal "foo", fields[0].expression
|
43
|
+
assert_equal "bar", fields[0].alias_name
|
44
|
+
assert_equal "baz", fields[1].expression
|
45
|
+
assert_equal "bat", fields[1].alias_name
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_parse_aggregated_fields
|
49
|
+
fields = SkyDB::Query::Selection.parse_fields("sum(foo), MIN(bar)")
|
50
|
+
assert_equal 2, fields.length
|
51
|
+
assert_equal "foo", fields[0].expression
|
52
|
+
assert_equal :sum, fields[0].aggregation_type
|
53
|
+
assert_equal "bar", fields[1].expression
|
54
|
+
assert_equal :min, fields[1].aggregation_type
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_parse_aliased_aggregated_fields
|
58
|
+
fields = SkyDB::Query::Selection.parse_fields("sum(foo) baz, MIN(bar) bat")
|
59
|
+
assert_equal 2, fields.length
|
60
|
+
assert_equal "foo", fields[0].expression
|
61
|
+
assert_equal "baz", fields[0].alias_name
|
62
|
+
assert_equal :sum, fields[0].aggregation_type
|
63
|
+
assert_equal "bar", fields[1].expression
|
64
|
+
assert_equal "bat", fields[1].alias_name
|
65
|
+
assert_equal :min, fields[1].aggregation_type
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
######################################
|
70
|
+
# Group parsing
|
71
|
+
######################################
|
72
|
+
|
73
|
+
def test_parse_single_group
|
74
|
+
groups = SkyDB::Query::Selection.parse_groups("foo")
|
75
|
+
assert_equal 1, groups.length
|
76
|
+
assert_equal "foo", groups[0].expression
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_parse_multiple_groups
|
80
|
+
groups = SkyDB::Query::Selection.parse_groups("foo, bar")
|
81
|
+
assert_equal 2, groups.length
|
82
|
+
assert_equal "foo", groups[0].expression
|
83
|
+
assert_equal "bar", groups[1].expression
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
######################################
|
89
|
+
# Aggregation Generation
|
90
|
+
######################################
|
91
|
+
|
92
|
+
def test_simple_codegen
|
93
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("foo, bar my_alias")
|
94
|
+
expected =
|
95
|
+
<<-BLOCK.unindent
|
96
|
+
function select(cursor, data)
|
97
|
+
target = data
|
98
|
+
target.foo = cursor.event.foo()
|
99
|
+
target.my_alias = cursor.event.bar()
|
100
|
+
end
|
101
|
+
BLOCK
|
102
|
+
assert_equal expected, @selection.codegen_select()
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_count_codegen
|
106
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("count() bar")
|
107
|
+
expected =
|
108
|
+
<<-BLOCK.unindent
|
109
|
+
function select(cursor, data)
|
110
|
+
target = data
|
111
|
+
target.bar = (target.bar or 0) + 1
|
112
|
+
end
|
113
|
+
BLOCK
|
114
|
+
assert_equal expected, @selection.codegen_select()
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_sum_codegen
|
118
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("SUM(foo) bar")
|
119
|
+
expected =
|
120
|
+
<<-BLOCK.unindent
|
121
|
+
function select(cursor, data)
|
122
|
+
target = data
|
123
|
+
target.bar = (target.bar or 0) + cursor.event.foo()
|
124
|
+
end
|
125
|
+
BLOCK
|
126
|
+
assert_equal expected, @selection.codegen_select()
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_min_codegen
|
130
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("min(foo) bar")
|
131
|
+
expected =
|
132
|
+
<<-BLOCK.unindent
|
133
|
+
function select(cursor, data)
|
134
|
+
target = data
|
135
|
+
if(target.bar == nil or target.bar > cursor.event.foo()) then
|
136
|
+
target.bar = cursor.event.foo()
|
137
|
+
end
|
138
|
+
end
|
139
|
+
BLOCK
|
140
|
+
assert_equal expected, @selection.codegen_select()
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_max_codegen
|
144
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("min(foo) bar")
|
145
|
+
expected =
|
146
|
+
<<-BLOCK.unindent
|
147
|
+
function select(cursor, data)
|
148
|
+
target = data
|
149
|
+
if(target.bar == nil or target.bar > cursor.event.foo()) then
|
150
|
+
target.bar = cursor.event.foo()
|
151
|
+
end
|
152
|
+
end
|
153
|
+
BLOCK
|
154
|
+
assert_equal expected, @selection.codegen_select()
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_grouped_codegen
|
158
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("foo, bar my_alias")
|
159
|
+
@selection.groups = SkyDB::Query::Selection.parse_groups("baz")
|
160
|
+
expected =
|
161
|
+
<<-BLOCK.unindent
|
162
|
+
function select(cursor, data)
|
163
|
+
target = data
|
164
|
+
|
165
|
+
group_value = cursor.event.baz()
|
166
|
+
if target[group_value] == nil then
|
167
|
+
target[group_value] = {}
|
168
|
+
end
|
169
|
+
target = target[group_value]
|
170
|
+
|
171
|
+
target.foo = cursor.event.foo()
|
172
|
+
target.my_alias = cursor.event.bar()
|
173
|
+
end
|
174
|
+
BLOCK
|
175
|
+
assert_equal expected, @selection.codegen_select()
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_multiple_group_codegen
|
179
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("foo, bar my_alias")
|
180
|
+
@selection.groups = SkyDB::Query::Selection.parse_groups("aaa, bbb, ccc")
|
181
|
+
expected =
|
182
|
+
<<-BLOCK.unindent
|
183
|
+
function select(cursor, data)
|
184
|
+
target = data
|
185
|
+
|
186
|
+
group_value = cursor.event.aaa()
|
187
|
+
if target[group_value] == nil then
|
188
|
+
target[group_value] = {}
|
189
|
+
end
|
190
|
+
target = target[group_value]
|
191
|
+
|
192
|
+
group_value = cursor.event.bbb()
|
193
|
+
if target[group_value] == nil then
|
194
|
+
target[group_value] = {}
|
195
|
+
end
|
196
|
+
target = target[group_value]
|
197
|
+
|
198
|
+
group_value = cursor.event.ccc()
|
199
|
+
if target[group_value] == nil then
|
200
|
+
target[group_value] = {}
|
201
|
+
end
|
202
|
+
target = target[group_value]
|
203
|
+
|
204
|
+
target.foo = cursor.event.foo()
|
205
|
+
target.my_alias = cursor.event.bar()
|
206
|
+
end
|
207
|
+
BLOCK
|
208
|
+
assert_equal expected, @selection.codegen_select()
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
######################################
|
213
|
+
# Merge Codegen
|
214
|
+
######################################
|
215
|
+
|
216
|
+
def test_simple_merge_codegen
|
217
|
+
@selection.fields = SkyDB::Query::Selection.parse_fields("foo, sum(bar) my_alias, count(), min(x), max(y)")
|
218
|
+
expected =
|
219
|
+
<<-BLOCK.unindent
|
220
|
+
function merge(results, data)
|
221
|
+
a = results
|
222
|
+
b = data
|
223
|
+
a.foo = b.foo
|
224
|
+
a.my_alias = (a.my_alias or 0) + (b.my_alias or 0)
|
225
|
+
a.count = (a.count or 0) + (b.count or 0)
|
226
|
+
if(a.x == nil or a.x > b.x) then
|
227
|
+
a.x = b.x
|
228
|
+
end
|
229
|
+
if(a.y == nil or a.y < b.y) then
|
230
|
+
a.y = b.y
|
231
|
+
end
|
232
|
+
end
|
233
|
+
BLOCK
|
234
|
+
assert_equal expected, @selection.codegen_merge()
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_grouped_merge_codegen
|
238
|
+
@selection = SkyDB::Query::Selection.new.select("sum(foo), count()").group_by(:bar)
|
239
|
+
expected =
|
240
|
+
<<-BLOCK.unindent
|
241
|
+
function merge(results, data)
|
242
|
+
for k0,v0 in pairs(data) do
|
243
|
+
if results[k0] == nil then results[k0] = {} end
|
244
|
+
a = results[k0]
|
245
|
+
b = data[k0]
|
246
|
+
a.foo = (a.foo or 0) + (b.foo or 0)
|
247
|
+
a.count = (a.count or 0) + (b.count or 0)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
BLOCK
|
251
|
+
assert_equal expected, @selection.codegen_merge()
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_multigroup_merge_codegen
|
255
|
+
@selection = SkyDB::Query::Selection.new.select("sum(foo), count()").group_by(:bar, :baz)
|
256
|
+
expected =
|
257
|
+
<<-BLOCK.unindent
|
258
|
+
function merge(results, data)
|
259
|
+
for k0,v0 in pairs(data) do
|
260
|
+
if results[k0] == nil then results[k0] = {} end
|
261
|
+
for k1,v1 in pairs(data[k0]) do
|
262
|
+
if results[k0][k1] == nil then results[k0][k1] = {} end
|
263
|
+
a = results[k0][k1]
|
264
|
+
b = data[k0][k1]
|
265
|
+
a.foo = (a.foo or 0) + (b.foo or 0)
|
266
|
+
a.count = (a.count or 0) + (b.count or 0)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
BLOCK
|
271
|
+
assert_equal expected, @selection.codegen_merge()
|
272
|
+
end
|
273
|
+
end
|