class Twb::DataSource

Attributes

aliases[R]
allFields[R]
attributes[R]
calculatedField[R]
calculatedFieldNames[R]
calculatedFields[R]
calculatedFieldsMap[R]
caption[R]
columnFields[R]
connAttributes[R]
connHash[R]
connection[R]
connections[R]
dbFields[R]
dsclass[R]
fieldUINames[R]
filters[R]
groups[R]
hasField[R]
isExtract[R]
isPublished[R]
joinPairs[R]
localField[R]
localFieldNames[R]
localFields[R]
mappedFields[R]
metadataFields[R]
name[R]
node[R]
tableFieldsMap[R]
tables[R]
uiname[R]
uuid[R]
workbook[R]

Public Class Methods

new(dataSourceNode, workbook) click to toggle source
# File lib/twb/datasource.rb, line 65
def initialize dataSourceNode, workbook
  @node     = dataSourceNode
  @workbook = workbook 
  @name     = @node.attr('name')
  @caption  = @node.attr('caption')
  @uiname   = @caption.nil? ? @name : @caption
  # puts "DATASOURCE: #{@uiname}"
  # processConnection
  # processFilters
  loadTableFields
  loadFieldUINames
  return self
end

Public Instance Methods

Parameters?() click to toggle source
# File lib/twb/datasource.rb, line 234
def Parameters?
  'Parameters'.eql? @name 
