twb 4.9.10 → 5.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/twb.rb +1 -1
- data/lib/twb/analysis/calculatedfields/calculatedfieldsanalyzer.rb +47 -32
- data/lib/twb/analysis/calculatedfields/t.rb +6 -0
- data/lib/twb/calculatedfield.rb +4 -4
- data/lib/twb/columnfield.rb +2 -2
- data/lib/twb/datasource.rb +49 -37
- data/lib/twb/fieldcalculation.rb +171 -98
- data/test/testFieldCalculation.rb +10 -6
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f839625abecd6c9b4ad520856fd216678790a2dace5307e62458db4e07b970cd
|
4
|
+
data.tar.gz: f95701f60e3f4f99525113e723392b1d039b361db9ac63eb2689c58ef4a3a490
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d59954bb21cc6b232402d0792219df4e0e48ddcf8a664088b58409c7e28b30175f3f3304910459304f2d87639bf1ce5a6f7d9b533b43ed0088bfbb1c4f131c8f
|
7
|
+
data.tar.gz: c8fa036df0e3e8808f507404f5930a8db20ca19fb7a04251eda1deee7dc1ea09f1e06a811f79539275d2eed9cb473f009239dca5ae1c56c7179f4826ed0201c0
|
data/lib/twb.rb
CHANGED
@@ -249,47 +249,62 @@ DOTHEADER
|
|
249
249
|
]
|
250
250
|
end
|
251
251
|
#-- collect fields referenced in formula
|
252
|
-
emit "# Calculated Fields: #{calculation.
|
253
|
-
calculation.
|
254
|
-
emit " referenced field ::
|
255
|
-
emit " referenced field.name ::'#{rf.name.nil?}' :: '#{rf.name}'"
|
256
|
-
emit " referenced field.uiname::'#{rf.uiname}'"
|
257
|
-
# if @doGraph
|
258
|
-
unless rf.uiname.nil?
|
259
|
-
properties = {'DataSource' => ds.uiname, 'DataSourceReference' => 'local', :source => rf}
|
260
|
-
refFieldNode = Twb::Util::Graphnode.new(name: rf.uiname, id: rf.id, type: rf.type, properties: properties)
|
261
|
-
@nodes.add refFieldNode
|
262
|
-
fieldFieldEdge = Twb::Util::Graphedge.new(from: calcFieldNode, to: refFieldNode, relationship: 'references')
|
263
|
-
@edges.add fieldFieldEdge
|
264
|
-
end
|
265
|
-
# end
|
266
|
-
referencedFields.add rf.id
|
267
|
-
refFieldTable = ds.fieldTable(rf.name)
|
268
|
-
emit "refFieldTable.nil? : #{refFieldTable.nil?}"
|
269
|
-
unless refFieldTable.nil?
|
270
|
-
tableID = refFieldTable + ':::' + ds.uiname
|
271
|
-
tableName = "||#{refFieldTable}||"
|
272
|
-
# if @doGraph
|
273
|
-
tableNode = Twb::Util::Graphnode.new(name: tableName, id: tableID, type: :DBTable, properties: properties)
|
274
|
-
@nodes.add tableNode
|
275
|
-
fieldFieldEdge = Twb::Util::Graphedge.new(from: refFieldNode, to: tableNode, relationship: 'is a field in')
|
276
|
-
@edges.add fieldFieldEdge
|
277
|
-
# end
|
278
|
-
# fldToDsNode = tableNode
|
279
|
-
end
|
252
|
+
emit "# Calculated Fields: #{calculation.referencedFields.length}"
|
253
|
+
calculation.referencedFields.each do |rf|
|
254
|
+
emit " referenced field :: %12s %s " % [ rf.dataSourceName, rf.uiname ]
|
280
255
|
@csvFormulaFields << [
|
281
256
|
@referencedFieldsCount += 1,
|
282
257
|
@twb.name,
|
283
258
|
# @modTime,
|
284
|
-
ds.uiname,
|
259
|
+
rf.dataSourceName, # ds.uiname,
|
285
260
|
calcField.uiname,
|
286
261
|
calculation.formulaFlat,
|
287
262
|
calculation.formulaFlatResolved,
|
288
263
|
rf.name,
|
289
|
-
rf.uiname,
|
290
|
-
rf.id,
|
291
|
-
refFieldTable
|
264
|
+
rf.uiname, #.uiname,
|
265
|
+
'', # rf.id,
|
266
|
+
'', #refFieldTable
|
292
267
|
]
|
268
|
+
|
269
|
+
|
270
|
+
# emit " referenced field.name ::'#{rf.name.nil?}' :: '#{rf.name}'"
|
271
|
+
# emit " referenced field.uiname::'#{rf.uiname}'"
|
272
|
+
# if @doGraph
|
273
|
+
# unless rf.uiname.nil?
|
274
|
+
# properties = {'DataSource' => ds.uiname, 'DataSourceReference' => 'local', :source => rf}
|
275
|
+
# refFieldNode = Twb::Util::Graphnode.new(name: rf.uiname, id: rf.id, type: rf.type, properties: properties)
|
276
|
+
# @nodes.add refFieldNode
|
277
|
+
# fieldFieldEdge = Twb::Util::Graphedge.new(from: calcFieldNode, to: refFieldNode, relationship: 'references')
|
278
|
+
# @edges.add fieldFieldEdge
|
279
|
+
# end
|
280
|
+
# # end
|
281
|
+
# referencedFields.add rf.id
|
282
|
+
# refFieldTable = ds.fieldTable(rf.name)
|
283
|
+
# emit "refFieldTable.nil? : #{refFieldTable.nil?}"
|
284
|
+
# unless refFieldTable.nil?
|
285
|
+
# tableID = refFieldTable + ':::' + ds.uiname
|
286
|
+
# tableName = "||#{refFieldTable}||"
|
287
|
+
# # if @doGraph
|
288
|
+
# tableNode = Twb::Util::Graphnode.new(name: tableName, id: tableID, type: :DBTable, properties: properties)
|
289
|
+
# @nodes.add tableNode
|
290
|
+
# fieldFieldEdge = Twb::Util::Graphedge.new(from: refFieldNode, to: tableNode, relationship: 'is a field in')
|
291
|
+
# @edges.add fieldFieldEdge
|
292
|
+
# # end
|
293
|
+
# # fldToDsNode = tableNode
|
294
|
+
# end
|
295
|
+
# @csvFormulaFields << [
|
296
|
+
# @referencedFieldsCount += 1,
|
297
|
+
# @twb.name,
|
298
|
+
# # @modTime,
|
299
|
+
# ds.uiname,
|
300
|
+
# calcField.uiname,
|
301
|
+
# calculation.formulaFlat,
|
302
|
+
# calculation.formulaFlatResolved,
|
303
|
+
# rf.name,
|
304
|
+
# rf.uiname,
|
305
|
+
# rf.id,
|
306
|
+
# refFieldTable
|
307
|
+
# ]
|
293
308
|
end # resolvedFields.each do
|
294
309
|
end # if calculation.has_formula
|
295
310
|
end # ds.calculatedFields.each
|
data/lib/twb/calculatedfield.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2014, 2015,
|
1
|
+
# Copyright (C) 2014, 2015, 2020 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
|
@@ -26,7 +26,7 @@ module Twb
|
|
26
26
|
attr_reader :node, :properties
|
27
27
|
attr_reader :caption, :name, :uiname
|
28
28
|
attr_reader :datatype, :role, :propType
|
29
|
-
attr_reader :calculation, :
|
29
|
+
attr_reader :calculation, :referencedFields
|
30
30
|
attr_reader :isGroup, :groupMembers
|
31
31
|
attr_reader :hidden
|
32
32
|
|
@@ -52,8 +52,8 @@ module Twb
|
|
52
52
|
@properties ||= loadProperties
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
@calculation.
|
55
|
+
def referencedFields
|
56
|
+
@calculation.referencedFields
|
57
57
|
end
|
58
58
|
|
59
59
|
def formulaLines
|
data/lib/twb/columnfield.rb
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
16
|
require 'nokogiri'
|
17
|
+
require 'pry'
|
17
18
|
|
18
19
|
module Twb
|
19
20
|
|
@@ -85,7 +86,6 @@ module Twb
|
|
85
86
|
@aggregation = load 'aggregation'
|
86
87
|
@autoColumn = load 'auto-column'
|
87
88
|
@datatypeCustomized = load 'datatype-customized'
|
88
|
-
# @calcField = loadCalcField
|
89
89
|
end
|
90
90
|
|
91
91
|
def id
|
@@ -94,7 +94,7 @@ module Twb
|
|
94
94
|
|
95
95
|
def load nodeName
|
96
96
|
attr = @node.attribute(nodeName)
|
97
|
-
val = attr.nil? ? nil : attr.text.strip
|
97
|
+
val = attr.nil? ? nil : attr.text.strip
|
98
98
|
return val
|
99
99
|
end
|
100
100
|
|
data/lib/twb/datasource.rb
CHANGED
@@ -56,7 +56,7 @@ module Twb
|
|
56
56
|
attr_reader :tableFieldsMap
|
57
57
|
attr_reader :fieldUINames
|
58
58
|
attr_reader :aliases
|
59
|
-
attr_reader :calculatedFields, :
|
59
|
+
attr_reader :calculatedFields, :calculatedFieldsMap, :calculatedFieldNames, :calculatedField
|
60
60
|
attr_reader :allFields
|
61
61
|
attr_reader :groups
|
62
62
|
attr_reader :filters
|
@@ -391,40 +391,6 @@ module Twb
|
|
391
391
|
return @fieldUINames
|
392
392
|
end
|
393
393
|
|
394
|
-
def loadFieldUINames
|
395
|
-
# puts 'loadFieldUINames'
|
396
|
-
@fieldUINames = {}
|
397
|
-
# puts 'metadataFields'
|
398
|
-
metadataFields.each do |fld|
|
399
|
-
# puts " - name:%-45s | uiname:%-45s | localName:%-45s " % [ "'#{fld.name}'", "'#{fld.uiname}'", "'#{fld.localName}'"]
|
400
|
-
@fieldUINames[fld.uiname] = fld.uiname
|
401
|
-
@fieldUINames[fld.localName] = fld.uiname unless fld.localName.nil?
|
402
|
-
@fieldUINames[fld.name] = fld.uiname unless fld.name.nil?
|
403
|
-
end
|
404
|
-
# puts 'calculatedFields'
|
405
|
-
calculatedFields.each do |fld|
|
406
|
-
# puts " - name:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.uiname}'"]
|
407
|
-
@fieldUINames[fld.name] = fld.uiname
|
408
|
-
@fieldUINames[fld.uiname] = fld.uiname
|
409
|
-
end
|
410
|
-
# puts 'localFields'
|
411
|
-
localFields.each do |fld|
|
412
|
-
# puts " - name:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.uiname}'"]
|
413
|
-
@fieldUINames[fld.name] = fld.uiname
|
414
|
-
@fieldUINames[fld.uiname] = fld.uiname
|
415
|
-
end
|
416
|
-
# puts "columnFields: #{columnFields.length}"
|
417
|
-
columnFields.each do |fld|
|
418
|
-
@fieldUINames[fld.name] = fld.uiname
|
419
|
-
@fieldUINames[fld.uiname] = fld.uiname
|
420
|
-
end
|
421
|
-
groups.each do |fld|
|
422
|
-
@fieldUINames[fld.name] = fld.uiname
|
423
|
-
@fieldUINames[fld.uiname] = fld.uiname
|
424
|
-
end
|
425
|
-
return @fieldUINames
|
426
|
-
end
|
427
|
-
|
428
394
|
def tableFields
|
429
395
|
@tableFieldsMap.values
|
430
396
|
end
|
@@ -482,8 +448,7 @@ module Twb
|
|
482
448
|
|
483
449
|
def loadAllFields
|
484
450
|
@allFields = SortedSet.new
|
485
|
-
|
486
|
-
@allFields << dbf
|
451
|
+
@allFields << dbFields
|
487
452
|
@allFields << calculatedFieldNames
|
488
453
|
end
|
489
454
|
|
@@ -532,6 +497,53 @@ module Twb
|
|
532
497
|
|
533
498
|
private
|
534
499
|
|
500
|
+
def loadFieldUINames
|
501
|
+
@fieldUINames = {}
|
502
|
+
# puts"metadataFields: #{metadataFields.length}"
|
503
|
+
metadataFields.each do |fld|
|
504
|
+
# puts" - name:%-45s | caption:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.caption}'", "'#{fld.uiname}'"]
|
505
|
+
unless fld.name.nil?
|
506
|
+
@fieldUINames[fld.uiname] = fld.uiname
|
507
|
+
@fieldUINames[fld.localName] = fld.uiname unless fld.localName.nil?
|
508
|
+
@fieldUINames[fld.name] = fld.uiname
|
509
|
+
end
|
510
|
+
end
|
511
|
+
# puts"localFields: #{localFields.length}"
|
512
|
+
localFields.each do |fld|
|
513
|
+
# puts" - name:%-45s | caption:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.caption}'", "'#{fld.uiname}'"]
|
514
|
+
unless fld.caption.nil?
|
515
|
+
@fieldUINames[fld.name] = fld.caption
|
516
|
+
@fieldUINames[fld.uiname] = fld.caption
|
517
|
+
end
|
518
|
+
end
|
519
|
+
# puts"groups: #{groups.length}"
|
520
|
+
groups.each do |fld|
|
521
|
+
# puts" - name:%-45s | caption:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.caption}'", "'#{fld.uiname}'"]
|
522
|
+
unless fld.caption.nil?
|
523
|
+
@fieldUINames[fld.name] = fld.caption
|
524
|
+
@fieldUINames[fld.uiname] = fld.caption
|
525
|
+
end
|
526
|
+
end
|
527
|
+
# puts"calculatedFields: #{calculatedFields.length}"
|
528
|
+
calculatedFields.each do |fld|
|
529
|
+
# puts" - name:%-45s | caption:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.caption}'", "'#{fld.uiname}'"]
|
530
|
+
unless fld.caption.nil?
|
531
|
+
@fieldUINames[fld.name] = fld.caption
|
532
|
+
@fieldUINames[fld.uiname] = fld.caption
|
533
|
+
end
|
534
|
+
end
|
535
|
+
# puts"columnFields: #{columnFields.length}"
|
536
|
+
columnFields.each do |fld|
|
537
|
+
# puts" - name:%-45s | caption:%-45s | uiname:%-45s " % [ "'#{fld.name}'", "'#{fld.caption}'", "'#{fld.uiname}'"]
|
538
|
+
unless fld.caption.nil?
|
539
|
+
# @fieldUINames[fld.name] = fld.caption
|
540
|
+
@fieldUINames[fld.name.gsub(/^[\[]|[\]]$/,'')] = fld.caption
|
541
|
+
@fieldUINames[fld.uiname] = fld.caption
|
542
|
+
end
|
543
|
+
end
|
544
|
+
return @fieldUINames
|
545
|
+
end
|
546
|
+
|
535
547
|
def loadGroups
|
536
548
|
@groups = []
|
537
549
|
groupNodes = @node.xpath('.//group')
|
data/lib/twb/fieldcalculation.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
require 'nokogiri'
|
17
17
|
require 'digest/md5'
|
18
18
|
require 'csv'
|
19
|
+
require 'pry'
|
19
20
|
|
20
21
|
module Twb
|
21
22
|
|
@@ -35,7 +36,7 @@ module Twb
|
|
35
36
|
attr_reader :is_tableCalc
|
36
37
|
attr_reader :is_lod, :lodCodePos
|
37
38
|
attr_reader :class, :scopeIsolation
|
38
|
-
attr_reader :fields, :remoteFields,
|
39
|
+
attr_reader :fields, :remoteFields, :referencedFields
|
39
40
|
attr_reader :comments, :uuid
|
40
41
|
|
41
42
|
# attr_accessor :ttlogfile
|
@@ -120,59 +121,29 @@ module Twb
|
|
120
121
|
end
|
121
122
|
|
122
123
|
def formulaResolved
|
123
|
-
@formulaResolved ||=
|
124
|
+
@formulaResolved ||= resolveFormula
|
124
125
|
end
|
125
126
|
|
126
127
|
def resolveFormula
|
127
128
|
# puts "\ndef resolveFormula:\n--\n#{@formula}"
|
128
129
|
formula = @formula
|
129
|
-
parseFormFields # - extracts the fields from the formula; as persisted they're the internal names
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
130
|
+
# parseFormFields # - extracts the fields from the formula; as persisted they're the internal names
|
131
|
+
referencedFields.each do |calcField|
|
132
|
+
# if calcField.techUIdiff
|
133
|
+
# # puts ":::: #{calcField.techCode} // #{calcField.uiCode}"
|
134
|
+
# formula = formula.gsub(calcField.techCode,calcField.uiCode)
|
135
|
+
# # puts ":--: #{formula}"
|
136
|
+
# end
|
136
137
|
end
|
137
138
|
return formula
|
138
139
|
end
|
139
140
|
|
140
|
-
def
|
141
|
-
@
|
141
|
+
def referencedFields
|
142
|
+
@referencedFields ||= parseFormFields
|
142
143
|
end
|
143
144
|
|
144
|
-
def parseFormFields
|
145
|
-
# puts "--parseFormFields"
|
146
|
-
@fields = Set.new
|
147
|
-
@calcFields = Set.new
|
148
|
-
formula = @formulaFlat
|
149
|
-
if !formula.nil? && formula.include?('[') && formula.include?(']')
|
150
|
-
fields = Set.new
|
151
|
-
# noSqLits = formula.gsub( /'[\[\.\]]+'/, ' ')
|
152
|
-
quotes = formula.gsub('"',"'")
|
153
|
-
noSqLits = quotes.gsub( /'[\[\.\]]+'/, ' ')
|
154
|
-
flatForm = noSqLits.gsub( /\n/, ' ')
|
155
|
-
stripFrt = flatForm.gsub( /^[^\[]*[\[]/ , '[' )
|
156
|
-
stripBck = stripFrt.gsub( /\][^\]]+$/ , ']' )
|
157
|
-
stripMid = stripBck.gsub( /\][^\]]{2,}\[/ , ']]..[[' )
|
158
|
-
stripCom = stripMid.gsub( /\][ ]*,[ ]*\[/ , ']]..[[' )
|
159
|
-
stripFns = stripMid.gsub( /\][ ]*[\*\/+\-><,=][ ]*\[/ , ']]..[[' )
|
160
|
-
fields = stripFns.split(']..[')
|
161
|
-
emit "::self::: #{self} :: #{__LINE__} :: fields:'#{fields.inspect}'"
|
162
|
-
fields.each do |field|
|
163
|
-
emit "::self::: #{self} :: #{__LINE__} :: field:'#{field}'"
|
164
|
-
cf = CalculationField.new( field.gsub(/^\[|\]$/, ''), @dataSource )
|
165
|
-
@calcFields.add cf
|
166
|
-
@fields.add field.gsub(/^\[|\]$/, '')
|
167
|
-
end
|
168
|
-
end
|
169
|
-
return @calcFields
|
170
|
-
end
|
171
145
|
|
172
146
|
def formulaResolvedLines
|
173
|
-
# puts "\ndef formulaResolvedLines\n--\n#{formulaResolved}"
|
174
|
-
# puts "--\n#{formulaResolved.split(/\n|\r\n/)}"
|
175
|
-
# puts "--\n#{formulaResolved.split(/\n|\r\n/)}"
|
176
147
|
formulaResolved.split(/\n|\r\n/)
|
177
148
|
end
|
178
149
|
|
@@ -212,11 +183,149 @@ module Twb
|
|
212
183
|
return comments.strip
|
213
184
|
end
|
214
185
|
|
215
|
-
|
186
|
+
private
|
216
187
|
|
217
188
|
|
189
|
+
def pullString chars
|
190
|
+
delim1 = chars.shift
|
191
|
+
delim2 = delim1+delim1
|
192
|
+
field = delim1
|
193
|
+
done = false
|
194
|
+
until done | chars.empty?
|
195
|
+
s01 = chars[0..1].join
|
196
|
+
if !delim1.eql? chars[0]
|
197
|
+
field += chars.shift
|
198
|
+
else
|
199
|
+
case s01
|
200
|
+
when delim2
|
201
|
+
field += delim2
|
202
|
+
chars.shift(2)
|
203
|
+
when delim1
|
204
|
+
field += delim1
|
205
|
+
chars.shift
|
206
|
+
done = true
|
207
|
+
else
|
208
|
+
field += delim1
|
209
|
+
chars.shift
|
210
|
+
done = true
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def pullField chars
|
217
|
+
# chars = str.split ''
|
218
|
+
done = false
|
219
|
+
ds = ''
|
220
|
+
field = ''
|
221
|
+
until done
|
222
|
+
s01 = chars[0..1].join
|
223
|
+
s02 = chars[0..2].join
|
224
|
+
if ']'.eql? chars[0]
|
225
|
+
case s01
|
226
|
+
when ']]'
|
227
|
+
field += ']]'
|
228
|
+
chars.shift(2)
|
229
|
+
when ']'
|
230
|
+
field += chars.shift
|
231
|
+
done = true
|
232
|
+
else
|
233
|
+
if '].['.eql?(s02)
|
234
|
+
ds = field + ']'
|
235
|
+
chars.shift(2)
|
236
|
+
# fldstr = chars.join
|
237
|
+
field = pullField(chars)[:field]
|
238
|
+
done = true
|
239
|
+
else
|
240
|
+
field += ']'
|
241
|
+
chars.shift
|
242
|
+
done = true
|
243
|
+
end
|
244
|
+
end
|
245
|
+
else
|
246
|
+
field += chars[0]
|
247
|
+
chars.shift
|
248
|
+
end
|
249
|
+
end
|
250
|
+
# puts "field: '#{field}' \t\t ds: #{ds}"
|
251
|
+
return {:field => field.sub(/\[/,'').sub(/\]$/,''), :ds => ds.sub(/\[/,'').sub(/\]$/,'') }
|
252
|
+
end
|
218
253
|
|
219
|
-
|
254
|
+
def parseFormFields # formula
|
255
|
+
@referencedFields = Array.new
|
256
|
+
rawFields = Array.new
|
257
|
+
if !@formula.nil? && @formula.include?('[') && @formula.include?(']')
|
258
|
+
chars = formula.split('')
|
259
|
+
until chars.empty?
|
260
|
+
char0 = chars[0]
|
261
|
+
case char0
|
262
|
+
when '"', "'"
|
263
|
+
pullString(chars)
|
264
|
+
when '['
|
265
|
+
rawFields << pullField(chars)
|
266
|
+
else
|
267
|
+
unless chars.nil? | chars.empty?
|
268
|
+
chars.shift
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
rawFields.each do |rf|
|
273
|
+
ds = rf[:ds]
|
274
|
+
dataSource = if ''.eql? ds
|
275
|
+
@dataSource
|
276
|
+
else
|
277
|
+
@dataSource.workbook.datasource(ds)
|
278
|
+
end
|
279
|
+
# fieldUIName = dataSource.fieldUIName(rf[:field])
|
280
|
+
refField = ReferencedField.new(rf[:field], dataSource)
|
281
|
+
@referencedFields << refField
|
282
|
+
end
|
283
|
+
end
|
284
|
+
return @referencedFields
|
285
|
+
end
|
286
|
+
|
287
|
+
def parseFormFieldsx # formula
|
288
|
+
rawFields = Set.new
|
289
|
+
if !@formula.nil? && @formula.include?('[') && @formula.include?(']')
|
290
|
+
noComms = @formula.gsub(/\/\/.*\r\n/,' ')
|
291
|
+
formBase = noComms.gsub(/\r\n/,' ')
|
292
|
+
formLen = formBase.length
|
293
|
+
formChars = formBase.split ''
|
294
|
+
until formChars.empty?
|
295
|
+
c = formChars.shift
|
296
|
+
case c
|
297
|
+
when '"', "'"
|
298
|
+
pullString(formChars, c)
|
299
|
+
when '['
|
300
|
+
rawFields << pullField(formChars, ']', @referencedFields)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
@referencedFields = Set.new
|
305
|
+
rawFields.each do |rf|
|
306
|
+
# @referencedFields << rf
|
307
|
+
dataSource = if ''.eql? rf[:ds]
|
308
|
+
@dataSource
|
309
|
+
else
|
310
|
+
@dataSource.workbook.datasource(rf[:ds])
|
311
|
+
end
|
312
|
+
# if dataSource.nil?
|
313
|
+
# binding.pry
|
314
|
+
# end
|
315
|
+
fieldUIName = dataSource.fieldUIName(rf[:field])
|
316
|
+
# binding.pry
|
317
|
+
refField = ReferencedField.new(rf[:field], dataSource)
|
318
|
+
# binding.pry
|
319
|
+
@referencedFields << refField
|
320
|
+
end
|
321
|
+
return @referencedFields
|
322
|
+
end
|
323
|
+
|
324
|
+
end # class FieldCalculation
|
325
|
+
|
326
|
+
|
327
|
+
# class CalculationField
|
328
|
+
class ReferencedField
|
220
329
|
# is a field used in a calculation, resolved into its human-meaningful form
|
221
330
|
|
222
331
|
include Comparable
|
@@ -228,65 +337,29 @@ module Twb
|
|
228
337
|
attr_reader :fqName, :type
|
229
338
|
attr_reader :techUIdiff
|
230
339
|
|
231
|
-
def initialize
|
232
|
-
# puts "\n\
|
340
|
+
def initialize name, datasource
|
341
|
+
# puts "\n\nReferencedField :: ds: %-25s | n: %s " % [datasource, name]
|
342
|
+
@name = name
|
233
343
|
@dataSource = datasource
|
234
|
-
@dataSourceName = datasource.uiname
|
344
|
+
@dataSourceName = datasource.nil? ? nil : datasource.uiname
|
235
345
|
@dataSourceRef = :local
|
236
346
|
@dataSourceExists = true
|
347
|
+
@techCode = "[#{name}]"
|
237
348
|
@techUIdiff = false
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
#puts "@name
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
else # !datasource.nil?
|
252
|
-
# puts 'b'
|
253
|
-
#puts "b - found uiname for '#{@name}'?: #{!datasource.fieldUIName(@name).nil?} \t is:#{datasource.fieldUIName(@name)} "
|
254
|
-
@uiname = datasource.fieldUIName(@name).nil? ? @name : datasource.fieldUIName(@name)
|
255
|
-
@uiCode = @uiname.nil? ? @techCode : "[#{@uiname}]"
|
256
|
-
@techUIdiff = !@techCode.eql?(@uiCode)
|
257
|
-
# puts ":b #{datasource.fieldUIName(@name).nil?} ... #{@name} ... #{@uiname}"
|
258
|
-
# puts "CalculationField :: uin: %-25s | @name:%-s" % [@uiname,@name]
|
259
|
-
end
|
260
|
-
else # parts.length <> 1
|
261
|
-
# puts 'c'
|
262
|
-
rdstech = parts[0]
|
263
|
-
calcField = parts[1]
|
264
|
-
@uiname = calcField
|
265
|
-
@dataSourceName = rdstech
|
266
|
-
@dataSourceRef = :remote
|
267
|
-
@techCode = "[#{rdstech}].[#{calcField}]"
|
268
|
-
workbook = datasource.workbook
|
269
|
-
@dataSource = workbook.nil? ? nil : workbook.datasource(rdstech)
|
270
|
-
# puts "\t twb: #{workbook.class} / remoteds: #{remoteds.class} : #{remoteds.nil? ? "<<NOT FOUND:#{rdstech}:>>" : remoteds.uiname} "
|
271
|
-
#--
|
272
|
-
if @dataSource.nil? || @dataSource.fieldUIName(calcField).nil?
|
273
|
-
# puts 'd'
|
274
|
-
@uiname = calcField
|
275
|
-
@uiCode = "[<<NOT FOUND>>#{rdstech}].[#{calcField}]"
|
276
|
-
@techUIdiff = true
|
277
|
-
@dataSourceExists = false
|
278
|
-
else # !remoteds.nil?
|
279
|
-
# puts 'e'
|
280
|
-
@dataSourceName = @dataSource.uiname
|
281
|
-
@uiname = @dataSource.fieldUIName(calcField)
|
282
|
-
@uiCode = "[#{@dataSourceName}].[#{@uiname}]"
|
283
|
-
@techUIdiff = !@techCode.eql?(@uiCode)
|
284
|
-
@dataSourceExists = true
|
285
|
-
end
|
349
|
+
if dataSource.nil?
|
350
|
+
# puts 'a'
|
351
|
+
@uiname = @name
|
352
|
+
@uiCode = @techCode
|
353
|
+
@techUIdiff = false
|
354
|
+
else # !datasource.nil?
|
355
|
+
# puts 'b'
|
356
|
+
# puts "b - found uiname for '#{@name}'?: #{!datasource.fieldUIName(@name).nil?} \t is:#{datasource.fieldUIName(@name)} "
|
357
|
+
@uiname = datasource.fieldUIName(@name).nil? ? @name : datasource.fieldUIName(@name)
|
358
|
+
@uiCode = @uiname.nil? ? @techCode : "[#{@uiname}]"
|
359
|
+
@techUIdiff = !@techCode.eql?(@uiCode)
|
360
|
+
# puts ":b #{datasource.fieldUIName(@name).nil?} ... #{@name} ... #{@uiname}"
|
361
|
+
# puts "CalculationField :: uin: %-25s | @name:%-s" % [@uiname,@name]
|
286
362
|
end
|
287
|
-
# puts "\t dsName: #{@dataSourceName}"
|
288
|
-
# puts "\t @name: #{@name}"
|
289
|
-
# puts "\t uiname: #{@uiname}"
|
290
363
|
@fqName = "#{@dataSourceName}::#{@uiname}"
|
291
364
|
@type = if @dataSource.nil?
|
292
365
|
:CalculatedField
|
@@ -308,6 +381,6 @@ module Twb
|
|
308
381
|
@fqName <=> other.fqName
|
309
382
|
end
|
310
383
|
|
311
|
-
end # class
|
384
|
+
end # class ReferencedField
|
312
385
|
|
313
386
|
end # module Twb
|
@@ -16,7 +16,9 @@
|
|
16
16
|
require 'nokogiri'
|
17
17
|
|
18
18
|
#require 'twb'
|
19
|
-
require 'C:\tech\Tableau\tools\Ruby\gems\twb\lib\twb.rb'
|
19
|
+
# require 'C:\tech\Tableau\tools\Ruby\gems\twb\lib\twb.rb'
|
20
|
+
# require 'C:\tech\Tableau\Tableau Tools\Ruby\gems\twb\lib\twb.rb'
|
21
|
+
require 'twb'
|
20
22
|
require "test/unit"
|
21
23
|
|
22
24
|
system "cls"
|
@@ -25,10 +27,11 @@ class TestFieldCalculation < Test::Unit::TestCase
|
|
25
27
|
|
26
28
|
def test_fragment1
|
27
29
|
doc = Nokogiri::XML::Document.parse <<-EOHTML
|
28
|
-
<calculation class='tableau' formula='abc' />
|
30
|
+
<calculation class='tableau' name='I am a formular field' formula='abc' datatype='datatype' role='' type='' class='calcfield' />
|
29
31
|
EOHTML
|
30
|
-
calcNode
|
31
|
-
|
32
|
+
calcNode = doc.at_xpath('./calculation')
|
33
|
+
calcField = Twb::CalculatedField.new calcNode
|
34
|
+
calc = Twb::FieldCalculation.new(calcField)
|
32
35
|
assert(!calc.nil?)
|
33
36
|
#puts "node: #{calcNode}"
|
34
37
|
#puts "formula: #{calc.formula}"
|
@@ -41,10 +44,11 @@ EOHTML
|
|
41
44
|
|
42
45
|
def test_fragment2
|
43
46
|
doc = Nokogiri::XML::Document.parse <<-EOHTML
|
44
|
-
<calculation class='tableau' formula='// this is the number of days between the order and shipment datediff('day',[Order Date] , [other].[Ship Date])' />
|
47
|
+
<calculation class='tableau' name='Another formula fied' formula='// this is the number of days between the order and shipment datediff('day',[Order Date] , [other].[Ship Date])' />
|
45
48
|
EOHTML
|
46
49
|
calcNode = doc.at_xpath('./calculation')
|
47
|
-
|
50
|
+
calcField = Twb::CalculatedField calcNode
|
51
|
+
calc = Twb::FieldCalculation.new(calcField)
|
48
52
|
assert(!calc.nil?)
|
49
53
|
#puts "node: #{calcNode}"
|
50
54
|
#puts "formula: #{calc.formula}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Gerrard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05
|
11
|
+
date: 2020-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: creek
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/twb/analysis/calculatedfields/fieldsaliasesanalyzer.rb
|
68
68
|
- lib/twb/analysis/calculatedfields/groupfieldsanalyzer.rb
|
69
69
|
- lib/twb/analysis/calculatedfields/markdownemitter.rb
|
70
|
+
- lib/twb/analysis/calculatedfields/t.rb
|
70
71
|
- lib/twb/analysis/datasources/categoricalcolorcodinganalyzer.rb
|
71
72
|
- lib/twb/analysis/datasources/datasourcefieldsanalyzer.rb
|
72
73
|
- lib/twb/analysis/datasources/datasourcefieldscsvemitter.rb
|