zillabyte 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTIzYmY3MjJhM2U0M2I2OGU4ZGE3ZDk2YmI4NjhkYzM1MTY0ZjY1ZA==
4
+ YWU1ZGQ4YmZiNjUxNDdhZjExYWU5Y2IyMWJlNWE4MmU1MTM3YTYwNg==
5
5
  data.tar.gz: !binary |-
6
- OTkyMzYzODhjZmNmNjZiYzc2ZGI3NTVjNDFlNDljMzBjNTJhOTRiOQ==
7
- !binary "U0hBNTEy":
6
+ NmVlNjAzNTIwMjRiODFjZmNmZTQzYzc0YTM0NWE4ZjFiN2QzOGUxZg==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- OTJiZjQwMGRiYjEzMTM4YTZlODZhZTA2N2Y1YjNiMDQ4MTY3NWNkZjNkYzM0
10
- NzRkNmVkN2M3OTFmNjc1Yzc2ZDU5YTA5ZjNlODU3YjIwNzVlNTE1NGM5OTk5
11
- YjQxOThlNWNmY2E0YWUwM2YzZjM4Y2JhMzY3Y2IyM2VkMjM0ZTQ=
9
+ NTNiMmYzMDBlNjJjMGVmYTQ3YjdkMTVjMmVmNDgyZTE1YmJiMTRhYmNmZjY3
10
+ YTUzODQwZDZlZWViZGQ1NTkxNmE1NjAyNmQ4Nzg4YjljZjMzZjJmODY0MDJi
11
+ OTdlYWYwOWRhOWRkZmU5OTY3ZmZjMTg3ZDZmMjEwZjMxMjAwNGY=
12
12
  data.tar.gz: !binary |-
13
- N2IyMjlhMWVkZTdmODA4MmZhOWY4YTU0NTg3NDMwZTlhY2ZmOTMzZjAyNzU1
14
- Y2E0ZTcxYzYyNmVjM2Q0ZDM5YjEyMmQ1Y2ZlOGJmY2NmZjk2MDRiMzQ1ODIx
15
- OGUyOWY4MmRmODc4M2VkMTJiOWI5ZTY0MTVjYTZiYWM4MjE5MjQ=
13
+ OTRkMzYxYmM2YTY1MWYyNTllMTg5YjI1M2NhN2U5ZjBjMGE4MTM3MDExODdk
14
+ ODQzMDc4MDkwY2NlZWE0Mzk1NDVjYjAxYzMyMGZiMDc0ZDVjYjI5NDE4ZDI5
15
+ M2ExOWJjMWFkZTdkMmI2N2I4MWE4N2M5ZDM5ZTI2NzA3Nzc1NTk=
@@ -3,21 +3,9 @@ require "zillabyte/common/progress"
3
3
 
4
4
  module Zillabyte
5
5
 
6
- def self.new(name=nil)
7
- @topology = Zillabyte::Harness::Topology.build(name)
8
- @topology
9
- end
10
-
11
- def self.simple_function(*args, &block)
12
- Zillabyte::Harness::SimpleFunction.build(*args, &block)
13
- end
14
-
15
- def self.simple_source(*args, &block)
16
- Zillabyte::Harness::SimpleSource.build(*args, &block)
17
- end
18
-
19
- def self.simple_aggregate(*args, &block)
20
- Zillabyte::Harness::SimpleAggregate.build(*args, &block)
6
+ def self.app(name=nil)
7
+ @app = Zillabyte::Harness::App.build(name)
8
+ @app
21
9
  end
22
10
 
23
11
  end