end
columnField(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 238
def columnField fieldName
  loadColumnFields if @columnFieldsMap.nil?
  @columnFieldsMap[ fieldName ]
end
columnFieldsMap() click to toggle source
# File lib/twb/datasource.rb, line 248
def columnFieldsMap
  loadColumnFields if @columnFieldsMap.nil?
  return @columnFieldsMap
end
dbFieldsMap() click to toggle source
# File lib/twb/datasource.rb, line 410
def dbFieldsMap
  @tableFieldsMap
end
deAlias(fieldName, fAlias) click to toggle source
# File lib/twb/datasource.rb, line 336
def deAlias fieldName, fAlias
  fldAliases = aliases[fieldName]
  return fAlias if fldAliases.nil?
  dbFieldValue = fldAliases.key(fAlias)
  dbFieldValue.nil? ? fAlias : dbFieldValue
end
field(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 473
def field fieldName
  dbFieldsMap[fieldName]
end
fieldAlias(fieldName, value) click to toggle source
# File lib/twb/datasource.rb, line 328
def fieldAlias fieldName, value
  emit "fieldAlias:  #{fieldName.class}  -> #{value.class}" 
  loadAliases  if @aliases.nil?
  return value if @aliases.nil? || @aliases[fieldName].nil? # unless fieldHasAliases(fieldName)
  fldAlias = @aliases[fieldName][value]
  fldAlias.nil? ? value : fldAlias
end
fieldAliases(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 324
def fieldAliases fieldName
  aliases[fieldName]
end
fieldHasAliases(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 320
def fieldHasAliases fieldName
  !aliases[fieldName].nil?
end
fieldTable(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 477
def fieldTable fieldName
  loadTableFields if @tableFieldsMap.nil?
  dbField = @tableFieldsMap[fieldName]
  return dbField.nil? ? nil : dbField.dbtable
end
fieldUIName(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 396
def fieldUIName fieldName
  loadFieldUINames if @fieldUINames.nil?
  @fieldUINames[fieldName].nil? ? fieldName : @fieldUINames[fieldName]
end
has_field?(fieldName) click to toggle source
# File lib/twb/datasource.rb, line 469
def has_field? fieldName
  dbFieldsMap.has_key? fieldName
end
id() click to toggle source
# File lib/twb/datasource.rb, line 97
def id
    @id ||= @id = @name
end
joinTree() click to toggle source
# File lib/twb/datasource.rb, line 210
def joinTree
  @joinTree ||= loadJoinTree
end
loadAliases() click to toggle source
# File lib/twb/datasource.rb, line 282
def loadAliases
  @aliases   = {}
  # puts $node.xpath('.//column/aliases/..').length
  cnt = 0
  @node.xpath('./column//aliases/..').each do |anode|
    # puts "anode:: #{anode}"
    # puts " path:: #{anode.path}"
    aliasMap = {}
    nameTech = anode.attribute('name').text.gsub(/^\[|\]$/,'')
    name     = fieldUIName nameTech
    if ':Measure Names'.eql? name
      # puts "processing Measure Names"
      anode.xpath('.//alias').each do |vnode|
        keyCode  = vnode.attribute('key').text.gsub(/^[#"%]|[#"%]$/,'')
        key      = Twb::CodedField.new(keyCode).name
        field    = fieldUIName key
        alia     = vnode.attribute('value').text
        # puts "  keyCode:: #{key}"
        # puts "  key    :: #{key}"
        # puts "  field  :: #{field}"
        # puts "  alias  :: #{alia}"
        aliasMap[field] = alia
      end
    else
      anode.xpath('.//alias').each do |vnode|
        key  = vnode.attribute('key').text.gsub(/^[#"]|[#"]$/,'')
        alia = vnode.attribute('value').text
        # puts " key :: #{key}"
        # puts "alias:: #{alia}"
        aliasMap[key] = alia
      end
    end
    @aliases[name] = aliasMap
  end
  emit "FIELD ALIASES: @aliases"
  return @aliases
end
loadAllFields() click to toggle source
# File lib/twb/datasource.rb, line 461
def loadAllFields
  @allFields = SortedSet.new
  # dbFields.each { |f| @allFields << f }
  # calculatedFields.each { |f| @allFields << f }
  @allFields.merge dbFields
  @allFields.merge calculatedFields
end
loadAttributes(node) click to toggle source
# File lib/twb/datasource.rb, line 87
def loadAttributes node
  attributes = {}
  unless node.nil?
    node.attributes.each do |k,v|
      attributes[k] = v.text
    end
  end
  return attributes
end
loadCalculatedFields() click to toggle source
# File lib/twb/datasource.rb, line 447
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() click to toggle source
# File lib/twb/datasource.rb, line 253
def loadColumnFields
  @columnFields    = Set.new
  @columnFieldsMap = {}
  nodes = @node.xpath('.//column')
  nodes.each do |n|
    # puts " "
    # puts @columnFieldsMap.keys.inspect
    name = n.attribute('name').text.sub(/^\[/,'').sub(/\]$/,'')
    loaded = @columnFieldsMap.has_key? name
    if loaded
       # puts "LOADED"
       field = @columnFieldsMap[name]
       # puts "#{field.class}"
       field.loadAttributes(n)
    else 
       field = Twb::ColumnField.new n, self
       @columnFieldsMap[field.uiname] = field
       @columnFieldsMap[field.name]   = field
    end
    # puts "name:#{name}: \t nn:#{field.name}:\t loaded?:#{loaded}  node:#{n}:"
  end
  @columnFields = @columnFieldsMap.values
  return @columnFields
end
loadIsPublished() click to toggle source
# File lib/twb/datasource.rb, line 176
def loadIsPublished
  @isPublished = !node.at_xpath('./repository-location').nil?
end
loadJoinPairs() click to toggle source
# File lib/twb/datasource.rb, line 199
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() click to toggle source
# File lib/twb/datasource.rb, line 214
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() click to toggle source
# File lib/twb/datasource.rb, line 347
def loadLocalFields
  @localFields = Set.new
  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
    end
  end
  return @localFields
end
loadMetadataFields() click to toggle source
# File lib/twb/datasource.rb, line 369
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[@class='column']")
    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() click to toggle source

fields are unique in the data source by UI name

# File lib/twb/datasource.rb, line 484
def loadTableFields
  # puts  "DATA SOURCE FIELD TABLE LOAD"
  @tableFieldsMap = {}
  fieldNodes = @node.xpath('./connection/cols/map')
  fieldNodes.each do |fn|
    dbField = Twb::DbField.new(@uiname, fn, :map)
    @tableFieldsMap[dbField.uiname] = dbField
  end
  relTableNodes = @node.xpath('.//relation[@table]')
  relTableNodes.each do |relNode|
    table = relNode.attribute('name').text
    cols  = relNode.xpath('./columns/column')
    cols.each do |col|
      dbField = Twb::DbField.new(@uiname, col, :tableColumn, table)
      fldName = col.attribute('name')
      @tableFieldsMap[dbField.uiname] = dbField
    end
  end
end
loadTables() click to toggle source
# File lib/twb/datasource.rb, line 184
def loadTables
  @tables = {}
  connections.each do |conn|
    nodes = conn.xpath(".//relation[@type='table']")
    nodes.each do |node|
      @tables[node.attr('name')] = node.attr('table')
    end
  end
  return @tables
end
mappedFieldsMap() click to toggle source
# File lib/twb/datasource.rb, line 418
def mappedFieldsMap
  loadTableFields if @tableFieldsMap.nil?
  return @tableFieldsMap
end
processConnection(path) click to toggle source
# File lib/twb/datasource.rb, line 120
def processConnection path
    conns = @node.xpath(path)
    conns.each do |connNode|
      @connections << connNode
        # connClass = @dsclass
        # cpath     = connNode.path
        # connPath  = cpath.gsub(/\[[0-9]+\]/,'')
        # connPNum  = /(\d+)/.match(cpath)
        # # puts cpath, connPath
        # # puts "CPATH: #{cpath}"
        # conn.attributes.each do |name,value|
        #     # puts  "\n\t\t - %-15s -> %-s" % [name, value]
        #     $csvFile << [ $recCount += 1,
        #                   $twbName,  $dir,     $build,    $version,
        #                   $dsName,   $dstype,  $dsuiname, connClass,
        #                   connPath,  connPNum,
        #                   name,      value.value
        #                 ]
        # end
    end
end
processConnections() click to toggle source
# File lib/twb/datasource.rb, line 113
def processConnections
  @connections = Array.new
  processConnection './/connection'
  processConnection './/named-connection'
  return @connections
end
pullTable(xml) click to toggle source
# File lib/twb/datasource.rb, line 229
def pullTable xml
    code =xml.attribute('op').text
    table = code.split('].[')[0][1..-1]
end
setConnectionHash() click to toggle source

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
# File lib/twb/datasource.rb, line 158
def setConnectionHash
  dsAttributes = @node.xpath('./connection/@*')
  dsConnStr    = ''
  dsAttributes.each do |attr|
    dsConnStr += attr.text
  end
  @connHash = Digest::MD5.hexdigest(dsConnStr)
  @uuid = @connHash
end
tableFields() click to toggle source
# File lib/twb/datasource.rb, line 406
def tableFields
  @tableFieldsMap.values
end
tableauVersion(tabVersion) click to toggle source
# File lib/twb/datasource.rb, line 101
def tableauVersion tabVersion
  @tableauVersion = tabVersion
end
updateTime() click to toggle source
# File lib/twb/datasource.rb, line 391
def updateTime
  attr = @node.xpath('.//@update-time').first
  @updateTime = attr.nil? ? nil : attr.value
end

Private Instance Methods

loadFieldUINames() click to toggle source
# File lib/twb/datasource.rb, line 514
def loadFieldUINames
  @fieldUINames = {}
   # puts"metadataFields: #{metadataFields.length}"
  metadataFields.each do |fld|
     # puts" - name:%-45s   |  caption:%-45s   |  uiname:%-45s " % [ "'#{fld.name}'",  "'#{fld.caption}'", "'#{fld.uiname}'"]
    unless fld.name.nil?
      @fieldUINames[fld.uiname]    = fld.uiname
      @fieldUINames[fld.localName] = fld.uiname unless  fld.localName.nil?
      @fieldUINames[fld.name]      = fld.uiname
    end
  end
   # puts"localFields: #{localFields.length}"
  localFields.each do |fld|
     # puts" - name:%-45s   |  caption:%-45s   |  uiname:%-45s " % [ "'#{fld.name}'",  "'#{fld.caption}'", "'#{fld.uiname}'"]
    unless fld.caption.nil?
      @fieldUINames[fld.name]   = fld.caption
      @fieldUINames[fld.uiname] = fld.caption
    end
  end
   # puts"groups: #{groups.length}"
  groups.each do |fld|
     # puts" - name:%-45s   |  caption:%-45s   |  uiname:%-45s " % [ "'#{fld.name}'",  "'#{fld.caption}'", "'#{fld.uiname}'"]
    unless fld.caption.nil?
      @fieldUINames[fld.name]   = fld.caption
      @fieldUINames[fld.uiname] = fld.caption
    end
  end
   # puts"calculatedFields: #{calculatedFields.length}"
  calculatedFields.each do |fld| 
     # puts" - name:%-45s   |  caption:%-45s   |  uiname:%-45s " % [ "'#{fld.name}'",  "'#{fld.caption}'", "'#{fld.uiname}'"]
    unless fld.caption.nil?
      @fieldUINames[fld.name]   = fld.caption
      @fieldUINames[fld.uiname] = fld.caption
    end
  end
   # puts"columnFields: #{columnFields.length}"
  columnFields.each do |fld|
     # puts" - name:%-45s   |  caption:%-45s   |  uiname:%-45s " % [ "'#{fld.name}'",  "'#{fld.caption}'", "'#{fld.uiname}'"]
    unless fld.caption.nil?
      # @fieldUINames[fld.name]                          = fld.caption
      @fieldUINames[fld.name.gsub(/^[\[]|[\]]$/,'')]   = fld.caption
      @fieldUINames[fld.uiname]                        = fld.caption
    end
  end
  return @fieldUINames
end
loadFilters() click to toggle source

def processFilters

# File lib/twb/datasource.rb, line 572
def loadFilters
  @filters = []
  sharedFilters = @workbook.node.xpath('./shared-views/shared-view[@name="excel.41269.481293159719"]//filter')
  sharedFilters.each do |sf|
    filter = QuickFilter.new(sf,@workbook)
    @filters << filter
  end
  return @filters
end
loadGroups() click to toggle source
# File lib/twb/datasource.rb, line 561
def loadGroups
  @groups = []
  groupNodes = @node.xpath('.//group')
  groupNodes.each do |groupNode|
    groupField = Twb::GroupField.new(groupNode)
    @groups << groupField
  end
  return @groups
end