lib/gooddata/models/blueprint/to_wire.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.
module GoodData
module Model
module ToWire
# Converts anchor to wire format. There is difference between datsets that
# do not have anchor and those that do. Even if there is no acnhor you
# stil have to generate. If there is anchor it behaves exactly like am
# attribute
#
# @param project [Hash] Project blueprint hash represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.anchor_to_wire(_project, dataset)
attribute_to_wire(dataset, DatasetBlueprint.anchor(dataset))
end
# Converts atttribute to wire format.
#
# @param project [Hash] Project blueprint hash represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.attributes_to_wire(_project, dataset)
DatasetBlueprint.attributes(dataset).map do |a|
attribute_to_wire(dataset, a)
end
end
# Converts atttribute to wire format.
#
# @param dataset [Hash] Dataset blueprint hash represenation
# @param attribute [Hash] Attribute
# @return [Hash] Manifest for a particular reference
def self.attribute_to_wire(dataset, attribute)
ls = DatasetBlueprint.labels_for_attribute(dataset, attribute)
labels = ls.map do |l|
{
label: {
identifier: l[:id],
title: GoodData::Model.title(l),
type: l[:gd_type] || Model::DEFAULT_TYPE,
dataType: GoodData::Model.normalize_gd_data_type(l[:gd_data_type]) || Model::DEFAULT_ATTRIBUTE_DATATYPE
}
}
end
{}.tap do |a|
a[:attribute] = {}
a[:attribute][:identifier] = attribute[:id]
a[:attribute][:title] = Model.title(attribute)
a[:attribute][:folder] = attribute[:folder] || dataset[:folder] || GoodData::Model.title(dataset)
a[:attribute][:labels] = labels unless labels.empty?
a[:attribute][:description] = GoodData::Model.description(attribute) if GoodData::Model.description(attribute)
if attribute[:order_by]
label, direction = attribute[:order_by].split(' - ')
a[:attribute][:sortOrder] = {
attributeSortOrder: {
label: label,
direction: direction
}
}
end
if attribute[:grain]
a[:attribute][:grain] = attribute[:grain].map do |g|
case g.keys.first
when :date
{ dateDimension: g.values.first }
else
g
end
end
end
if attribute[:relations]
a[:attribute][:relations] = attribute[:relations]
end
default = ls.find { |l| l[:default_label] }
a[:attribute][:defaultLabel] = (default && default[:id]) || ls.first[:id] unless ls.empty?
end
end
# Converts dataset to wire format.
#
# @param project [Hash] Project blueprint hash represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.dataset_to_wire(project, dataset)
{
dataset: {
identifier: dataset[:id],
title: GoodData::Model.title(dataset),
anchor: anchor_to_wire(project, dataset),
attributes: attributes_to_wire(project, dataset),
facts: DatasetBlueprint.facts(dataset).map { |f| fact_to_wire(dataset, f) },
references: references_to_wire(project, dataset),
bridges: bridges_to_wire(project, dataset)
}
}
end
# Converts date dimension to wire format.
#
# @param project [Hash] Project blueprint hash represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.date_dimension_to_wire(project, dataset)
payload = {}.tap do |dd|
dd[:name] = dataset[:id]
dd[:urn] = dataset[:urn] if dataset[:urn]
dd[:title] = GoodData::Model.title(dataset)
dd[:identifierPrefix] = dataset[:identifier_prefix] if dataset[:identifier_prefix]
dd[:bridges] = bridges_to_wire(project, dataset)
end
{ dateDimension: payload }
end
# Converts fact to wire format.
#
# @param dataset [Hash] Dataset blueprint hash represenation
# @param fact [Hash] Fact blueprint
# @return [Hash] Manifest for a particular reference
def self.fact_to_wire(dataset, fact)
payload = {
fact: {
identifier: fact[:id],
title: GoodData::Model.title(fact),
folder: fact[:folder] || dataset[:folder] || GoodData::Model.title(dataset),
dataType: GoodData::Model.normalize_gd_data_type(fact[:gd_data_type]) || DEFAULT_FACT_DATATYPE,
type: fact[:type]
}
}
payload.tap do |p|
p[:fact][:description] = GoodData::Model.description(fact) if GoodData::Model.description(fact)
p[:fact][:restricted] = fact[:restricted] if fact[:restricted]
end
end
# Converts references to wire format.
#
# @param fact [Hash] Project blueprint hash represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.references_to_wire(_project, dataset)
DatasetBlueprint.references(dataset).map do |r|
r[:dataset]
end
end
# Converts bridges to wire format.
#
# @param _project [Hash] Project blueprint hash represenation
# @return [Hash] Manifest for a particular bridge
def self.bridges_to_wire(_project, bridge)
DatasetBlueprint.bridges(bridge).map do |r|
r[:dataset]
end
end
# Entry method. Converts ProjectBlueprint representation into wire format
# which is understood by the API
#
# @param fact [Hash] Project blueprint represenation
# @param dataset [Hash] Dataset blueprint hash represenation
# @return [Hash] Manifest for a particular reference
def self.to_wire(what)
{
diffRequest: {
targetModel: {
projectModel: {
modelMetadata: { containCA: what[:include_ca] },
datasets: (what[:datasets] || []).map { |d| dataset_to_wire(what, d) },
dateDimensions: (what[:date_dimensions] || []).map { |d| date_dimension_to_wire(what, d) }
}
}
}
}
end
end
end
end