@@ -0,0 +1,59 @@
1
+ require "json"
2
+
3
+ class Zillabyte::Harness::App
4
+ attr_accessor :_name, :_options, :_nodes, :_streams, :_info_file
5
+
6
+ def self.build(name)
7
+ h = Zillabyte::Harness::App.new()
8
+ h._nodes = []
9
+ h._streams = {}
10
+ h._name = name
11
+ Zillabyte::Harness::Helper.check_name("new", h._name, {})
12
+ h._options = Zillabyte::Harness::Helper.opt_parser()
13
+ if(h._options[:command] == :info)
14
+ h._info_file = File.open(h._options[:file],"w+")
15
+ info_hash = {"language" => "ruby", "name" => h._name}
16
+ Zillabyte::Harness::Helper.write_hash_to_file(info_hash, h._info_file)
17
+ end
18
+ h
19
+ end
20
+
21
+ def source(*args, &block)
22
+ h = Zillabyte::Harness::Source.new()
23
+ # Are we given a block?
24
+ if block_given?
25
+ h.instance_eval(&block)
26
+ Zillabyte::Harness::Helper.check_name("source", h._name, {})
27
+ Zillabyte::Harness::Helper.check_source("source", h)
28
+ if(!h._emits)
29
+ h._emits = ["stream_"+Zillabyte::Harness::Counter.get()]
30
+ end
31
+ # No block? Then we assume we're given sql or sxp and parse it using h.matches. Also give it a generated stream name.
32
+ else
33
+ h._emits = ["stream_"+Zillabyte::Harness::Counter.get()]
34
+ h.matches(args[0])
35
+ end
36
+ @_nodes << h
37
+ if(@_options[:command] == :info)
38
+ info_hash = {"name" => h._name, "type" => h._type, "emits" => h._emits, "end_cycle_policy" => h._end_cycle_policy}
39
+ if(h._relation)
40
+ info_hash["relation"] = h._relation
41
+ elsif(h._matches)
42
+ info_hash["matches"] = h._matches
43
+ end
44
+ Zillabyte::Harness::Helper.write_hash_to_file(info_hash, @_info_file)
45
+ elsif(@_options[:command] == :execute and @_options[:name] == h._name)
46
+ pipe_name = @_options[:pipe]
47
+ c = Zillabyte::Harness::SourceController.new(h, progress = Zillabyte::Common::Progress.new)
48
+ c.run(pipe_name)
49
+ end
50
+
51
+ output_streams = []
52
+ h._emits.each do |stream|
53
+ output_streams << Zillabyte::Harness::Stream.new(stream, self, nil)
54
+ end
55
+ output_streams = output_streams[0] if output_streams.size == 1
56
+ output_streams
57
+ end
58
+
59
+ end
@@ -1,5 +1,5 @@
1
1
  class Zillabyte::Harness::Each
2
- attr_accessor :_name, :_type, :_emits, :_consumes, :_prepare, :_execute
2
+ attr_accessor :_has_emit, :_name, :_type, :_emits, :_consumes, :_prepare, :_execute
3
3
 
4
4
  def initialize()
5
5
  @_name = "each_"+Zillabyte::Harness::Counter.get()
@@ -10,12 +10,12 @@ class Zillabyte::Harness::Each
10
10
  @_name = v
11
11
  end
12
12
 
13
- def emits(v)
14
- @_emits = v
13
+ def emits(*v)
14
+ @_emits = *v
15
15
  end
16
16
 
17
- def consumes(v)
18
- @_consumes = v
17
+ def emit(*v)
18
+ @_has_emit = true
19
19
  end
20
20
 
21
21
  def prepare(&block)
@@ -1,3 +1,5 @@
1
+ require 'optparse'
2
+
1
3
  class Zillabyte::Harness::Helper
2
4
 
3
5
  def self.opt_parser()
@@ -38,7 +40,7 @@ class Zillabyte::Harness::Helper
38
40
 
39
41
  # \w matchs [a-zA-Z0-9_]
40
42
  if(!name.instance_of?(String) or (name =~ /^\w+$/).nil?)
41
- msg = "#{ee}\"Name\" must be a non-empty STRING with only alphanumeric and underscore characters at \"#{name}\". Flows and simple_functions must have names!"
43
+ msg = "#{ee}\"Name\" must be a non-empty STRING with only alphanumeric and underscore characters at \"#{name}\". Apps and simple_apps must have names!"
42
44
  Zillabyte::Harness::Helper.print_error(msg)
