twb 1.9.1 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,208 @@
1
+ # DocumentedFieldsCSVEmitter.rb - this Ruby script Copyright 2017 Christopher Gerrard
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'twb'
17
+ require 'csv'
18
+
19
+ module Twb
20
+ module Analysis
21
+
22
+ class DocumentedFieldsCSVEmitter
23
+
24
+ attr_reader :csvFileName, :csvRecords
25
+ attr_reader :dsCount, :fieldsCount
26
+
27
+ @@csvHeader = ['Record #',
28
+ 'Workbook',
29
+ 'Workbook Dir',
30
+ 'Data Source',
31
+ 'Field',
32
+ 'Doc Type',
33
+ 'Doc Line #'
34
+ 'Doc Line'
35
+ ]
36
+ @@csvFileType = 'TwbAnnotatedFields'
37
+ @@csvFileName = @@csvFileType + '.csv'
38
+
39
+ def initialize
40
+ @csvFile = CSV.open(@@csvFileName,'w')
41
+ @csvFile << @@csvHeader
42
+ @csvRecords = Set.new
43
+ puts "Opened: #{!@csvFile.nil?} - #{@@csvFileName}"
44
+ # --
45
+ @recNum = 0
46
+ @dsCount = 0
47
+ @fieldsCount = 0
48
+ end
49
+
50
+ def self.csvHeader
51
+ @@csvHeader
52
+ end
53
+
54
+ def self.csvFileType
55
+ @@csvFileType
56
+ end
57
+
58
+ def self.csvFileNaame
59
+ @@csvFileName
60
+ end
61
+
62
+ def processTwb twb
63
+ @twb = nil
64
+ @twb = twb if twb.instance_of? Twb::Workbook
65
+ @twb = Twb::Workbook.new(twb) if twb.instance_of? String
66
+ raise ArgumentError.new("ERROR in Workbok processing: '#{twb}' must be a Workbook (class) or the name of a Workbook (String), is a #{twb.class} \n ") unless @twb.is_a? Twb::Workbook
67
+ # --
68
+ dss = @twb.datasources
69
+ dss.each do |ds|
70
+ @dsname = ds.uiname
71
+ # puts "\n -- #{ds.uiname} "
72
+ # tables = Set.new
73
+ fields = {}
74
+ @dsCount += 1
75
+ fclasses = Set.new
76
+ ds.localFields.each do |field|
77
+ recordFieldFull field, :local
78
+ # recordField( fields, field, {:type=>:local,:columnField=>true,:hidden=>field.hidden} )
79
+ # emitTech( ds, field.uiname, 'Local', field.properties)
80
+ # recordTech( field, 'LocalA')
81
+ end
82
+ ds.columnFields.each do |field|
83
+ recordFieldFull field, :column
84
+ # recordField( fields, field, {:type=>'column',:columnField=>true,:hidden=>field.hidden} )
85
+ # emitTech( ds, field.uiname, 'Column', field.properties)
86
+ # recordTech( field, 'ColumnA')
87
+ end
88
+ ds.calculatedFields.each do |field|
89
+ recordFieldFull field, :calc
90
+ # puts "WWW #{field.class} :: #{field} ::prop:: #{field.properties.class} :: #{field.properties}"
91
+ # recordField( fields, field, {:type=>'calc',:calculatedField=>true,:hidden=>field.hidden} )
92
+ # emitTech( ds, field.uiname, 'Calculated', field.properties)
93
+ # recordTech( field, 'CalcA')
94
+ end
95
+ ds.metadataFields.each do |field|
96
+ recordFieldFull field, :metadata
97
+ # recordField( fields, field, {:type=>'metadata',:metadataField=>true} )
98
+ # emitTech( ds, field.uiname, 'MetaData', field.properties)
99
+ # recordTech( field, 'MetadataA')
100
+ end
101
+ ds.dbFields.each do |field|
102
+ recordFieldFull field, :db
103
+ # recordField( fields, field, {:type=>'database',:dbField=>true} )
104
+ # emitTech( ds, field.uiname, 'Db', field.properties)
105
+ # recordTech( field, 'DbA')
106
+ end
107
+ ds.mappedFields.each do |field|
108
+ recordFieldFull field, :mapped
109
+ # recordField( fields, field, {:type=>'mapped',:mappedField=>true} )
110
+ # emitTech( ds, field.uiname, 'Mapped', field.properties)
111
+ # recordTech( field, 'MappedA')
112
+ end
113
+ emitFields(fields)
114
+ end
115
+ end # def processTwb twb
116
+
117
+ def recordFieldFull field, source
118
+ # print field.properties.nil? ? '-' : ":#{field.properties.length}"
119
+ # puts field.properties
120
+ @recNum+=1
121
+ field.properties.each do |name,value|
122
+ # print name
123
+ @csvFileFull << [ @recNum,
124
+ @twb.name,
125
+ @twb.dir,
126
+ @dsname,
127
+ field.uiname,
128
+ source,
129
+ field.class,
130
+ field.node.path.to_s.gsub(/[0-9]/,'').gsub('[]',''),
131
+ name,
132
+ value
133
+ ]
134
+ # @csvFileFull << csvRec
135
+ end
136
+ end
137
+
138
+ def recordField fields, field, props
139
+ # puts "%-65s :: %s " % [fieldName,props]
140
+ return if field.uiname.nil?
141
+ if fields.has_key? field.uiname
142
+ fields[field.uiname].merge! field.properties
143
+ else
144
+ fields[field.uiname] = field.properties
145
+ end
146
+ end
147
+
148
+ def emitFields fields
149
+ fields.each do |fieldName,props|
150
+ # puts "FIELD:: %-40s :: %s" % [fieldName,props.inspect]
151
+ # class = props[]
152
+ csvRec = [ @recNum+=1,
153
+ @twb.name,
154
+ @twb.dir,
155
+ @dsname,
156
+ fieldName,
157
+ props[:type],
158
+ props['hidden'],
159
+ props[:columnField],
160
+ props[:calculatedField],
161
+ props[:dbField],
162
+ props[:mappedField],
163
+ props[:metadataField]
164
+ ]
165
+ @csvFile << csvRec
166
+ @csvRecords.add csvRec
167
+ end
168
+ end
169
+
170
+ def recordTech field, type
171
+ @recNum+=1
172
+ field.properties.each do |name,value|
173
+ @csvFileTech << [ @recNum,
174
+ @twb.name,
175
+ @twb.dir,
176
+ @dsname,
177
+ field.uiname,
178
+ type,
179
+ name,
180
+ value
181
+ ]
182
+ end
183
+ end
184
+
185
+ def emitTech dataSource, fieldName, type, properties
186
+ # puts "XX #{dataSource.uiname} :: #{fieldName} #{} :: #{type} :: #{properties}"
187
+ @recNum+=1
188
+ properties.each do |name,value|
189
+ @csvFileTech << [ @recNum,
190
+ @twb.name,
191
+ @twb.dir,
192
+ dataSource.uiname,
193
+ fieldName,
194
+ type,
195
+ name,
196
+ value
197
+ ]
198
+ end
199
+ end
200
+
201
+ def cleanup
202
+ @csvFile.close unless @csvFile.nil?
203
+ end
204
+
205
+ end # class DocumentedFieldsCSVEmitter
206
+
207
+ end # module Analysis
208
+ end # module Twb
@@ -0,0 +1,77 @@
1
+ # calculatedfieldsanalyzer.rb - this Ruby script Copyright 2017 Christopher Gerrard
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'twb'
17
+
18
+ module Twb
19
+ module Analysis
20
+
21
+ class DocumentedFieldsMarkdownEmitter
22
+
23
+ attr_reader :docFileName
24
+
25
+ def initialize
26
+ # puts ""
27
+ end
28
+
29
+ def processTwb twbName
30
+ @twb = Twb::Workbook.new twbName
31
+ @docFileName = @twb.name + '.DocumentedFields.md'
32
+ @docFile = File.open(@docFileName,'w')
33
+ @docFile.puts "## #{@twb.name}"
34
+ dss = @twb.datasources
35
+ @docFile.puts "#{dss.length} Data Source#{(dss.length>1) ? 's' : ''}"
36
+ @docFile.puts " "
37
+ dss.each do |ds|
38
+ @docFile.puts "- #{ds.uiname}"
39
+ end
40
+ @docFile.puts " "
41
+ dss.each do |ds|
42
+ @docFile.puts "### #{ds.uiname}"
43
+ columnFields = ds.columnFields #.sort_by { |fldName,calc| fldName }
44
+ columnFields.each do |field|
45
+ commentLines = field.comment
46
+ calculation = field.calcField
47
+ # puts "\n#{field.uiname}"
48
+ # puts "Comment? #{commentLines}"
49
+ # puts "Calc ? #{calculation}"
50
+ @docFile.puts "\n##### #{field.uiname} "
51
+ unless commentLines.nil?
52
+ commentLines.each do |line|
53
+ @docFile.puts "###### #{line}"
54
+ end
55
+ end
56
+ unless calculation.nil?
57
+ @docFile.puts "```"
58
+ @docFile.puts calculation.formulaResolved
59
+ @docFile.puts "\n -- Fields --" unless calculation.calcFields.empty?
60
+ refFields = SortedSet.new
61
+ calculation.calcFields.each do |cf|
62
+ fds = if cf.dataSourceRef == :remote then "<<#{cf.dataSource}>>" else '' end
63
+ refFields.add "#{cf.uiName} \t #{fds}"
64
+ end
65
+ refFields.each do |rf|
66
+ @docFile.puts " #{rf}"
67
+ end
68
+ @docFile.puts "```"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end # class MarkdownEmitter
75
+
76
+ end # module Analysis
77
+ end # module Twb
@@ -19,14 +19,16 @@ module Twb
19
19
 
