Class: Twb::DataSource
- Inherits:
-
Object
- Object
- Twb::DataSource
- Defined in:
- lib/twb/datasource.rb
Constant Summary collapse
- @@hasher =
Digest::SHA256.new
- @@connGNodeParamsJSON =
%q( { "csv" : { "label" : ["filename"], "id" : ["directory","filename"], "type" : "CSV" }, "excel" : { "label" : ["filename"], "id" : ["directory","filename"], "type" : "Excel" }, "dataengine" : { "label" : ["dbname" ], "id" : ["directory","filename"], "type" : "TDE" }, "msaccess" : { "label" : ["filename"], "id" : ["directory","filename"], "type" : "MS Access" }, "oracle" : { "label" : ["server" ], "id" : [ "server" ], "type" : "Oracle" }, "postgres" : { "label" : ["server" ], "id" : [ "server" ], "type" : "PostgreSQL" }, "textscan" : { "label" : ["filename"], "id" : ["directory","filename"], "type" : "CSV / TSV" }, "excel-direct" : { "label" : ["filename"], "id" : [ "filename"], "type" : "Excel" }, "salesforce" : { "label" : ["server" ], "id" : [ "server" ], "type" : "Salesforce" } } )
- @@cgNodeParams =
JSON.parse @@connGNodeParamsJSON
Instance Attribute Summary collapse
-
#allFields ⇒ Object
readonly
Returns the value of attribute allFields.
-
#calculatedField(name) ⇒ Object
readonly
Returns the value of attribute calculatedField.
-
#calculatedFieldNames ⇒ Object
readonly
Returns the value of attribute calculatedFieldNames.
-
#calculatedFieldNamesMap ⇒ Object
readonly
Returns the value of attribute calculatedFieldNamesMap.
-
#calculatedFields ⇒ Object
readonly
Returns the value of attribute calculatedFields.
-
#caption ⇒ Object
readonly
Returns the value of attribute caption.
-
#columnFields ⇒ Object
readonly
Returns the value of attribute columnFields.
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#connHash ⇒ Object
readonly
Returns the value of attribute connHash.
-
#dbFields ⇒ Object
readonly
Returns the value of attribute dbFields.
-
#dsclass ⇒ Object
readonly
Returns the value of attribute dsclass.
-
#fieldUINames ⇒ Object
readonly
Returns the value of attribute fieldUINames.
-
#filters ⇒ Object
readonly
Returns the value of attribute filters.
-
#hasField ⇒ Object
readonly
Returns the value of attribute hasField.
-
#isExtract ⇒ Object
readonly
Returns the value of attribute isExtract.
-
#joinPairs ⇒ Object
readonly
Returns the value of attribute joinPairs.
-
#localField ⇒ Object
readonly
Returns the value of attribute localField.
-
#localFieldNames ⇒ Object
readonly
Returns the value of attribute localFieldNames.
-
#localFields ⇒ Object
readonly
Returns the value of attribute localFields.
-
#mappedFields ⇒ Object
readonly
Returns the value of attribute mappedFields.
-
#metadataFields ⇒ Object
readonly
Returns the value of attribute metadataFields.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#node ⇒ Object
readonly
Returns the value of attribute node.
-
#tables ⇒ Object
readonly
Returns the value of attribute tables.
-
#uiname ⇒ Object
readonly
Returns the value of attribute uiname.
-
#workbook ⇒ Object
readonly
Returns the value of attribute workbook.
Instance Method Summary collapse
-
#calculatedFieldsMap ⇒ Object
NOTE: Calculated Fields are mapped by their UI name.
- #fieldTable(fieldName) ⇒ Object
- #fieldUIName(fieldName) ⇒ Object
- #has_field?(fieldName) ⇒ Boolean
-
#initialize(dataSourceNode, workbook) ⇒ DataSource
constructor
A new instance of DataSource.
- #joinTree ⇒ Object
- #loadCalculatedFields ⇒ Object
- #loadColumnFields ⇒ Object
- #loadFieldUINames ⇒ Object
- #loadJoinPairs ⇒ Object
- #loadJoinTree ⇒ Object
- #loadLocalFields ⇒ Object
- #loadMetadataFields ⇒ Object
-
#loadTableFields ⇒ Object
fields are unique in the data source by UI name.
- #loadTables(connection) ⇒ Object
- #Parameters? ⇒ Boolean
- #processConnection ⇒ Object
- #processFilters ⇒ Object
- #pullTable(xml) ⇒ Object
-
#setConnectionHash ⇒ Object
Notes: - TODO: need to determine which, if any, of the connection attributes should be included in the hash in order to identify it unambiguously - without local values that obscure the data source’s ‘real’ identity - attributes with value ” don’t contribute to the hash.
- #tableauVersion ⇒ Object
- #updateTime ⇒ Object
Constructor Details
#initialize(dataSourceNode, workbook) ⇒ DataSource
Returns a new instance of DataSource.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/twb/datasource.rb', line 57 def initialize dataSourceNode, workbook @node = dataSourceNode @workbook = workbook @name = @node.attr('name') @caption = @node.attr('caption') @uiname = if @caption.nil? || @caption == '' then @name else @caption end processConnection processFilters loadTableFields return self end |
Instance Attribute Details
#allFields ⇒ Object (readonly)
Returns the value of attribute allFields.
53 54 55 |
# File 'lib/twb/datasource.rb', line 53 def allFields @allFields end |
#calculatedField(name) ⇒ Object (readonly)
Returns the value of attribute calculatedField.
52 53 54 |
# File 'lib/twb/datasource.rb', line 52 def calculatedField @calculatedField end |
#calculatedFieldNames ⇒ Object (readonly)
Returns the value of attribute calculatedFieldNames.
52 53 54 |
# File 'lib/twb/datasource.rb', line 52 def calculatedFieldNames @calculatedFieldNames end |
#calculatedFieldNamesMap ⇒ Object (readonly)
Returns the value of attribute calculatedFieldNamesMap.
52 53 54 |
# File 'lib/twb/datasource.rb', line 52 def calculatedFieldNamesMap @calculatedFieldNamesMap end |
#calculatedFields ⇒ Object (readonly)
Returns the value of attribute calculatedFields.
52 53 54 |
# File 'lib/twb/datasource.rb', line 52 def calculatedFields @calculatedFields end |
#caption ⇒ Object (readonly)
Returns the value of attribute caption.
42 43 44 |
# File 'lib/twb/datasource.rb', line 42 def caption @caption end |
#columnFields ⇒ Object (readonly)
Returns the value of attribute columnFields.
47 48 49 |
# File 'lib/twb/datasource.rb', line 47 def columnFields @columnFields end |
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
44 45 46 |
# File 'lib/twb/datasource.rb', line 44 def connection @connection end |
#connHash ⇒ Object (readonly)
Returns the value of attribute connHash.
44 45 46 |
# File 'lib/twb/datasource.rb', line 44 def connHash @connHash end |
#dbFields ⇒ Object (readonly)
Returns the value of attribute dbFields.
49 50 51 |
# File 'lib/twb/datasource.rb', line 49 def dbFields @dbFields end |
#dsclass ⇒ Object (readonly)
Returns the value of attribute dsclass.
43 44 45 |
# File 'lib/twb/datasource.rb', line 43 def dsclass @dsclass end |
#fieldUINames ⇒ Object (readonly)
Returns the value of attribute fieldUINames.
51 52 53 |
# File 'lib/twb/datasource.rb', line 51 def fieldUINames @fieldUINames end |
#filters ⇒ Object (readonly)
Returns the value of attribute filters.
54 55 56 |
# File 'lib/twb/datasource.rb', line 54 def filters @filters end |
#hasField ⇒ Object (readonly)
Returns the value of attribute hasField.
46 47 48 |
# File 'lib/twb/datasource.rb', line 46 def hasField @hasField end |
#isExtract ⇒ Object (readonly)
Returns the value of attribute isExtract.
43 44 45 |
# File 'lib/twb/datasource.rb', line 43 def isExtract @isExtract end |
#joinPairs ⇒ Object (readonly)
Returns the value of attribute joinPairs.
45 46 47 |
# File 'lib/twb/datasource.rb', line 45 def joinPairs @joinPairs end |
#localField ⇒ Object (readonly)
Returns the value of attribute localField.
46 47 48 |
# File 'lib/twb/datasource.rb', line 46 def localField @localField end |
#localFieldNames ⇒ Object (readonly)
Returns the value of attribute localFieldNames.
46 47 48 |
# File 'lib/twb/datasource.rb', line 46 def localFieldNames @localFieldNames end |
#localFields ⇒ Object (readonly)
Returns the value of attribute localFields.
46 47 48 |
# File 'lib/twb/datasource.rb', line 46 def localFields @localFields end |
#mappedFields ⇒ Object (readonly)
Returns the value of attribute mappedFields.
50 51 52 |
# File 'lib/twb/datasource.rb', line 50 def mappedFields @mappedFields end |
#metadataFields ⇒ Object (readonly)
Returns the value of attribute metadataFields.
48 49 50 |
# File 'lib/twb/datasource.rb', line 48 def @metadataFields end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
42 43 44 |
# File 'lib/twb/datasource.rb', line 42 def name @name end |
#node ⇒ Object (readonly)
Returns the value of attribute node.
55 56 57 |
# File 'lib/twb/datasource.rb', line 55 def node @node end |
#tables ⇒ Object (readonly)
Returns the value of attribute tables.
45 46 47 |
# File 'lib/twb/datasource.rb', line 45 def tables @tables end |
#uiname ⇒ Object (readonly)
Returns the value of attribute uiname.
42 43 44 |
# File 'lib/twb/datasource.rb', line 42 def uiname @uiname end |
#workbook ⇒ Object (readonly)
Returns the value of attribute workbook.
41 42 43 |
# File 'lib/twb/datasource.rb', line 41 def workbook @workbook end |
Instance Method Details
#calculatedFieldsMap ⇒ Object
NOTE: Calculated Fields are mapped by their UI name
265 266 267 |
# File 'lib/twb/datasource.rb', line 265 def calculatedFieldsMap @calculatedFieldsMap ||= loadCalculatedFields end |
#fieldTable(fieldName) ⇒ Object
305 306 307 308 309 |
# File 'lib/twb/datasource.rb', line 305 def fieldTable fieldName loadTableFields if @mappedFields.nil? tf = @mappedFields[fieldName] return tf.nil? ? nil : tf['table'] end |
#fieldUIName(fieldName) ⇒ Object
225 226 227 228 |
# File 'lib/twb/datasource.rb', line 225 def fieldUIName fieldName loadFieldUINames if @fieldUINames.nil? @fieldUINames[fieldName] end |
#has_field?(fieldName) ⇒ Boolean
301 302 303 |
# File 'lib/twb/datasource.rb', line 301 def has_field? fieldName dbFields.has_key? fieldName end |
#joinTree ⇒ Object
129 130 131 |
# File 'lib/twb/datasource.rb', line 129 def joinTree @joinTree ||= loadJoinTree end |
#loadCalculatedFields ⇒ Object
284 285 286 287 288 289 290 291 292 |
# File 'lib/twb/datasource.rb', line 284 def loadCalculatedFields @calculatedFieldsMap = {} cfnodes = @node.xpath("./column[calculation]") cfnodes.each do |node| calcField = Twb::CalculatedField.new node, self @calculatedFieldsMap[calcField.uiname] = calcField end return @calculatedFieldsMap end |
#loadColumnFields ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/twb/datasource.rb', line 162 def loadColumnFields @columnFields = Set.new nodes = @node.xpath('./column') nodes.each do |n| field = Twb::ColumnField.new n @columnFields << field end return @columnFields end |
#loadFieldUINames ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/twb/datasource.rb', line 235 def loadFieldUINames @fieldUINames = {} columnNodes = @node.xpath('./column') columnNodes.each do |cn| name = cn.attribute('name').text.gsub(/^\[|\]$/,'') caption = cn.attribute('caption') uiName = caption.nil? ? name : caption.text @fieldUINames[name] = uiName @fieldUINames[caption.text] = caption.text unless caption.nil? # in case of unintended usage: lookup by Caption name end mappedFields.each do |fname,fmap| dbTable = fmap['table'] dbName = fmap['dbName'] @fieldUINames[dbName] = fname unless @fieldUINames.include?(dbName) @fieldUINames[fname] = fname unless @fieldUINames.include?(fname) end end |
#loadJoinPairs ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/twb/datasource.rb', line 118 def loadJoinPairs @joinPairs = Set.new mainJoin = @node.xpath("./connection/relation[@type='join']") clauses = @node.xpath(".//relation[@type='join']/clause") clauses.each do |clause| leafs = clause.xpath('.//expression[not(node())]') @joinPairs << [ pullTable(leafs[0]) , pullTable(leafs[1]) ] end return @joinPairs end |
#loadJoinTree ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/twb/datasource.rb', line 133 def loadJoinTree loadJoinPairs if @joinPairs.nil? # puts "LJT::#{@uiname}::joinPairs:: #{@joinPairs.inspect}" # @joinPairs.each { |jp| puts "JP::#{jp}" } @joinTree = JoinTree.new(@name) @joinPairs.each do |from,to| # puts "from:#{from} -> to:#{to}" tableFrom = JoinTable.new(from) tableTo = JoinTable.new(to) @joinTree.add(tableFrom, tableTo) end # puts '---' return @joinTree end |
#loadLocalFields ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/twb/datasource.rb', line 176 def loadLocalFields @localFields = {} unless @connection.nil? # Parameters has no connection node, & no local fields connClass = @node.at_xpath('./connection').attribute('class').text fxpath = case connClass when 'dataengine' then './column' when 'sqlserver' then './column' else './connection/relation/columns/column' end nodes = @node.xpath(fxpath) nodes.each do |node| field = Twb::LocalField.new(node) @localFields[field.name] = field end end return @localFields end |
#loadMetadataFields ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/twb/datasource.rb', line 198 def loadMetadataFields @metadataFields = Set.new unless @connection.nil? # Parameters has no connection node, & no metadata fields # nodes = @node.xpath(".//metadata-record[@class='column']") # # note: there are other nodes "<metadata-record class='capability'>" whose nature is unclear # # these nodes have no value for their <name node, so are not loaded nodes = @node.xpath('./connection//metadata-record') nodes.each do |node| field = Twb::MetadataField.new(node) field.source = :db @metadataFields << field end nodes = @node.xpath('./extract//metadata-record') nodes.each do |node| field = Twb::MetadataField.new(node) field.source = :extract @metadataFields << field end end return @metadataFields end |
#loadTableFields ⇒ Object
fields are unique in the data source by UI name
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/twb/datasource.rb', line 312 def loadTableFields # puts "DATA SOURCE FIELD TABLE LOAD" @mappedFields = {} fieldNodes = @node.xpath('./connection/cols/map') fieldNodes.each do |fn| uiName = fn.attribute('key').text.gsub(/^\[|\]$/,'') fldRef = fn.attribute('value').text.gsub(/^\[|\]$/,'') parts = fldRef.split('].[') table = parts[0] dbName = parts[1] @mappedFields[uiName] = {'table' => table, 'dbName' => dbName} # puts "=== #{uiName} :: T=#{@mappedFields[uiName]['table']} DBN=#{@mappedFields[uiName]['dbName']} " end relTableNodes = @node.xpath('.//relation[@table]') relTableNodes.each do |relNode| table = relNode.attribute('name').text cols = relNode.xpath('./columns/column') cols.each do |col| fldName = col.attribute('name') @mappedFields[fldName.text] = {'table' => table, 'dbName' => @uiname} unless fldName.nil? end end end |
#loadTables(connection) ⇒ Object
106 107 108 109 110 111 112 |
# File 'lib/twb/datasource.rb', line 106 def loadTables connection @tables = {} nodes = connection.xpath(".//relation[@type='table']") nodes.each do |node| @tables[node.attr('name')] = node.attr('table') end end |
#Parameters? ⇒ Boolean
154 155 156 |
# File 'lib/twb/datasource.rb', line 154 def Parameters? 'Parameters'.eql? @name end |
#processConnection ⇒ Object
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/twb/datasource.rb', line 77 def processConnection @connection = @node.at_xpath('./connection') @dsclass = @name # handles 'Parameters' data source, which has no connection element (& others if so) unless @connection.nil? @dsclass = @connection.attribute('class').text # note: must use "dsclass" as "class" would override Rubys ".class" Kernel method setConnectionHash loadTables @connection end end |
#processFilters ⇒ Object
begin
<filter class='categorical' column='[enforcement_type]' filter-group='2'>
<groupfilter function='member' level='[enforcement_type]' member='"towing"' user:ui-domain='database' user:ui-enumeration='inclusive' user:ui-marker='enumerate' />
</filter>
end
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/twb/datasource.rb', line 341 def processFilters if @filters.nil? @filters = {} fnodes = @node.xpath('./filter') fnodes.each do |fn| columnN = fn.attribute('column') unless columnN.nil? memberNodes = fn.xpath('.//groupfilter/@member') unless memberNodes.nil? members = [] memberNodes.each do |m| members.push m.text end @filters[columnN.text] = members end end end end end |
#pullTable(xml) ⇒ Object
148 149 150 151 |
# File 'lib/twb/datasource.rb', line 148 def pullTable xml code =xml.attribute('op').text table = code.split('].[')[0][1..-1] end |
#setConnectionHash ⇒ Object
Notes:
- TODO: need to determine which, if any, of the connection attributes should be
included in the hash in order to identify it unambiguously - without
local values that obscure the data source's 'real' identity
- attributes with value '' don't contribute to the hash
93 94 95 96 97 98 99 100 |
# File 'lib/twb/datasource.rb', line 93 def setConnectionHash dsAttributes = @node.xpath('./connection/@*') dsConnStr = '' dsAttributes.each do |attr| dsConnStr += attr.text end @connHash = Digest::MD5.hexdigest(dsConnStr) end |
#tableauVersion ⇒ Object
69 70 71 |
# File 'lib/twb/datasource.rb', line 69 def tableauVersion tabVersion @tableauVersion = tabVersion end |
#updateTime ⇒ Object
220 221 222 223 |
# File 'lib/twb/datasource.rb', line 220 def updateTime attr = @node.xpath('.//@update-time').first @updateTime = attr.nil? ? nil : attr.value end |