43
45
  end
44
46
  if(names[name] and names[name] != "new" and names[name] != "sink" and operation != "new" and operation != "sink")
@@ -51,22 +53,18 @@ class Zillabyte::Harness::Helper
51
53
 
52
54
  def self.check_source(operation, source)
53
55
  ee = "Error in \"#{operation}\": \n\t "
54
- if(["simple_function", "simple_aggregate"].member?(operation))
55
- pp = "\"#{operation}\" may only contain a single \"matches\" clause."
56
- else
57
- pp = "A \"#{operation}\" may only contain a single \"emits\" OR \"matches\" clause."
58
- end
59
-
60
- em = !source._emits.nil?
56
+ pp = @@_print_check_source
57
+
61
58
  rm = !source._relation.nil?
62
59
  mm = !source._matches.nil?
63
- if( (em and rm) or (rm and mm) or (mm and em) )
64
- msg = "#{ee}#{pp}"
60
+ if( rm and mm )
61
+ msg = "#{ee}"
62
+ msg += "A \"#{operation}\" may contain either a \"matches\" clause or a \"relation\" clause, not both. #{pp}"
65
63
  Zillabyte::Harness::Helper.print_error(msg)
66
64
  end
67
65
  if(rm or mm)
68
66
  if source._prepare or source._next_batch
69
- msg = "#{ee}If \"#{operation}\" has a \"matches\" clause, it may not have a \"prepare\" or \"next_batch\" block."
67
+ msg = "#{ee}If \"#{operation}\" has a \"matches\\relation\" clause, it may not have a \"prepare\" or \"next_batch\" block. #{pp}"
70
68
  Zillabyte::Harness::Helper.print_error(msg)
71
69
  end
72
70
  end
@@ -74,16 +72,11 @@ class Zillabyte::Harness::Helper
74
72
 
75
73
  def self.check_emits(operation, emits, streams)
76
74
  ee = "Error in \"#{operation}\" at \"emits\": \n\t "
77
- if(operation.include?("simple"))
78
- pp = @@_print_check_simple_function_emits
79
- nn = "relation"
80
- else
81
- pp = @@_print_check_emits
82
- nn = "stream"
83
- end
84
-
75
+ pp = @@_print_check_emits
76
+ nn = "stream"
77
+
85
78
  if(!emits.instance_of?(Array))
86
- msg = "#{ee}\"Emits\" must be an ARRAY at #{emits}. #{pp}"
79
+ msg = "#{ee}\"Emits\" must be a sequence of strings at #{emits}. #{pp}"
87
80
  Zillabyte::Harness::Helper.print_error(msg)
88
81
  end
89
82
  n_emits = emits.length
@@ -94,47 +87,15 @@ class Zillabyte::Harness::Helper
94
87
 
95
88
  current_op_streams = {}
96
89
  emits.each do |e|
97
- if(!e.instance_of?(Array) or e.length != 2)
98
- msg = "#{ee}Invalid format for \"emits\" in #{e}. #{pp}"
99
- Zillabyte::Harness::Helper.print_error(msg)
100
- end
101
- if(!e[0].instance_of?(String) or (e[0] =~ /^\w+$/).nil?)
90
+ if(!e.instance_of?(String) or (e =~ /^\w+$/).nil?)
102
91
  msg = "#{ee}\"Emits\" #{nn} name must be a non-empty STRING with only alphanumeric and underscore characters in \"#{e}\". #{pp}"
103
92
  Zillabyte::Harness::Helper.print_error(msg)
104
93
  end
105
- if(current_op_streams[e[0]])
94
+ if(current_op_streams[e])
106
95
  msg = "#{ee}The #{nn} \"#{e[0]}\" is listed multiple times in the same \"emits\". #{pp}"
107
96
  Zillabyte::Harness::Helper.print_error(msg)
108
97
  end