20
20
  class CalculatedField
21
21
 
22
- attr_reader :node, :dataSource
22
+ attr_reader :dataSource
23
+ attr_reader :node, :properties
23
24
  attr_reader :caption, :name, :uiname
24
25
  attr_reader :datatype, :role, :type
25
- attr_reader :calculation
26
+ attr_reader :calculation, :calcFields
27
+ attr_reader :hidden
26
28
 
27
29
  def initialize(calcNode, datasource=nil)
28
- @dataSource = datasource
29
30
  @node = calcNode
31
+ @dataSource = datasource
30
32
  # --
31
33
  @caption = calcNode.attribute('caption').text if calcNode.has_attribute?('caption')
32
34
  @name = calcNode.attribute('name').text.gsub(/^\[/,'').gsub(/\]$/,'')
@@ -37,6 +39,37 @@ module Twb
37
39
  @type = @node.attribute('type').text
38
40
  # --
39
41
  @calculation = Twb::FieldCalculation.new(self, datasource)
42
+ # --
43
+ @hidden = true if calcNode.has_attribute?('caption')
44
+ end
45
+
46
+ def properties
47
+ @properties ||= loadProperties
48
+ end
49
+
50
+ def calcLines
51
+ @calculation.calcFields
52
+ end
53
+
54
+ def formulaLines
55
+ @calculation.formulaLines
56
+ end
57
+
58
+ def formulaResolvedLines
59
+ @calculation.formulaResolvedLines
60
+ end
61
+
62
+ def formulaResolved
63
+ @calculation.formulaResolved
64
+ end
65
+
66
+ def loadProperties
67
+ @properties= {}
68
+ @node.attributes.each do |name,attr|
69
+ @properties[name] = attr.value
70
+ end
71
+ @properties[:uiname] = @uiname
72
+ return @properties
40
73
  end
