gd_bam 0.0.1

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.
@@ -0,0 +1,96 @@
1
+ require 'rgl/adjacency'
2
+ require 'rgl/dot'
3
+ require 'rgl/topsort'
4
+
5
+ require 'repository/repo'
6
+
7
+ module GoodData
8
+ module CloverGenerator
9
+ module Dependency
10
+
11
+
12
+ class Visitor
13
+
14
+ def accept(node)
15
+ puts node
16
+ if node.type == "ldm"
17
+ puts "LDM #{node.to_s}"
18
+ else
19
+ puts "doing something on #{node.to_s}"
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ class N
26
+ def initialize(x)
27
+ @x = x
28
+ end
29
+
30
+ def to_s
31
+ "#{@x[:type]}-#{@x[:name]}"
32
+ end
33
+
34
+ def type
35
+ @x[:type]
36
+ end
37
+
38
+ def provides
39
+ @x[:provides]
40
+ end
41
+
42
+ def requires
43
+ @x[:requires]
44
+ end
45
+
46
+ def package
47
+ @x[:package]
48
+ end
49
+
50
+ def visit(v)
51
+ v.accept(self)
52
+ end
53
+
54
+ end
55
+
56
+
57
+ def resolve(repo, you)
58
+ repo << you
59
+
60
+ providers = repo.reduce({}) do |memo, mod|
61
+ package = mod.package
62
+ mod.provides.each do |providee|
63
+ memo[[package, providee].join('/')] = mod
64
+ end
65
+ memo
66
+ end
67
+
68
+ vertices = repo.reduce([]) do |memo, mod|
69
+ package = mod.package
70
+ reqs = mod.requires
71
+ len = reqs.length
72
+ req_modules = reqs.map do |m|
73
+ if providers[m].nil?
74
+ fail "Dependency not met. Looking for #{m} and could not find it"
75
+ else
76
+ providers[m]
77
+ end
78
+ end
79
+ memo.concat([mod].cycle().take(len).zip(req_modules).flatten)
80
+ end
81
+
82
+ x = RGL::DirectedAdjacencyGraph[*vertices]
83
+ fail "Graph is cyclic" unless x.acyclic?
84
+ x
85
+ end
86
+
87
+ def get_dependent(graph, you)
88
+ graph.bfs_search_tree_from(you)
89
+ end
90
+
91
+ def to_dot(graph)
92
+ graph.write_to_graphic_file('jpg')
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,371 @@
1
+ module GoodData
2
+ module CloverGenerator
3
+ module Nodes
4
+
5
+ SF_CONNECTION = "SFDC"
6
+ EDGE = "EDGE"
7
+ WRITER = "DATA_WRITER"
8
+ READER = "DATA_READER"
9
+ SF_READER = "SF_READER"
10
+ REFORMAT = "REFORMAT"
11
+ PERSISTENT_LOOKUP = "persistentLookup"
12
+ GD_LOOKUP = "gdLookup"
13
+ GD_ESTORE_WRITER = "GD_ESTORE_WRITER"
14
+ GD_ESTORE_READER = "GD_ESTORE_READER"
15
+ ENABLED = "ENABLED"
16
+ DEFAULT_HEIGHT = "77"
17
+ DEFAULT_WIDTH = "128"
18
+ GD_DATASET_WRITER = "GD_DATASET_WRITER"
19
+ GD_ESTORE_TRUNCATE = "GD_ESTORE_TRUNCATE"
20
+ DATA_GENERATOR = "DATA_GENERATOR"
21
+ SIMPLE_GATHER = "SIMPLE_GATHER"
22
+ SIMPLE_COPY = "SIMPLE_COPY"
23
+ CHECK_FOREIGN_KEY = "CHECK_FOREIGN_KEY"
24
+ RUN_GRAPH = "RUN_GRAPH"
25
+ TRASH = "TRASH"
26
+ LOOKUP_TABLE_READER_WRITER = "LOOKUP_TABLE_READER_WRITER"
27
+ FILE_COPY_MOVE = "FILE_COPY_MOVE"
28
+ FILE_DELETE = "FILE_DELETE"
29
+ FILE_LIST = "FILE_LIST"
30
+ EXT_SORT = "EXT_SORT"
31
+ EXT_HASH_JOIN = "EXT_HASH_JOIN"
32
+ NORMALIZER = "NORMALIZER"
33
+
34
+
35
+ DEFAULT_NODE_PARAMS = {
36
+ :enabled => ENABLED,
37
+ :guiHeight => DEFAULT_HEIGHT,
38
+ :guiWidth => DEFAULT_WIDTH
39
+ }
40
+
41
+ def self.node(data, options={})
42
+ defaults = options[:defaults] || {}
43
+ required = options[:required] || []
44
+ allowed = options[:allowed] || []
45
+ output_data = defaults.merge(data)
46
+ required.each do |key|
47
+ unless output_data.has_key?(key)
48
+ fail "#{key} is required but not provided"
49
+ end
50
+ end
51
+ output_data
52
+ end
53
+
54
+ def self.base_node(data, options={})
55
+ defaults = DEFAULT_NODE_PARAMS.merge(options[:defaults] || {})
56
+ required = (options[:required] || []).concat([:type, :id])
57
+ allowed = options[:allowed] || []
58
+ output_data = defaults.merge(data)
59
+
60
+ node(output_data, {
61
+ :allowed => [:enabled, :guiName, :id, :type, :guiHeight, :guiWidth, :name].concat(allowed),
62
+ :required => required,
63
+ :defaults => defaults
64
+ })
65
+ end
66
+
67
+ def self.gd_loader2(data, options={})
68
+ local_defaults = {
69
+ :type => GD_DATASET_WRITER,
70
+ :projectId => "${GDC_PROJECT_ID}",
71
+ }
72
+ defaults = local_defaults.merge(options[:defaults] || {})
73
+ base_node(defaults.merge(data), {
74
+ :allowed => [:enabled, :guiName, :id, :type, :guiHeight, :guiWidth, :name, :projectId, :dataset, :datasetFieldMappings],
75
+ :defaults => defaults,
76
+ :required => []
77
+ })
78
+ end
79
+
80
+ def self.writer2(data, options={})
81
+ local_defaults = {
82
+ :type => WRITER,
83
+ :quoteCharacter => "\"",
84
+ :charset => "UTF-8",
85
+ :quotedStrings => "true",
86
+ :append => "false",
87
+ :outputFieldNames => "false"
88
+ }
89
+ defaults = local_defaults.merge(options[:defaults] || {})
90
+
91
+ base_node(defaults.merge(data), {
92
+ :allowed => [:fileURL, :quotedStrings, :quoteCharacter, :charset, :outputFieldNames, :append],
93
+ :defaults => defaults,
94
+ :required => [:fileURL]
95
+ })
96
+ end
97
+
98
+ def self.reader2(data, options={})
99
+ local_defaults = {
100
+ :type => READER,
101
+ :quoteCharacter => "\"",
102
+ :charset => "UTF-8",
103
+ :quotedStrings => "true",
104
+ :skipRows => 1
105
+ }
106
+ defaults = local_defaults.merge(options[:defaults] || {})
107
+
108
+ base_node(defaults.merge(data), {
109
+ :allowed => [:fileURL, :quotedStrings, :quoteCharacter, :charset, :skipRows],
110
+ :defaults => defaults,
111
+ :required => [:fileURL]
112
+ })
113
+ end
114
+
115
+ def self.sfdc_reader2(data, options={})
116
+ local_defaults = {
117
+ :type => SF_READER,
118
+ }
119
+ defaults = local_defaults.merge(options[:defaults] || {})
120
+
121
+ base_node(defaults.merge(data), {
122
+ :allowed => [:soql, :sfdcConnection, :mandatoryFields],
123
+ :defaults => defaults,
124
+ :required => [:soql, :sfdcConnection]
125
+ })
126
+
127
+ end
128
+
129
+ def self.run_graph2(data, options={})
130
+ local_defaults = {
131
+ :type => RUN_GRAPH,
132
+ :paramsToPass => "GDC_WEBDAV_ROOT;GDC_PROJECT_ID;GDC_USERNAME;GDC_PASSWORD;GDC_SST"
133
+ }
134
+ defaults = local_defaults.merge(options[:defaults] || {})
135
+
136
+ base_node(defaults.merge(data), {
137
+ :allowed => [:paramsToPass, :type, :name, :clientId, :loginHostname, :name, :username, :password, :passwordEncrypted, :token, :id],
138
+ :defaults => defaults,
139
+ :required => [:graphName]
140
+ })
141
+ end
142
+
143
+ def self.edge2(data, options={})
144
+ local_defaults = {
145
+ :type => EDGE,
146
+ :guiBendpoints => "",
147
+ :guiRouter => "Manhattan",
148
+ :inPort => "Port 0 (in)",
149
+ :outPort => "Port 0 (output)"
150
+ }
151
+ defaults = local_defaults.merge(options[:defaults] || {})
152
+ base_node(defaults.merge(data), {
153
+ :allowed => [],
154
+ :defaults => defaults,
155
+ :required => []
156
+ })
157
+ end
158
+
159
+ def self.metadata2(data)
160
+ data
161
+ end
162
+
163
+ def self.reformat2(data, options={})
164
+ local_defaults = {
165
+ :type => REFORMAT,
166
+ }
167
+ defaults = local_defaults.merge(options[:defaults] || {})
168
+ base_node(defaults.merge(data), {
169
+ :allowed => [],
170
+ :defaults => defaults,
171
+ :required => []
172
+ })
173
+ end
174
+
175
+ def self.normalizer2(data, options={})
176
+ local_defaults = {
177
+ :type => NORMALIZER,
178
+ }
179
+ defaults = local_defaults.merge(options[:defaults] || {})
180
+ base_node(defaults.merge(data), {
181
+ :allowed => [],
182
+ :defaults => defaults,
183
+ :required => []
184
+ })
185
+ end
186
+
187
+
188
+ def self.lookup_reader_writer2(data, options={})
189
+ local_defaults = {
190
+ :type => LOOKUP_TABLE_READER_WRITER,
191
+ }
192
+ defaults = local_defaults.merge(options[:defaults] || {})
193
+ base_node(defaults.merge(data), {
194
+ :allowed => [],
195
+ :defaults => defaults,
196
+ :required => []
197
+ })
198
+ end
199
+
200
+ def self.lookup2(data, options={})
201
+ local_defaults = {
202
+ :type => PERSISTENT_LOOKUP,
203
+ :cacheSize => "1000",
204
+ :commitInterval => "100",
205
+ :pageSize => "16"
206
+ }
207
+ defaults = local_defaults.merge(options[:defaults] || {})
208
+ base_node(defaults.merge(data), {
209
+ :allowed => [],
210
+ :defaults => defaults,
211
+ :required => [:metadata]
212
+ })
213
+ end
214
+
215
+ def self.trash2(data, options={})
216
+ local_defaults = {
217
+ :type => TRASH,
218
+ }
219
+ defaults = local_defaults.merge(options[:defaults] || {})
220
+ base_node(defaults.merge(data), {
221
+ :allowed => [],
222
+ :defaults => defaults,
223
+ :required => []
224
+ })
225
+ end
226
+
227
+ def self.data_generator2(data, options={})
228
+ local_defaults = {
229
+ :type => DATA_GENERATOR,
230
+ :recordsNumber => 1
231
+ }
232
+ defaults = local_defaults.merge(options[:defaults] || {})
233
+ base_node(defaults.merge(data), {
234
+ :allowed => [],
235
+ :defaults => defaults,
236
+ :required => []
237
+ })
238
+ end
239
+
240
+ # <Node baseURL="${DATA}/1_in.csv" enabled="enabled" guiHeight="65" guiName="File List" guiWidth="128" guiX="147" guiY="213" id="FILE_LIST0" outputMapping="//#CTL2&#10;&#10;// Transforms input record into output record.&#10;function integer transform() {&#10;&#9;$out.0.field1 = $in.0.fileName;&#10;&#10;&#9;return ALL;&#10;}&#10;&#10;// Called during component initialization.&#10;// function boolean init() {}&#10;&#10;// Called during each graph run before the transform is executed. May be used to allocate and initialize resources&#10;// required by the transform. All resources allocated within this method should be released&#10;// by the postExecute() method.&#10;// function void preExecute() {}&#10;&#10;// Called only if transform() throws an exception.&#10;// function integer transformOnError(string errorMessage, string stackTrace) {}&#10;&#10;// Called during each graph run after the entire transform was executed. Should be used to free any resources&#10;// allocated within the preExecute() method.&#10;// function void postExecute() {}&#10;&#10;// Called to return a user-defined error message when an error occurs.&#10;// function string getMessage() {}&#10;" type="FILE_LIST"/>
241
+ def self.file_list2(data, options={})
242
+ local_defaults = {
243
+ :type => FILE_LIST,
244
+ }
245
+ defaults = local_defaults.merge(options[:defaults] || {})
246
+ base_node(defaults.merge(data), {
247
+ :allowed => [],
248
+ :defaults => defaults,
249
+ :required => []
250
+ })
251
+ end
252
+
253
+ def self.hash_join2(data, options={})
254
+ local_defaults = {
255
+ :type => EXT_HASH_JOIN,
256
+ }
257
+ defaults = local_defaults.merge(options[:defaults] || {})
258
+ base_node(defaults.merge(data), {
259
+ :allowed => [],
260
+ :defaults => defaults,
261
+ :required => []
262
+ })
263
+ end
264
+
265
+ def self.sort2(data, options={})
266
+ local_defaults = {
267
+ :type => EXT_SORT,
268
+ }
269
+ defaults = local_defaults.merge(options[:defaults] || {})
270
+ base_node(defaults.merge(data), {
271
+ :allowed => [],
272
+ :defaults => defaults,
273
+ :required => []
274
+ })
275
+ end
276
+
277
+ def self.es_truncate2(data, options={})
278
+ local_defaults = {
279
+ :type => GD_ESTORE_TRUNCATE,
280
+ }
281
+ defaults = local_defaults.merge(options[:defaults] || {})
282
+ base_node(defaults.merge(data), {
283
+ :allowed => [],
284
+ :defaults => defaults,
285
+ :required => []
286
+ })
287
+ end
288
+
289
+
290
+ def self.es_reader2(data, options={})
291
+ local_defaults = {
292
+ :type => GD_ESTORE_READER,
293
+ }
294
+ defaults = local_defaults.merge(options[:defaults] || {})
295
+ base_node(defaults.merge(data), {
296
+ :allowed => [],
297
+ :defaults => defaults,
298
+ :required => []
299
+ })
300
+ end
301
+
302
+ def self.es_writer2(data, options={})
303
+ local_defaults = {
304
+ :type => GD_ESTORE_WRITER,
305
+ }
306
+ defaults = local_defaults.merge(options[:defaults] || {})
307
+ base_node(defaults.merge(data), {
308
+ :allowed => [],
309
+ :defaults => defaults,
310
+ :required => []
311
+ })
312
+ end
313
+
314
+
315
+ def self.file_delete2(data, options={})
316
+ local_defaults = {
317
+ :type => FILE_DELETE
318
+ }
319
+ defaults = local_defaults.merge(options[:defaults] || {})
320
+ base_node(defaults.merge(data), {
321
+ :allowed => [],
322
+ :defaults => defaults,
323
+ :required => []
324
+ })
325
+ end
326
+
327
+ def self.file_copy2(data, options={})
328
+ local_defaults = {
329
+ :type => FILE_COPY_MOVE,
330
+ :operation => "COPY",
331
+ :baseURL => "${PROJECT}"
332
+ }
333
+ defaults = local_defaults.merge(options[:defaults] || {})
334
+ base_node(defaults.merge(data), {
335
+ :allowed => [],
336
+ :defaults => defaults,
337
+ :required => []
338
+ })
339
+ end
340
+
341
+
342
+ def self.copy2(data, options={})
343
+ local_defaults = {
344
+ :type => SIMPLE_COPY,
345
+ }
346
+ defaults = local_defaults.merge(options[:defaults] || {})
347
+ base_node(defaults.merge(data), {
348
+ :allowed => [],
349
+ :defaults => defaults,
350
+ :required => []
351
+ })
352
+ end
353
+
354
+ def self.connection2(data, options={})
355
+ local_defaults = {
356
+ :type => SF_CONNECTION,
357
+ :passwordEncrypted => "false",
358
+ :loginHostname => "login.salesforce.com",
359
+ :clientId => "gooddata/gooddata/",
360
+ :name => "Salesforce connection"
361
+ }
362
+ defaults = local_defaults.merge(options[:defaults] || {})
363
+ node(defaults.merge(data), {
364
+ :allowed => [:type, :name, :clientId, :loginHostname, :name, :username, :password, :passwordEncrypted, :token, :id],
365
+ :defaults => defaults,
366
+ :required => [:password, :username, :token, :loginHostname, :id, :clientId, :name]
367
+ })
368
+ end
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,8 @@
1
+ {
2
+ "name" : "Quota attainment usecase"
3
+ ,"type" : "usecase"
4
+ ,"package" : "GoodSales"
5
+ ,"version" : "0.0.1"
6
+ ,"provides" : ["quota_attainment"]
7
+ ,"requires" : ["GoodSales/opportunity", "GoodSales/user"]
8
+ }
@@ -0,0 +1,21 @@
1
+ module GoodData
2
+ module CloverGenerator
3
+ module Repo
4
+
5
+ def self.parse(json_definition)
6
+ JSON.parse(json_definition, :symbolize_names => true)
7
+ end
8
+
9
+ def self.load(path)
10
+ definitions = nil
11
+ FileUtils.cd(path) do
12
+ definitions = Dir.glob('*.json').map do |f|
13
+ parse(File.read(f))
14
+ end
15
+ end
16
+ definitions
17
+ end
18
+
19
+ end
20
+ end
21
+ end