109
- current_op_streams[e[0]] = 1
110
- if(streams[e[0]] and streams[e[0]] != e[1])
111
- msg = "#{ee}The #{nn} name \"#{e[0]}\" was previously defined with a different set of fields! #{pp}"
112
- Zillabyte::Harness::Helper.print_error(msg)
113
- end
114
- streams[e[0]] = e[1]
115
- if(e[1].length == 0)
116
- msg = "#{ee}Must be at least one output field to #{nn} \"#{e[0]}\". #{pp}"
117
- Zillabyte::Harness::Helper.print_error(msg)
118
- end
119
-
120
- if(operation.include?("simple"))
121
- Zillabyte::Harness::Helper.check_simple_function_emits(operation, e)
122
- else
123
- if(!e[1].instance_of?(Array))
124
- msg = "#{ee}Field names must be an ARRAY of STRINGS in stream \"#{e[0]}\". #{pp}"
125
- Zillabyte::Harness::Helper.print_error(msg)
126
- end
127
- e[1].each do |f|
128
- if(!f.instance_of?(String) or (f =~ /^\w+$/).nil?)
129
- msg = "#{ee}Field names must be non-empty STRINGS with only alphanumeric and underscore characters in stream \"#{e[0]}\". #{pp}"
130
- Zillabyte::Harness::Helper.print_error(msg)
131
- end
132
- if(f =~ /^v[0-9]+$/i or @@meta_names.member?(f.downcase))
133
- msg = "#{ee}\"v[number]\", \"id\", \"confidence\", \"since\" and \"source\" are special names in Zillabyte. Please name your field something else. #{pp}"
134
- Zillabyte::Harness::Helper.print_error(msg)
135
- end
136
- end
137
- end
98
+ current_op_streams[e] = 1
138
99
  end
139
100
  if(n_emits > 1)
140
101
  return true
@@ -144,31 +105,6 @@ class Zillabyte::Harness::Helper
144
105
 
145
106
  end
146
107
 
147
- def self.check_consumes(h, streams)
148
- ee = "Error in \"#{h._type}\" at \"consumes\": \n\t "
149
- if(h._type == "each")
150
- pp = @@_print_check_each_consumes
151
- elsif(h._type == "aggregate")
152
- pp = @@_print_check_aggregate_consumes
153
- elsif(h._type == "sink")
154
- pp = @@_print_check_sink
155
- end
156
-
157
- consumes = h._consumes
158
- if(!consumes)
159
- msg = "#{ee}\"Consumes\" must be specified since a preceding \"each\", \"source\" or \"aggregate\" emitted multiple streams. #{pp}"
160
- Zillabyte::Harness::Helper.print_error(msg)
161
- end
162
- if(!streams[consumes])
163
- msg = "#{ee}The stream \"#{consumes}\" specified in \"consumes\" does not exist! #{pp}"
164
- Zillabyte::Harness::Helper.print_error(msg)
165
- end
166
-
167
- if(h._type == "sink")
168
- Zillabyte::Harness::Helper.check_sink_consumes(h, streams)
169
- end
170
- end
171
-
172
108
  def self.check_group_by(operation, h, nodes, streams)
173
109
  ee = "Error in \"#{operation}\" at \"group_by\": \n\t "
174
110
  pp = ""
@@ -248,14 +184,14 @@ class Zillabyte::Harness::Helper
248
184
  pp = @@_print_check_sink
249
185
  elsif(operation.include?("simple"))
250
186
  ee = "Error in \"#{operation}\" at \"emits\": \n\t "
251
- pp = @@_print_check_simple_function_emits
187
+ pp = @@_print_check_simple_app_emits
252
188
  end
253
189
 
254
190
  if(!cname.instance_of?(String) or (cname =~ /^\w+$/).nil?)
255
191
  msg = "#{ee}Field names must be non-empty STRINGS with only alphanumeric and underscore characters in relation \"#{relation_name}\". #{pp}"
256
192
  Zillabyte::Harness::Helper.print_error(msg)
257
193
  end