41
74
 
42
75
  def to_s
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014, 2015 Chris Gerrard
1
+ # Copyright (C) 2014, 2018 Chris Gerrard
2
2
  #
3
3
  # This program is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -47,15 +47,18 @@ module Twb
47
47
  # value
48
48
  # visual-totals
49
49
 
50
- attr_reader :node
50
+ attr_reader :node, :properties
51
51
  attr_reader :name, :caption, :uiname
52
52
  attr_reader :dataType, :defaultFormat, :paramDomainType
53
53
  attr_reader :role, :type, :value
54
54
  attr_reader :alias, :semanticRole, :aggregation
55
55
  attr_reader :autoColumn, :hidden, :datatypeCustomized
56
+ attr_reader :calcField
56
57
 
57
58
 
58
- def initialize fieldNode
59
+ def initialize(fieldNode, datasource=nil)
60
+
61
+ @datasource = datasource
59
62
  @node = fieldNode
60
63
  @name = load 'name'
61
64
  @caption = load 'caption'
@@ -73,6 +76,7 @@ module Twb
73
76
  @autoColumn = load 'auto-column'
74
77
  @hidden = load 'hidden'
75
78
  @datatypeCustomized = load 'datatype-customized'
79
+ @calcField = loadCalcField
76
80
  end
