gd_bam 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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