class Twb::QuickFilter
Attributes
Public Class Methods
# File lib/twb/quickfilter.rb, line 31 def initialize(node,twb) init emit "\nFILTER:\n#{node}\n=====" @node = node filterClass = @node['class'] @type = filterClass.gsub('-',' ').capitalize @kind = @node['kind'] fieldCode = node['column'] codedField = Twb::CodedField.new(fieldCode) fieldTech = codedField.name inexclusions = fieldTech =~ /^(Ex|In)clusions/ @measureNames = ':Measure Names' == fieldTech srcTech = codedField.dataSource @dataSource = twb.datasource(srcTech) @dsAliases = @dataSource.aliases field = @measureNames || inexclusions ? fieldTech : @dataSource.field(fieldTech) uiname = @dataSource.fieldUIName(fieldTech) @uiname = @measureNames || inexclusions ? fieldTech : uiname.nil? ? fieldTech : uiname @field = @uiname @includeNull = if @node['include-null'].nil? true elsif 'false' == @node['include-null'] false else true end @values = [] enode = @node.at_xpath('.//*[@user:ui-enumeration]') @inexclude = if enode.nil? 'Include' else case enode['user:ui-enumeration'] when 'inclusive' then 'Include' when 'exclusive' then 'Exclude' when nil then 'Include' when 'all' then 'Include' else 'undefined' end end @inexMode = enode.nil? ? 'Default' : 'Specified' emit "\n:: FIELD :: #{field} == #{@uiname} -- #{fieldTech} -- #{codedField.rawCode}" emit " filter class: #{filterClass}" emit " field code: #{fieldCode}" emit " coded field: #{codedField}" emit " field tech: #{fieldTech}" emit " field name: nil? #{@uiname.nil?} #{@uiname} " emit " src tech: #{srcTech}" emit " @measureNames: #{@measureNames}" emit " ds: #{@dataSource.uiname}" emit " field: #{@uiname}" emit " @inexclude: #{@inexclude}" emit " " aaa = case filterClass when 'relative-date' then resolveRelativeDate when 'quantitative' then resolveQuantitative when 'categorical' then resolveCategoricalValues end end
Public Instance Methods
# File lib/twb/quickfilter.rb, line 89 def context? @iscontext ||= @node['context'] end
# File lib/twb/quickfilter.rb, line 93 def to_s "%s => %s" % [uiname, values] end
Private Instance Methods
# File lib/twb/quickfilter.rb, line 352 def filtersFromRangeNode node emit "########################## filtersFromRangeNode" unless @twbDomainsLoaded loadDomains end # results = [] emit "filtersFromRangeNode" emit " from: #{node.attribute('from')}" emit " to. : #{node.attribute('to')}" from = node.attribute('from').text.gsub(/^"|"$/,'') to = node.attribute( 'to').text.gsub(/^"|"$/,'') emit " from: #{from}" emit " to. : #{to}" if @twbDomainsLoaded # results = filtersInRange from, to filtersInRange from, to else range = "#{from},...,#{to}" recordValue range, range end # return results end
# File lib/twb/quickfilter.rb, line 375 def filtersInRange from, to emit "########################## filtersInRange" # results = {} dsFields = @twbFielddomains[@dataSource.uiname] emit "dsFields : #{dsFields}" if dsFields.nil? || dsFields.empty? alert "#### ALERT #### - '#{@uiname}' FIELD DOMAIN VALUES FOR '#{@twb.name} DATASOURCE #{@dataSource.uiname} NOT LOADED ####" emit @twbFieldDomains emit "===========" emit dsFields emit "===========" else fieldVals = dsFields[@uiname].to_a if @dataSource.fieldHasAliases @uiname #-- resolve aliases dbValues = SortedSet.new aliases = @dataSource.fieldAliases @uiname fieldVals.each do |fv| fvAliased = aliases.has_value? fv if fvAliased dbValues << aliases.key(fv) else dbValues << fv end end $fieldVals = dbValues.to_a else #-- use domain values as returned $fieldVals = dsFields[@uiname].to_a end # domainVals = dsFields[field].to_a # #-- need to dealias (unalias?) the field domain values # dbVals = SortedSet.new # domainVals.each do |dv| emit "field values: #{$fieldVals}" unless $fieldVals.nil? || $fieldVals.empty? values = $fieldVals f_i = values.index from t_i = values.index to emit " from: #{f_i} :: '#{from}'" emit " to: #{t_i} :: '#{to}'" badRange = f_i.nil? || t_i.nil? emit "badRange: #{badRange}" if badRange emit "BAD RANGE" else tnames = values[f_i..t_i] tnames.each do |tname| # results[tname] = @dataSource.deAlias(@uiname,tname) # $TableNameAliases[tname] recordValue tname, @dataSource.deAlias(@uiname,tname) end # emit " filtersInRange f:%-35s t:%-s " % ["'#{from}:#{f_i}'", "'#{to}:#{t_i}'"] # emit " names: #{results.keys}" # emit " aliases: #{results.values}" end end end # return results end
# File lib/twb/quickfilter.rb, line 435 def loadDomains emit "def loadDomains\n==" unless @twb.nil? loader = Twb::Util::FieldDomainLoader.new @twbFielddomains = loader.loadWorkbook @twb emit "FIELD DOMAINS:: #{@twbFielddomains}\n==" @twbDomainsLoaded = true end end
# File lib/twb/quickfilter.rb, line 183 def parseRangeVal node return 'nil' if node.nil? text = node.text if text.start_with?('#') return text.gsub(/^[#]|[#]$/,'') end num = text.to_f # num.negative? ? num.floor : num.ceil result = if num < 0 num.floor else num.ceil end return result end
# File lib/twb/quickfilter.rb, line 169 def quantRangeValues min = @node.at_xpath('min') max = @node.at_xpath('max') emit "min: nil? %-6s val: %-s " % [min.nil?,min] emit "max: nil? %-6s val: %-s " % [max.nil?,max] minrv = parseRangeVal min unless min.nil? maxrv = parseRangeVal max unless max.nil? mintxt = min.nil? ? '' : max.nil? ? "At least: #{minrv}" : "#{minrv}" maxtxt = max.nil? ? '' : min.nil? ? "At most: #{maxrv}" : ",...,#{maxrv}" recordValue "#{mintxt}#{maxtxt}" # emit "#{mintxt}#{maxtxt}" # return "#{mintxt} #{maxtxt}" end
# File lib/twb/quickfilter.rb, line 99 def recordValue value, valias=nil # puts "recordValue--: #{value} :: @'#{valias}'" # valias = value if valias.nil? @values << {:value => value, :alias => valias} # puts "recordValue--: done" end
<filter class='categorical' column='[Sample - Superstore - English (Extract)].'>
<groupfilter from='"East"' function='range' level='[none:Region:nk]' to='"West"' user:ui-domain='relevant' user:ui-enumeration='inclusive' user:ui-marker='enumerate' />
</filter>
# File lib/twb/quickfilter.rb, line 202 def resolveCategoricalValues emit "########################## resolveCategoricalValues" emit "@measureNames: #{@measureNames}" if @node.element_children.empty? # <filter class='categorical' column='[Sample - Superstore].[Top Customers by Profit (copy)]' /> recordValue 'All' return end firstChild = @node.at_xpath('./groupfilter') unless firstChild.nil? # should not happen per 'if @node.element_children.empty?' above function = firstChild['function'] emit "function : #{function}" emit node.to_s #-- single element filter case function when 'member' member = firstChild['member'] value = @measureNames ? @dataSource.fieldUIName(Twb::CodedField.new(member).name) : member.gsub(/^"|"$/,'') recordValue value, @dataSource.deAlias(@uiname,value) when 'empty-level' recordValue 'None' when 'range' filtersFromRangeNode firstChild when 'union' emit "No resolving to do here. 'union' function accommodated with collection of members" when 'except' emit "UNRESOLVED function: #{function}" when 'reorder-dimensionality' emit "UNRESOLVED function: #{function}, involved with Inclusions & Exclusions - complicated to handle" when 'level-members' uiEnum = firstChild['user:ui-enumeration'] case uiEnum when 'all' recordValue 'All' else recordValue 'N/A' emit "###### ALERT - Unresolved Quick filter ######" end else recordValue "UNRESOLVED fn: #{function}" end # if 'member'.eql? function # emit "HANDLING SINGLE MEMBER FILTER" # member = firstChild['member'] # value = @measureNames ? @dataSource.fieldUIName(Twb::CodedField.new(member).name) : member.gsub(/^"|"$/,'') # alia = @dataSource.deAlias(@uiname,value) # emit "value :%-25s => alias: %-s" % [value, alia] # recordValue value, alia # return # end # if 'empty-level' == function # recordValue 'None', 'None' # return # end # if 'range'.eql? function # emit "HANDLING RANGE 1st Child FILTER" # # values = filtersFromRangeNode firstChild # filtersFromRangeNode firstChild # # values.each do |valMap| # # recordValue valMap[:value], valMap[:alias] # # end # end #-- another single element filter # <groupfilter function="level-members" level="[none:Business Line:nk]" user:ui-enumeration="all" user:ui-marker="enumerate"/> # <filter class='categorical' column='[federated.1astm0q1hl2ydc1dyqhqq0igvxkp].[none:Business Line:nk]' context='true'> # <groupfilter function='level-members' # level='[none:Business Line:nk]' # user:ui-enumeration='all' # user:ui-exclude='true' # user:ui-marker='enumerate' /> # </filter> # <filter class='categorical' column='[federated.1astm0q1hl2ydc1dyqhqq0igvxkp].[none:Business Line:nk]' context='true'> # <groupfilter function='level-members' # level='[none:Business Line:nk]' # user:ui-enumeration='all' # user:ui-marker='enumerate' /> # </filter> if 'level-members'.eql? function emit "HANDLING level-members FILTER" #-- # <filter class='categorical' column='[Sample - Superstore].[Top Customers by Profit (copy)]'> # <groupfilter function='level-members' level='[Customer Name]' user:ui-enumeration='all' user:ui-marker='enumerate' /> # </filter> #-- # <filter class='categorical' column='[Sample - Superstore].[none:Customer Name:nk]'> # <groupfilter function='level-members' level='[none:Customer Name:nk]' user:ui-enumeration='all' user:ui-marker='enumerate' /> # </filter> #-- # <filter class='categorical' column='[Sample - Superstore].[Top Customers by Profit (copy)]'> # <groupfilter function='level-members' level='[Customer Name]' user:ui-enumeration='all' user:ui-exclude='true' user:ui-marker='enumerate' /> # </filter> #-- # <filter class='categorical' column='[Sample - Superstore].[none:Customer Name:nk]'> # <groupfilter function='level-members' level='[none:Customer Name:nk]' user:ui-enumeration='all' user:ui-marker='enumerate' /> # </filter> #-- # <filter class='categorical' column='[Sample - Superstore].[Top Customers by Profit (copy)]'> # <groupfilter function='except' user:ui-domain='relevant' user:ui-enumeration='exclusive' user:ui-marker='enumerate'> # <groupfilter function='level-members' level='[Customer Name]' /> # <groupfilter function='union'> # <groupfilter function='member' level='[Customer Name]' member='"Adrian Barton"' /> # <groupfilter function='member' level='[Customer Name]' member='"Raymond Buch"' /> # </groupfilter> # </groupfilter> # </filter> #-- uiEnum = firstChild['user:ui-enumeration'] case uiEnum when 'all' recordValue 'All', 'All' when 'inclusive' @inexclude = 'Include' when 'exclusive' @inexclude = 'Exclude' end end #-- otherwise filter contains multiple elements #-- handle individual member elements elements = firstChild.xpath('.//groupfilter') elements.each do |element| function = element.attribute('function').text emit "element function: #{function}\n node:\n#{element}" if 'member'.eql? function member = element.attribute('member').text name = @measureNames ? @dataSource.fieldUIName(Twb::CodedField.new(member).name) : member.gsub(/^"|"$/,'') emit "%%%% member NAME:: #{name}" if '%null%' == name then name = 'Null' end alia = @dataSource.fieldAlias(@uiname,name) # $TableNameAliases[name] recordValue name, alia end if 'range'.eql? function emit "%%%% range element:: #{element}" t = filtersFromRangeNode element if t.empty? fromAttr = element['from'] from = fromAttr.nil? ? '' : fromAttr.gsub(/^[#"']|[#"']$/,'') toAttr = element['to'] to = toAttr.nil? ? '' : toAttr.gsub(/^[#"']|[#"']$/,'') range = "#{from},...,#{to}" recordValue range, range end t.each do |name,alia| # emit true, "++++ range Name: %-20s ALIAS: %-s " % [name, alia] # recordValue name, @dataSource.fieldAlias(@uiname,name) end end end end end
<filter class='quantitative' column='[Sample - Superstore].' included-values='in-range'> <filter class='quantitative' column='[Sample - Superstore].' included-values='in-range'> <filter class='quantitative' column='[Sample - Superstore].' included-values='in-range'> <filter class='quantitative' column='[Sample - Superstore].' included-values='all' /> <filter class='quantitative' column='[Sample - Superstore].' included-values='non-null' /> <filter class='quantitative' column='[Sample - Superstore].' included-values='null' />
# File lib/twb/quickfilter.rb, line 158 def resolveQuantitative emit "resolveQuantitative" inclValues = @node['included-values'] qvalues = if 'in-range' == inclValues quantRangeValues else "#{inclValues.capitalize} Values" end # recordValue qvalues, inclValues end
filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-1' include-future='true' include-null='false' last-period='-1' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-1' include-future='true' include-null='false' last-period='-1' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-1' include-future='true' include-null='false' last-period='0' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-2' include-future='true' include-null='false' last-period='0' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-2' include-future='true' include-null='false' last-period='0' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='-6' include-future='true' include-null='false' last-period='0' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='false' include-null='false' last-period='0' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='0' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='0' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='2' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='2' period-type='year' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='0' include-future='true' include-null='false' last-period='4' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='1' include-future='true' include-null='false' last-period='1' period-type='day' /> filter class='relative-date' column='[Sample - Superstore].[none:Order Date:qk]' first-period='1' include-future='true' include-null='false' last-period='1' period-type='year' />
# File lib/twb/quickfilter.rb, line 121 def resolveRelativeDate emit "resolveRelativeDate" periodType = @node['period-type'].nil? ? '' : @node['period-type'] inclFuture = @node['include-future'] == 'true' firstPeriod = @node['first-period'].to_i lastPeriod = @node['last-period'].to_i sum = firstPeriod + lastPeriod prod = firstPeriod * lastPeriod periodTech = "#{periodType} : #{firstPeriod} -> #{lastPeriod}" period = periodTech if sum == 0 && prod == 0 period = case periodType when 'day' then "Today" else inclFuture ? "This #{periodType.capitalize}" : "#{periodType.capitalize} to date" end elsif firstPeriod == lastPeriod future = firstPeriod > 0 reln = future ? 'Next' : 'Previous' period = case periodType when 'day' then future ? 'Tomorrow' : 'Yesterday' else "#{reln} #{periodType.capitalize}" end else span = lastPeriod - firstPeriod + 1 future = firstPeriod == 0 reln = future ? "Next" : "Last" period = "#{reln} #{span} #{periodType.capitalize}s" end recordValue period, periodTech end