77
81
 
78
82
  def load nodeName
@@ -81,6 +85,69 @@ module Twb
81
85
  return val
82
86
  end
83
87
 
88
+ def calcField
89
+ @calcField ||= loadCalcField
90
+ end
91
+
92
+ def loadCalcField
93
+ if !@node.at_xpath('./calculation').nil?
94
+ @calcField = Twb::CalculatedField.new @node, @datasource
95
+ else
96
+ @calcField = nil
97
+ end
98
+ end
99
+
100
+ def comment
101
+ @commentLines ||= loadComment
102
+ end
103
+
104
+ # COMMENTED FIELDS
105
+ # --------------------------------------
106
+ # <column caption='Calculation1' datatype='real' name='[Calculation_821344020759588865]' role='measure' type='quantitative'>
107
+ # <calculation class='tableau' formula='[Formula Length] * 1.1' />
108
+ # <desc>
109
+ # <formatted-text>
110
+ # <run>THIS IS A COMMENT</run>
111
+ # </formatted-text>
112
+ # </desc>
113
+ # </column>
114
+ # <column datatype='string' name='[Data Source Name (tech) (CalculatedFieldsReferencedFields.csv)]' role='dimension' type='nominal'>
115
+ # <desc>
116
+ # <formatted-text>
117
+ # <run>THIS IS A COMMENT</run>
118
+ # </formatted-text>
119
+ # </desc>
120
+ # </column>
121
+ def loadComment
122
+ @commentLines = []
123
+ runs = @node.xpath('./desc/formatted-text/run')
124
+ runs.each do |run|
125
+ lines = run.text.split(/\n/)
126
+ lines.each do |line|
127
+ @commentLines << line
128
+ end
129
+ end
130
+ return @commentLines
131
+ end
132
+
133
+ def hasComment?
134
+ loadComment if @commentLines.nil?
135
+ @commentLines.empty?
136
+ end
137
+
138
+ def properties
139
+ @properties ||= loadProperties
140
+ end
141
+
142
+ def loadProperties
143
+ @properties= {}
144
+ @node.attributes.each do |name,attr|
145
+ @properties[name] = attr.value
146
+ end
147
+ @properties[:uiname] = @name
148
+ return @properties
149
+ end
150
+
84
151
  def to_s
85
152
  @name
86
153
  end
@@ -48,6 +48,7 @@ module Twb
48
48
  attr_reader :metadataFields
49
49
  attr_reader :dbFields
50
50
  attr_reader :mappedFields
51
+ attr_reader :tableFieldsMap
51
52
  attr_reader :fieldUINames
52
53
  attr_reader :calculatedFields, :calculatedFieldNamesMap, :calculatedFieldNames, :calculatedField
