lib/gooddata/models/metadata/attribute.rb
# encoding: UTF-8
#
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
require_relative '../metadata'
require_relative 'metadata'
require_relative '../../mixins/is_attribute'
module GoodData
class Attribute < MdObject
include Mixin::IsAttribute
ATTRIBUTE_BASE_AGGREGATIONS = [:count]
class << self
# Method intended to get all objects of that type in a specified project
#
# @param options [Hash] the options hash
# @option options [Boolean] :full if passed true the subclass can decide
# to pull in full objects. This is desirable from the usability POV
# but unfortunately has negative impact on performance so it is
# not the default.
# @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
def all(options = { :client => GoodData.connection, :project => GoodData.project })
query('attribute', Attribute, options)
end
# Finds the value of an atribute and gives you the textual form for the label that is acquired by calling primary_label method
#
# @param uri [String] Uri of the element. in the form of /gdc/md/PID/obj/OBJ_ID/elements?id=21
# @return [String] Textual representation of a particular attribute element
def find_element_value(stuff, opts = { :project => GoodData.project })
stuff.scan(%r{([^\[\]]*)\/elements\?id=(\d+)}).pmap do |a, id|
opts[:project].attributes(a).primary_label.find_element_value(id.to_i)
end.first
end
end
def drill_down(attribute)
attribute = Attribute[attribute, client: client, project: project]
content['drillDownStepAttributeDF'] = attribute.primary_label.meta['uri']
save
end
# Returns the labels of an attribute
# @return [Array<GoodData::Label>]
def display_forms
content['displayForms'].pmap { |df| project.labels(df['meta']['uri']) }
end
alias_method :labels, :display_forms
def dimension
uri = content['dimension']
return nil if uri.nil?
GoodData::Dimension[uri, client: client, project: project]
end
# Tells you if an attribute is a date dimension. This happens by inspecting
# an identifier if it conforms to a particular scheme.
#
# @return [Boolean] Is the attribute a date attribute?
def date_attribute?
things = [
'week',
'euweek.in.year',
'day.in.week',
'day.in.month',
'day.in.quarter',
'day.in.euweek',
'date',
'quarter.in.year',
'week.in.year',
'day.in.year',
'month',
'quarter',
'month.in.quarter',
'week.in.quarter',
'year',
'euweek',
'euweek.in.quarter',
'month.in.year'
]
potential_id = identifier.split('.')[1..-1].join('.')
things.include?(potential_id) ? true : false
end
# Returns the first display form which is the primary one
# @return [GoodData::Label] Primary label
def primary_display_form
labels.first
end
alias_method :primary_label, :primary_display_form
# Creates the basic count metric with the attribute used. If you need to
# compute the attribute on a different dataset you can specify that in
# params. The metric created is not saved.
# @param [Hash] options the options to pass to the value list
# @option options [Symbol] :type type of aggregation function.
# @option options [Symbol] :attribute Use this attribute if you need to
# express different dataset for performing the computation on. It basically
# serves for creating metrics like SELECT COUNT(User, Opportunity).
# @return [GoodData::Metric]
def create_metric(options = {})
an_attribute = options[:attribute]
a_type = options[:type] || :count
unless ATTRIBUTE_BASE_AGGREGATIONS.include?(a_type)
fail 'Suggested aggreagtion function (#{a_type}) does not exist for ' \
'base metric created out of attribute. You can use only one of' \
"#{ATTRIBUTE_BASE_AGGREGATIONS.map { |x| ':' + x.to_s }.join(',')}"
end
a_title = options[:title] || "#{a_type} of #{title}"
if an_attribute
project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}], [#{an_attribute.uri}])", title: a_title, extended_notation: false)
else
project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}])", title: a_title, extended_notation: false)
end
end
alias_method :create_measure, :create_metric
# For an element id find values (titles) for all display forms. Element id can be given as both number id or URI as a string beginning with /
# @param [Object] element_id Element identifier either Number or a uri as a String
# @return [Array] list of values for certain element. Returned in the same order as is the order of labels
def values_for(element_id)
# element_id = element_id.is_a?(String) ? element_id.match(/\?id=(\d)/)[1] : element_id
labels.pmap do |label|
label.find_element_value(element_id)
end
end
# Returns all values for all labels. This is for inspection purposes only since obviously there can be huge number of elements.
# @param [Hash] options the options to pass to the value list
# @option options [Number] :limit limits the number of values to certain number. Default is 100
# @return [Array]
def values
results = labels.map(&:values)
results.first.zip(*results[1..-1])
end
# Allows to search in attribute labels by name. It uses the string as a basis for regexp and tries to match either a title or an identifier. Returns first match.
# @param name [String] name used as a basis for regular expression
# @return [GoodData::Label]
def label_by_name(name)
labels.find { |label| label.title =~ /#{name}/ || label.identifier =~ /#{name}/ }
end
def computed_attribute?
content['rel'] && !content['rel'].empty?
end
end
end