258
- if(cname =~ /^v[0-9]+$/i or @@meta_names.member?(cname.downcase))
194
+ if(cname =~ /^v[0-9]+$/i or @@_meta_names.member?(cname.downcase))
259
195
  msg = "#{ee}\"v[number]\", \"id\", \"confidence\", \"since\" and \"source\" are special names in Zillabyte. Please name your field something else. #{pp}"
260
196
  Zillabyte::Harness::Helper.print_error(msg)
261
197
  end
@@ -291,9 +227,9 @@ class Zillabyte::Harness::Helper
291
227
  end
292
228
  end
293
229
 
294
- def self.check_simple_function_emits(operation, emits)
230
+ def self.check_simple_app_emits(operation, emits)
295
231
  ee = "Error in \"#{operation}\" at \"emits\": \n\t "
296
- pp = @@_print_check_simple_function_emits
232
+ pp = @@_print_check_simple_app_emits
297
233
 
298
234
  name = emits[0]
299
235
  columns = emits[1]
@@ -317,7 +253,11 @@ class Zillabyte::Harness::Helper
317
253
  end
318
254
  end
319
255
 
320
-
256
+ def self.print_simple_app_usage(msg)
257
+ ee = "Error in \"simple_app\": \n\t "
258
+ msg = "#{ee}#{msg} #{@@_print_check_simple_app} #{@@_print_check_simple_app_emits}"
259
+ Zillabyte::Harness::Helper.print_error(msg)
260
+ end
321
261
 
322
262
  # Test helper...
323
263
  def self.argv()
@@ -329,85 +269,131 @@ class Zillabyte::Harness::Helper
329
269
  @_argv = v
330
270
  end
331
271
 
332
- @@_print_check_emits = "\n
333
- \"Emits\" Syntax:
334
- - \"Emits\" must be a non-empty ARRAY.
335
- - Each element of \"emits\" must be an ARRAY of length = 2.
272
+ @@_print_check_emits = <<-OUTPUT
273
+ "Emits" Syntax:
274
+ - "Emits" must be a non-empty ARRAY.
275
+ - Each element of "emits" must be an ARRAY of length = 2.
336
276
  * The first element should be the unique stream name defined as a non-empty STRING with only alphanumeric and underscore characters.
337
277
  * The second element should be an ARRAY of field names for that stream.
338
278
  e.g.