53
54
  attr_reader :allFields
@@ -59,7 +60,7 @@ module Twb
59
60
  @workbook = workbook
60
61
  @name = @node.attr('name')
61
62
  @caption = @node.attr('caption')
62
- @uiname = if @caption.nil? || @caption == '' then @name else @caption end
63
+ @uiname = @caption.nil? ? @name : @caption
63
64
  processConnection
64
65
  processFilters
65
66
  loadTableFields
@@ -150,7 +151,6 @@ module Twb
150
151
  table = code.split('].[')[0][1..-1]
151
152
  end
152
153
 
153
-
154
154
  def Parameters?
155
155
  'Parameters'.eql? @name
156
156
  end
@@ -159,22 +159,30 @@ module Twb
159
159
  @columnFields ||= loadColumnFields
160
160
  end
161
161
 
162
+ def columnFieldsMap
163
+ loadColumnFields if @columnFieldsMap.nil?
164
+ return @columnFieldsMap
165
+ end
166
+
162
167
  def loadColumnFields
163
- @columnFields = Set.new
168
+ @columnFields = Set.new
169
+ @columnFieldsMap = {}
164
170
  nodes = @node.xpath('./column')
165
171
  nodes.each do |n|
166
- field = Twb::ColumnField.new n
172
+ field = Twb::ColumnField.new n, self
167
173
  @columnFields << field
174
+ @columnFieldsMap[field.uiname] = field
168
175
  end
169
176
  return @columnFields
170
177
  end
171
178
 
179
+
172
180
  def localFields
173
181
  @localFields ||= loadLocalFields
174
182
  end
175
183
 
176
184
  def loadLocalFields
177
- @localFields = {}
185
+ @localFields = Set.new
178
186
  unless @connection.nil? # Parameters has no connection node, & no local fields
179
187
  connClass = @node.at_xpath('./connection').attribute('class').text
180
188
  fxpath = case connClass
@@ -185,7 +193,7 @@ module Twb
185
193
  nodes = @node.xpath(fxpath)
186
194
  nodes.each do |node|
187
195
  field = Twb::LocalField.new(node)
188
- @localFields[field.name] = field
196
+ @localFields << field
189
197
  end
190
198
  end
191
199
  return @localFields
@@ -201,7 +209,7 @@ module Twb
201
209
  # nodes = @node.xpath(".//metadata-record[@class='column']")
202
210
  # # note: there are other nodes "<metadata-record class='capability'>" whose nature is unclear
203
211
  # # these nodes have no value for their <name node, so are not loaded
204
- nodes = @node.xpath('./connection//metadata-record')
212
+ nodes = @node.xpath("./connection//metadata-record[@class='column']")
205
213
  nodes.each do |node|
206
214
  field = Twb::MetadataField.new(node)
207
215
  field.source = :db
@@ -234,34 +242,44 @@ module Twb
234
242
 
235
243
  def loadFieldUINames
236
244
  @fieldUINames = {}
237
- columnNodes = @node.xpath('./column')
238
- columnNodes.each do |cn|
239
- name = cn.attribute('name').text.gsub(/^\[|\]$/,'')
240
- caption = cn.attribute('caption')
241
- uiName = caption.nil? ? name : caption.text
242
- @fieldUINames[name] = uiName
243
- @fieldUINames[caption.text] = caption.text unless caption.nil? # in case of unintended usage: lookup by Caption name
245
+ metadataFields.each do |fld|
246
+ unless fld.localName.nil?
247
+ @fieldUINames[fld.localName] = fld.uiname
248
+ @fieldUINames[fld.uiname] = fld.uiname
249
+ end
250
+ end
251
+ calculatedFields.each do |fld|
252
+ @fieldUINames[fld.name] = fld.uiname
253
+ @fieldUINames[fld.uiname] = fld.uiname
244
254
  end
245
- mappedFields.each do |fname,fmap|
246
- dbTable = fmap['table']
247
- dbName = fmap['dbName']
248
- @fieldUINames[dbName] = fname unless @fieldUINames.include?(dbName)
249
- @fieldUINames[fname] = fname unless @fieldUINames.include?(fname)
255
+ localFields.each do |fld|
256
+ @fieldUINames[fld.name] = fld.uiname
257
+ @fieldUINames[fld.uiname] = fld.uiname
250
258
  end
251
259
  end
252
260
 
261
+ def tableFields
262
+ @tableFieldsMap.values
263
+ end
264
+
265
+ def dbFieldsMap
266
+ @tableFieldsMap
267
+ end
268
+
253
269
  def dbFields
254
- return @mappedFields unless @mappedFields.nil?
255
- loadTableFields
256
- return @mappedFields
270
+ @tableFieldsMap.values
271
+ end
272
+
273
+ def mappedFieldsMap
274
+ loadTableFields if @tableFieldsMap.nil?
275
+ return @tableFieldsMap
257
276
  end
258
277
 
259
278
  def mappedFields
260
- loadTableFields if @mappedFields.nil?
261
- return @mappedFields
279
+ loadTableFields if @tableFieldsMap.nil?
280
+ return @tableFieldsMap.values
262
281
  end
263
282
 
264
- # NOTE: Calculated Fields are mapped by their UI name
265
283
  def calculatedFieldsMap
266
284
  @calculatedFieldsMap ||= loadCalculatedFields
267
285
  end
@@ -296,48 +314,40 @@ module Twb
296
314
  @allFields = SortedSet.new
297
315
  dbf = dbFields
298
316
  @allFields << dbf.keys
317
+ @allFields << calculatedFieldNames
299
318
  end
300
319
 
301
320
  def has_field? fieldName
302
- dbFields.has_key? fieldName
321
+ dbFieldsMap.has_key? fieldName
303
322
  end
304
323
 
305
324
  def fieldTable fieldName
306
- loadTableFields if @mappedFields.nil?
307
- tf = @mappedFields[fieldName]
308
- return tf.nil? ? nil : tf['table']
325
+ loadTableFields if @tableFieldsMap.nil?
326
+ dbField = @tableFieldsMap[fieldName]
327
+ return dbField.nil? ? nil : dbField.dbtable
309
328
  end
310
329
 
311
330
  # fields are unique in the data source by UI name
312
331
  def loadTableFields
313
332
  # puts "DATA SOURCE FIELD TABLE LOAD"
314
- @mappedFields = {}
333
+ @tableFieldsMap = {}
315
334
  fieldNodes = @node.xpath('./connection/cols/map')
316
335
  fieldNodes.each do |fn|
317
- uiName = fn.attribute('key').text.gsub(/^\[|\]$/,'')
318
- fldRef = fn.attribute('value').text.gsub(/^\[|\]$/,'')
319
- parts = fldRef.split('].[')
320
- table = parts[0]
321
- dbName = parts[1]
322
- @mappedFields[uiName] = {'table' => table, 'dbName' => dbName}
323
- # puts "=== #{uiName} :: T=#{@mappedFields[uiName]['table']} DBN=#{@mappedFields[uiName]['dbName']} "
336
+ dbField = Twb::DbField.new(@uiname, fn, :map)
337
+ @tableFieldsMap[dbField.uiname] = dbField
324
338
  end
325
339
  relTableNodes = @node.xpath('.//relation[@table]')
326
340
  relTableNodes.each do |relNode|
327
341
  table = relNode.attribute('name').text
328
- cols = relNode.xpath('./columns/column')
342
+ cols = relNode.xpath('./columns/column')
329
343
  cols.each do |col|
344
+ dbField = Twb::DbField.new(@uiname, col, :tableColumn, table)
330
345
  fldName = col.attribute('name')
331
- @mappedFields[fldName.text] = {'table' => table, 'dbName' => @uiname} unless fldName.nil?
346
+ @tableFieldsMap[dbField.uiname] = dbField
332
347
  end