339
- \t emits = [ [ \"stream_1\", [ \"field_11\", \"field_12\", ... ] ],
340
- \t [ \"stream_2\", [ \"field_21\", \"field_22\", ... ] ] ] .
279
+ emits = [ [ "stream_1", [ "field_11", "field_12", ... ] ],
280
+ [ "stream_2", [ "field_21", "field_22", ... ] ] ] .
341
281
  - Stream and field names must all be non-empty STRINGS with only alphanumeric and underscore characters.
342
- - Field names cannot be \"v[number]\", \"id\", \"confidence\", \"since\" or \"source\" which are reserved Zillabyte names."
343
-
344
- @@_print_check_group_by = "\n
345
- \"Group_by\" Syntax:
346
- - \"Group_by\" must be a non-empty ARRAY.
347
- - Each element of \"group_by\" must be a STRING corresponding to a field emitted by the previous operation or the stream
348
- consumed by the aggregation function."
349
-
350
- @@_print_check_simple_function_emits = "\n
351
- \"Emits\" Syntax:
352
- - \"Emits\" must be a non-empty ARRAY.
353
- - Each element of \"emits\" must be an ARRAY of length = 2.
282
+ - Field names cannot be "v[number]", "id", "confidence", "since" or "source" which are reserved Zillabyte names.
283
+ OUTPUT
284
+
285
+
286
+ @@_print_check_group_by =<<-OUTPUT
287
+ "Group_by" Syntax:
288
+ - "Group_by" must be a non-empty ARRAY.
289
+ - Each element of "group_by" must be a STRING corresponding to a field emitted by the previous operation or the stream
290
+ consumed by the aggregation operation.
291
+ OUTPUT
292
+
293
+ @@_print_check_simple_app_emits = <<-OUTPUT
294
+ "Emits" Syntax:
295
+ - "Emits" must be a non-empty ARRAY.
296
+ - Each element of "emits" must be an ARRAY of length = 2.
354
297
  * The first element should be the unique relation name defined as a non-empty STRING with only alphanumeric and underscore characters.
355
298
  * The second element should be an ARRAY of HASHES with field names and data types for that relation. e.g.
356
- \t emits = [ [ \"relation_1\", [ {\"field_11\" => \"type_11\"}, {\"field_12\" => \"type_12\"}, ... ] ],
357
- \t [ \"relation_2\", [ {\"field_21\" => \"type_21\"}, {\"field_22\" => \"type_22\"}, ... ] ] ] .
299
+ emits = [ [ "relation_1", [ {"field_11" => "type_11"}, {"field_12" => "type_12"}, ... ] ],
300
+ [ "relation_2", [ {"field_21" => "type_21"}, {"field_22" => "type_22"}, ... ] ] ] .
358
301
  - Relation and field names must all be non-empty STRINGS with only alphanumeric and underscore characters.
359
- - Field names cannot be \"v[number]\", \"id\", \"confidence\", \"since\" or \"source\" which are reserved Zillabyte names.
360
- - Field types must be SYMBOLS. The following types are allowed :string, :integer, :float, :double, and :boolean."
302
+ - Field names cannot be "v[number]", "id", "confidence", "since" or "source" which are reserved Zillabyte names.
303
+ - Field types must be SYMBOLS. The following types are allowed :string, :integer, :float, :double, and :boolean.
304
+ OUTPUT
361
305
 
362
- @@_print_check_sink = "\n
363
- \"Sink\" Syntax:
306
+ @@_print_check_sink = <<-OUTPUT
307
+ "Sink" Syntax:
364
308
  - Sinks must be specified using the following syntax:
365
309
  Single stream:
366
- \t flow.sink do |h|
367
- \t \t h.name \"name_of_relation\"
368
- \t \t h.column \"field_1\" :type_1
369
- \t \t h.column \"field_2\" :type_2 ...
370
- \t end
310
+ app.sink do
311
+ name "name_of_relation"
312
+ column "field_1" :type_1
313
+ column "field_2" :type_2 ...
314
+ end
371
315
  Multiple streams:
372
- \t flow.sink do |h|
373
- \t \t h.name \"relation_name\"
374
- \t \t h.consumes \"stream_consumed\"
375
- \t \t h.column \"field_1\" :type_1
376
- \t \t h.column \"field_2\" :type_2 ...
377
- \t end
378
- - \"Sink\" relation \"name\" must be specified as a non-empty STRING with only alphanumeric and underscore characters!
316
+ app.sink do
317
+ name "relation_name"
318
+ consumes "stream_consumed"
319
+ column "field_1" :type_1
320
+ column "field_2" :type_2 ...
321
+ end
322
+ - "Sink" relation "name" must be specified as a non-empty STRING with only alphanumeric and underscore characters!
379
323
  - Field names must be non-empty STRINGS with only alphanumeric or underscore characters.
380
- - Field names cannot be \"v[number]\", \"id\", \"confidence\", \"since\" or \"source\" which are reserved Zillabyte names.
324
+ - Field names cannot be "v[number]", "id", "confidence", "since" or "source" which are reserved Zillabyte names.
381
325
  - Field types must be SYMBOLS. The following types are allowed :string, :integer, :float, :double, and :boolean.
382
- - If there are multiple streams, \"consumes\" must be specified for each sink as a non-empty STRING!
383
- * \"Consumes\" is the name of a stream emitted by an \"each\" or a \"source\" which the \"sink\" should save as a table.
384
- * The columns specified in \"sink\" must match the fields emitted by the stream."
385
-
386
- @@_print_check_each_consumes = "\n
387
- \"Each\" Syntax for multiple streams:
388
- \t flow.each do |h|
389
- \t \t h.name \"name\", => optional
390
- \t \t h.emits emits,
391
- \t \t h.consumes \"consumed_stream\"
392
- \t \t h.prepare ...
393
- \t \t h.execute ...
394
- \t end
395
- - If there are multiple streams, \"consumes\" must be specified as a non-empty STRING!
396
- * \"Consumes\" is the name of a stream emitted by a preceding \"each\", \"source\" or \"aggregate\" which the current \"each\" operates on."
397
-
398
- @@_print_check_aggregate_consumes = "\n
399
- \"Aggregate\" Syntax for multiple streams:
400
- \t flow.aggregate do |h|
401
- \t \t h.name \"name\", => optional
402
- \t \t h.group_by [\"field_1\", \"field_2\", ...],
403
- \t \t h.emits emits,
404
- \t \t h.consumes \"consumed_stream\"
405
- \t \t h.begin_group ...
406
- \t \t h.aggregate ...
407
- \t \t h.end_group ...
408
- \t end
409
- - If there are multiple streams, \"consumes\" must be specified as a non-empty STRING!
410
- * \"Consumes\" is the name of a stream emitted by a preceding \"each\", \"source\" or \"aggregate\" which the current \"aggregate\" operates on."
411
-
412
- @@meta_names=["id", "confidence", "since", "source"]
326
+ - If there are multiple streams, "consumes" must be specified for each sink as a non-empty STRING!
327
+ * "Consumes" is the name of a stream emitted by an "each" or a "source" which the "sink" should save as a table.
328
+ * The columns specified in "sink" must match the fields emitted by the stream."
329
+ OUTPUT
330
+
331
+ @@_print_check_source = <<-OUTPUT
332
+ "Source" Syntax:
333
+ - Sources must be specified using the following syntax:
334
+ Sourcing from a relation:
335
+ app.source do
336
+ name "name" => optional
337
+ matches "sql_query or sxp"
338
+ end
339
+ Custom source:
340
+ app.source do
341
+ name "name" => optional
342
+ emits emits
343
+ prepare ...
344
+ next_batch ...
345
+ end
346
+ OUTPUT
347
+
348
+ @@_print_check_each = <<-OUTPUT
349
+ "Each" Syntax:
350
+ - Eaches must be specified using the following syntax:
351
+ app.each do
352
+ name "name" => optional
353
+ emits emits
354
+ consumes "consumed_stream" => optional if single stream
355
+ prepare ...
356
+ execute ...
357
+ end
358
+ - If there are multiple streams, "consumes" must be specified as a non-empty STRING!
359
+ * "Consumes" is the name of a stream emitted by a preceding "each", "source" or "aggregate" which the current "each" operates on."
360
+ OUTPUT
361
+
362
+ @@_print_check_aggregate = <<-OUTPUT
363
+ "Aggregate" Syntax:
364
+ - Aggregates must be specified using the following syntax:
365
+ app.aggregate do
366
+ name "name" => optional
367
+ group_by ["field_1", "field_2", ...]
368
+ emits emits
369
+ consumes "consumed_stream" => optional if single stream
370
+ begin_group ...
371
+ aggregate ...
372
+ end_group ...
373
+ end
374
+ - If there are multiple streams, "consumes" must be specified as a non-empty STRING!
375
+ * "Consumes" is the name of a stream emitted by a preceding "each", "source" or "aggregate" which the current "aggregate" operates on.
376
+ OUTPUT
377
+
378
+ @@_print_check_simple_app = <<-OUTPUT
379
+ "Simple_app" Syntax:
380
+ - Simple_apps must be specified using the following syntax:
381
+ Sinking directly from a custom source:
382
+ Zillabyte.simple_app do
383
+ name "name"
384
+ emits emits
385
+ prepare ...
386
+ next_batch ...
387
+ end
388
+ Processing and sinking data from a relation:
389
+ Zillabyte.simple_app do
390
+ name "name"
391
+ matches "sql_query or sxp"
392
+ emits emits
393
+ prepare ...
394
+ execute ...
395
+ end
396
+ OUTPUT
397
+
398
+ @@_meta_names = ["id", "confidence", "since", "source"]
413
399
  end