333
348
  end
334
349
  end
335
350
 
336
- # =begin
337
- # <filter class='categorical' column='[enforcement_type]' filter-group='2'>
338
- # <groupfilter function='member' level='[enforcement_type]' member='&quot;towing&quot;' user:ui-domain='database' user:ui-enumeration='inclusive' user:ui-marker='enumerate' />
339
- # </filter>
340
- # end
341
351
  def processFilters
342
352
  if @filters.nil?
343
353
  @filters = {}
@@ -360,70 +370,6 @@ module Twb
360
370
 
361
371
  end # class DataSource
362
372
 
363
- # DataSource Utilities
364
-
365
- # # Generates and returns a set of graph node-edge-node triplets.
366
- # # The intention is to create a graph that can be standalone used as a subgraph by the function's caller.
367
- # # The initial implementation only considers a linear list of node names as input, resulting in
368
- # # the creation of a single-path structure, e.g.
369
- # # [inNode] -> node1 -> node2 -> ... -> nodeN
370
- # # this may manifest as a tree when there are siblings at any level, e.g.
371
- # # [inNode] -> node1 -> node11 -> ... -> nodeX
372
- # # -> node22 -> ... -> nodeY
373
- # # -> node2 -> node21 -> ... -> nodeZ
374
- # # Params:
375
- # # +inNodes+:: the node(s) to which this function's generated graph is to be linked, may be nil:
376
- # # + , or multiple)
377
- # # +nodesList+:: list of node types by name to be built and linked together, in the order named
378
- # def graphNodes nodesList
379
- # graph = Twb::Util::Graphedges.new()
380
- # nodesList.each do |nName|
381
- # end
382
- # case @dsclass
383
- # when 'federated'
384
- # graph = processFederatedSource nodesList
385
- # end
386
- # return graph
387
- # end
388
-
389
- # def processFederatedSource nodesList
390
- # emit false, " (federated) #{dataSource.uiname}"
391
- # dsGNode = Twb::Util::Graphnode.new(name: @uiname, id: @name, type: 'Data Connection')
392
- # graph = Twb::Util::Graphedges.new(dsGNode)
393
- # edges = []
394
- # dsNode = dataSource.node
395
- # connections = dsNode.xpath('./connection/named-connections/named-connection/connection')
396
- # connections.each do |conn|
397
- # connClass = conn.attribute('class').text
398
- # emit true, "CONN CLASS: #{connClass}"
399
- # # -- Generating Source Node
400
- # cgParams = @@cgNodeParams[connClass]
401
- # # emit true, "cgparams : #{cgParams}"
402
- # cLabel = buildConnGraphPart( conn, cgParams['label'])
403
- # cID = buildConnGraphPart( conn, cgParams['id'])
404
- # cType = cgParams['type']
405
- # # emit true, " label : #{cLabel}"
406
- # # emit true, " id : #{cID}"
407
- # # emit true, " type : #{cType}"
408
- # srcNode = Twb::Util::Graphnode.new(name: cLabel, id: cID, type: 'Data Source')
409
- # graphEdge = Twb::Util::Graphedge.new(from: dsGNode, to: srcNode, relationship: 'is located at')
410
- # graph.edges << graphEdge
411
- # end
412
- # return graph
413
- # end
414
-
415
- # def buildConnGraphPart connNode, attributes
416
- # return connNode.attribute(attributes) if attributes.is_a? String
417
- # emit false, "ATTRIBUTES :: #{attributes}"
418
- # str = ''
419
- # attributes.each do |attName|
420
- # attrib = connNode.attribute(attName)
421
- # emit false, " -#{attName}\t-> #{attrib}"
422
- # str += attrib.text unless attrib.nil?
423
- # end
424
- # return str
425
- # end
426
-
427
373
 
428
374
  class JoinTablePair
429
375
  attr_reader :from, :to