gooddata 0.6.4 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +4 -0
- data/README.md +1 -0
- data/lib/gooddata/cli/commands/project_cmd.rb +2 -7
- data/lib/gooddata/client.rb +0 -2
- data/lib/gooddata/commands/project.rb +10 -0
- data/lib/gooddata/core/rest.rb +12 -2
- data/lib/gooddata/exceptions/attr_element_not_found.rb +12 -0
- data/lib/gooddata/extensions/enumerable.rb +12 -0
- data/lib/gooddata/helpers/global_helpers.rb +20 -0
- data/lib/gooddata/mixins/author.rb +16 -0
- data/lib/gooddata/mixins/content_getter.rb +11 -0
- data/lib/gooddata/mixins/content_property_reader.rb +13 -0
- data/lib/gooddata/mixins/content_property_writer.rb +13 -0
- data/lib/gooddata/mixins/contributor.rb +16 -0
- data/lib/gooddata/mixins/data_getter.rb +11 -0
- data/lib/gooddata/mixins/data_property_reader.rb +13 -0
- data/lib/gooddata/mixins/data_property_writer.rb +13 -0
- data/lib/gooddata/mixins/is_attribute.rb +13 -0
- data/lib/gooddata/mixins/is_fact.rb +13 -0
- data/lib/gooddata/mixins/is_label.rb +15 -0
- data/lib/gooddata/mixins/links.rb +11 -0
- data/lib/gooddata/mixins/md_finders.rb +36 -0
- data/lib/gooddata/mixins/md_id_to_uri.rb +29 -0
- data/lib/gooddata/mixins/md_json.rb +11 -0
- data/lib/gooddata/mixins/md_object_id.rb +11 -0
- data/lib/gooddata/mixins/md_object_indexer.rb +36 -0
- data/lib/gooddata/mixins/md_object_query.rb +83 -0
- data/lib/gooddata/mixins/md_relations.rb +39 -0
- data/lib/gooddata/mixins/meta_getter.rb +11 -0
- data/lib/gooddata/mixins/meta_property_reader.rb +13 -0
- data/lib/gooddata/mixins/meta_property_writer.rb +13 -0
- data/lib/gooddata/mixins/mixins.rb +15 -0
- data/lib/gooddata/mixins/not_attribute.rb +13 -0
- data/lib/gooddata/mixins/not_exportable.rb +11 -0
- data/lib/gooddata/mixins/not_fact.rb +13 -0
- data/lib/gooddata/mixins/not_label.rb +15 -0
- data/lib/gooddata/mixins/not_metric.rb +13 -0
- data/lib/gooddata/mixins/obj_id.rb +11 -0
- data/lib/gooddata/mixins/rest_getters.rb +13 -0
- data/lib/gooddata/mixins/rest_resource.rb +19 -0
- data/lib/gooddata/mixins/root_key_getter.rb +11 -0
- data/lib/gooddata/mixins/root_key_setter.rb +11 -0
- data/lib/gooddata/mixins/timestamps.rb +15 -0
- data/lib/gooddata/models/from_wire.rb +153 -0
- data/lib/gooddata/models/metadata.rb +28 -230
- data/lib/gooddata/models/metadata/attribute.rb +4 -6
- data/lib/gooddata/models/metadata/fact.rb +4 -6
- data/lib/gooddata/models/metadata/{display_form.rb → label.rb} +17 -11
- data/lib/gooddata/models/metadata/metric.rb +1 -1
- data/lib/gooddata/models/metadata/report_definition.rb +2 -2
- data/lib/gooddata/models/model.rb +55 -23
- data/lib/gooddata/models/models.rb +0 -2
- data/lib/gooddata/models/module_constants.rb +0 -2
- data/lib/gooddata/models/process.rb +1 -1
- data/lib/gooddata/models/project.rb +117 -76
- data/lib/gooddata/models/project_blueprint.rb +322 -42
- data/lib/gooddata/models/project_creator.rb +5 -4
- data/lib/gooddata/models/project_role.rb +20 -55
- data/lib/gooddata/models/schema_blueprint.rb +287 -84
- data/lib/gooddata/models/schema_builder.rb +0 -4
- data/lib/gooddata/models/to_manifest.rb +160 -0
- data/lib/gooddata/models/to_wire.rb +150 -0
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/blueprint_invalid.json +3 -1
- data/spec/data/gd_gse_data_blueprint.json +1370 -0
- data/spec/data/gd_gse_data_manifest.json +1424 -0
- data/spec/data/gd_gse_data_model.json +1772 -0
- data/spec/data/manifest_test_project.json +116 -0
- data/spec/data/model_view.json +1772 -0
- data/spec/data/superfluous_titles_view.json +81 -0
- data/spec/data/test_project_model_spec.json +7 -4
- data/spec/data/wire_test_project.json +143 -0
- data/spec/helpers/crypto_helper.rb +9 -0
- data/spec/helpers/project_helper.rb +2 -0
- data/spec/integration/command_projects_spec.rb +4 -2
- data/spec/integration/full_project_spec.rb +51 -18
- data/spec/integration/partial_md_export_import_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/models/attribute_column_spec.rb +7 -7
- data/spec/unit/models/domain_spec.rb +2 -2
- data/spec/unit/models/from_wire_spec.rb +119 -0
- data/spec/unit/models/metadata_spec.rb +4 -2
- data/spec/unit/models/project_blueprint_spec.rb +32 -16
- data/spec/unit/models/project_role_spec.rb +6 -4
- data/spec/unit/models/project_spec.rb +26 -3
- data/spec/unit/models/schema_builder_spec.rb +5 -6
- data/spec/unit/models/to_manifest_spec.rb +24 -0
- data/spec/unit/models/to_wire_spec.rb +63 -0
- metadata +53 -29
- data/lib/gooddata/models/attributes/anchor.rb +0 -37
- data/lib/gooddata/models/attributes/attributes.rb +0 -8
- data/lib/gooddata/models/attributes/date_attribute.rb +0 -25
- data/lib/gooddata/models/attributes/time_attribute.rb +0 -24
- data/lib/gooddata/models/columns/attribute.rb +0 -71
- data/lib/gooddata/models/columns/columns.rb +0 -8
- data/lib/gooddata/models/columns/date_column.rb +0 -63
- data/lib/gooddata/models/columns/fact_model.rb +0 -54
- data/lib/gooddata/models/columns/label.rb +0 -55
- data/lib/gooddata/models/columns/reference.rb +0 -57
- data/lib/gooddata/models/facts/facts.rb +0 -8
- data/lib/gooddata/models/facts/time_fact.rb +0 -20
- data/lib/gooddata/models/folders/attribute_folder.rb +0 -20
- data/lib/gooddata/models/folders/fact_folder.rb +0 -20
- data/lib/gooddata/models/folders/folders.rb +0 -8
- data/lib/gooddata/models/metadata/column.rb +0 -61
- data/lib/gooddata/models/metadata/data_set.rb +0 -32
- data/lib/gooddata/models/metadata/date_dimension.rb +0 -26
- data/lib/gooddata/models/metadata/schema.rb +0 -227
- data/lib/gooddata/models/references/date_reference.rb +0 -44
- data/lib/gooddata/models/references/references.rb +0 -8
- data/lib/gooddata/models/references/time_reference.rb +0 -13
- data/spec/helpers/schema_helper.rb +0 -16
- data/spec/unit/models/anchor_spec.rb +0 -32
- data/spec/unit/models/tools_spec.rb +0 -95
- data/test/test_upload.rb +0 -79
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/column'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# GoodData fact abstraction
|
|
9
|
-
#
|
|
10
|
-
class Fact < Column
|
|
11
|
-
def type_prefix
|
|
12
|
-
FACT_PREFIX
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def column_prefix
|
|
16
|
-
FACT_COLUMN_PREFIX
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def folder_prefix
|
|
20
|
-
FACT_FOLDER_PREFIX
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def table
|
|
24
|
-
@schema.table
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def column
|
|
28
|
-
@column ||= table + '.' + column_prefix + name
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def to_maql_create
|
|
32
|
-
"CREATE FACT {#{identifier}} VISUAL (#{visual})" \
|
|
33
|
-
+ " AS {#{column}};\n"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def to_manifest_part(mode)
|
|
37
|
-
{
|
|
38
|
-
'populates' => [identifier],
|
|
39
|
-
'mode' => mode,
|
|
40
|
-
'columnName' => name
|
|
41
|
-
}
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def to_wire_model
|
|
45
|
-
{
|
|
46
|
-
'fact' => {
|
|
47
|
-
'identifier' => identifier,
|
|
48
|
-
'title' => title
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/column'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# GoodData display form abstraction. Represents a default representation
|
|
9
|
-
# of an attribute column or an additional representation defined in a LABEL
|
|
10
|
-
# field
|
|
11
|
-
#
|
|
12
|
-
class Label < Column
|
|
13
|
-
attr_accessor :attribute
|
|
14
|
-
|
|
15
|
-
def type_prefix
|
|
16
|
-
'label'
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# def initialize(hash, schema)
|
|
20
|
-
def initialize(hash, attribute, schema)
|
|
21
|
-
super hash, schema
|
|
22
|
-
attribute = attribute.nil? ? schema.fields.find { |field| field.name == hash[:reference] } : attribute
|
|
23
|
-
@attribute = attribute
|
|
24
|
-
attribute.labels << self
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def identifier
|
|
28
|
-
@identifier ||= @attribute.name == name ? super : "#{type_prefix}.#{@schema.name}.#{@attribute.name}.#{name}"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def to_maql_create
|
|
32
|
-
"# LABEL FROM LABEL\nALTER ATTRIBUTE {#{@attribute.identifier}} ADD LABELS {#{identifier}}" \
|
|
33
|
-
+ " VISUAL (TITLE #{title.inspect}) AS {#{column}};\n"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def to_manifest_part(mode)
|
|
37
|
-
{
|
|
38
|
-
'populates' => [identifier],
|
|
39
|
-
'mode' => mode,
|
|
40
|
-
'columnName' => name
|
|
41
|
-
}
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def column
|
|
45
|
-
"#{@attribute.table}.#{LABEL_COLUMN_PREFIX}#{name}"
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
alias_method :inspect_orig, :inspect
|
|
49
|
-
|
|
50
|
-
def inspect
|
|
51
|
-
inspect_orig.sub(/>$/, " @attribute=#{@attribute.to_s.sub(/>$/, " @name=#{@attribute.name}")}>")
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/column'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# Reference to another data set
|
|
9
|
-
#
|
|
10
|
-
class Reference < Column
|
|
11
|
-
attr_accessor :reference, :schema_ref
|
|
12
|
-
|
|
13
|
-
def initialize(column, schema)
|
|
14
|
-
super column, schema
|
|
15
|
-
# pp column
|
|
16
|
-
@name = column[:name]
|
|
17
|
-
@reference = column[:reference]
|
|
18
|
-
@schema_ref = column[:dataset]
|
|
19
|
-
@schema = schema
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
##
|
|
23
|
-
# Generates an identifier of the referencing attribute using the
|
|
24
|
-
# schema name derived from schemaReference and column name derived
|
|
25
|
-
# from the reference key.
|
|
26
|
-
#
|
|
27
|
-
def identifier
|
|
28
|
-
@identifier ||= "#{ATTRIBUTE_PREFIX}.#{@schema_ref}.#{@reference}"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def key
|
|
32
|
-
"#{@name}_id"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def label_column
|
|
36
|
-
"#{LABEL_PREFIX}.#{@schema_ref}.#{@reference}"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def to_maql_create
|
|
40
|
-
"ALTER ATTRIBUTE {#{identifier}} ADD KEYS {#{@schema.table}.#{key}};\n"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def to_maql_drop
|
|
44
|
-
"ALTER ATTRIBUTE {#{identifier} DROP KEYS {#{@schema.table}.#{key}};\n"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def to_manifest_part(mode)
|
|
48
|
-
{
|
|
49
|
-
'populates' => [label_column],
|
|
50
|
-
'mode' => mode,
|
|
51
|
-
'columnName' => name,
|
|
52
|
-
'referenceKey' => 1
|
|
53
|
-
}
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/fact'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# Fact representation of a time of a day
|
|
9
|
-
#
|
|
10
|
-
class TimeFact < Fact
|
|
11
|
-
def column_prefix
|
|
12
|
-
TIME_COLUMN_PREFIX
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def type_prefix
|
|
16
|
-
TIME_FACT_PREFIX
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/folder'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# GoodData attribute folder abstraction
|
|
9
|
-
#
|
|
10
|
-
class AttributeFolder < Folder
|
|
11
|
-
def type
|
|
12
|
-
'ATTRIBUTE'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def type_prefix
|
|
16
|
-
'dim'
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata/folder'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
##
|
|
8
|
-
# GoodData fact folder abstraction
|
|
9
|
-
#
|
|
10
|
-
class FactFolder < Folder
|
|
11
|
-
def type
|
|
12
|
-
'FACT'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def type_prefix
|
|
16
|
-
'ffld'
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../md_object'
|
|
4
|
-
require_relative '../../helpers/helpers'
|
|
5
|
-
|
|
6
|
-
module GoodData
|
|
7
|
-
module Model
|
|
8
|
-
##
|
|
9
|
-
# This is a base class for server-side LDM elements such as attributes, labels and
|
|
10
|
-
# facts
|
|
11
|
-
#
|
|
12
|
-
class Column < MdObject
|
|
13
|
-
attr_accessor :folder, :name, :title, :schema
|
|
14
|
-
|
|
15
|
-
def initialize(hash, schema)
|
|
16
|
-
super()
|
|
17
|
-
fail(ArgumentError, "Schema must be provided, got #{schema.class}") unless schema.is_a? Schema
|
|
18
|
-
fail('Data set fields must have their names defined') if hash[:name].nil?
|
|
19
|
-
|
|
20
|
-
@name = hash[:name]
|
|
21
|
-
@title = hash[:title] || hash[:name].humanize
|
|
22
|
-
@folder = hash[:folder]
|
|
23
|
-
@schema = schema
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
# Generates an identifier from the object name by transliterating
|
|
28
|
-
# non-Latin character and then dropping non-alphanumerical characters.
|
|
29
|
-
#
|
|
30
|
-
def identifier
|
|
31
|
-
@identifier ||= "#{type_prefix}.#{@schema.name}.#{name}"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def to_maql_drop
|
|
35
|
-
"DROP {#{identifier}};\n"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def visual
|
|
39
|
-
visual = super
|
|
40
|
-
visual += ", FOLDER {#{folder_prefix}.#{(folder)}}" if folder
|
|
41
|
-
visual
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def to_csv_header(row)
|
|
45
|
-
name
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def to_csv_data(headers, row)
|
|
49
|
-
row[name]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Overriden to prevent long strings caused by the @schema attribute
|
|
53
|
-
#
|
|
54
|
-
def inspect
|
|
55
|
-
to_s.sub(/>$/, " @title=#{@title.inspect}, @name=#{@name.inspect}, @folder=#{@folder.inspect}," \
|
|
56
|
-
" @schema=#{@schema.to_s.sub(/>$/, ' @title=' + @schema.name.inspect + '>')}" \
|
|
57
|
-
">")
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../metadata.rb'
|
|
4
|
-
require_relative 'metadata'
|
|
5
|
-
|
|
6
|
-
module GoodData
|
|
7
|
-
class DataSet < GoodData::MdObject
|
|
8
|
-
root_key :dataSet
|
|
9
|
-
|
|
10
|
-
SLI_CTG = 'singleloadinterface'
|
|
11
|
-
DS_SLI_CTG = 'dataset-singleloadinterface'
|
|
12
|
-
|
|
13
|
-
def sli_enabled?
|
|
14
|
-
content['mode'] == 'SLI'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def sli
|
|
18
|
-
fail(NoProjectError, 'Connect to a project before searching for an object') unless GoodData.project
|
|
19
|
-
slis = GoodData.project.md.links(Model::LDM_CTG).links(SLI_CTG)[DS_SLI_CTG]
|
|
20
|
-
uri = slis[identifier]['link']
|
|
21
|
-
MdObject[uri]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def attributes
|
|
25
|
-
content['attributes'].map { |a| GoodData::Attribute[a] }
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def facts
|
|
29
|
-
content['facts'].map { |a| GoodData::Attribute[a] }
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../md_object'
|
|
4
|
-
|
|
5
|
-
module GoodData
|
|
6
|
-
module Model
|
|
7
|
-
class DateDimension < MdObject
|
|
8
|
-
def initialize(spec = {})
|
|
9
|
-
super()
|
|
10
|
-
@name = spec[:name]
|
|
11
|
-
@title = spec[:title] || @name
|
|
12
|
-
@urn = spec[:urn] || 'URN:GOODDATA:DATE'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def to_maql_create
|
|
16
|
-
# urn = "urn:chefs_warehouse_fiscal:date"
|
|
17
|
-
# title = "title"
|
|
18
|
-
# name = "name"
|
|
19
|
-
|
|
20
|
-
maql = ''
|
|
21
|
-
maql += "INCLUDE TEMPLATE \"#{@urn}\" MODIFY (IDENTIFIER \"#{@name}\", TITLE \"#{@title}\");"
|
|
22
|
-
maql
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require_relative '../../helpers/helpers'
|
|
4
|
-
|
|
5
|
-
require_relative '../attributes/anchor'
|
|
6
|
-
require_relative '../columns/columns'
|
|
7
|
-
require_relative '../md_object'
|
|
8
|
-
|
|
9
|
-
module GoodData
|
|
10
|
-
module Model
|
|
11
|
-
##
|
|
12
|
-
# Server-side representation of a local data set; includes connection point,
|
|
13
|
-
# attributes and labels, facts, folders and corresponding pieces of physical
|
|
14
|
-
# model abstractions.
|
|
15
|
-
#
|
|
16
|
-
class Schema < MdObject
|
|
17
|
-
attr_reader :fields, :attributes, :facts, :folders, :references, :labels, :name, :title, :anchor
|
|
18
|
-
|
|
19
|
-
def self.load(file)
|
|
20
|
-
Schema.new JSON.load(open(file))
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def initialize(a_config, a_name = 'Default Name', a_title = 'Default Title')
|
|
24
|
-
super()
|
|
25
|
-
@fields = []
|
|
26
|
-
@attributes = []
|
|
27
|
-
@facts = []
|
|
28
|
-
@folders = {
|
|
29
|
-
:facts => {},
|
|
30
|
-
:attributes => {}
|
|
31
|
-
}
|
|
32
|
-
@references = []
|
|
33
|
-
@labels = []
|
|
34
|
-
|
|
35
|
-
a_config[:name] = a_name unless a_config[:name]
|
|
36
|
-
a_config[:title] = a_config[:name] unless a_config[:title]
|
|
37
|
-
a_config[:title] = a_title unless a_config[:title]
|
|
38
|
-
a_config[:title] = a_config[:title].humanize
|
|
39
|
-
|
|
40
|
-
fail 'Schema name not specified' unless a_config[:name]
|
|
41
|
-
@name = a_config[:name]
|
|
42
|
-
@title = a_config[:title]
|
|
43
|
-
self.config = (a_config)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def config=(config)
|
|
47
|
-
config[:columns].each do |c|
|
|
48
|
-
case c[:type].to_s
|
|
49
|
-
when 'attribute'
|
|
50
|
-
add_attribute c
|
|
51
|
-
when 'fact'
|
|
52
|
-
add_fact c
|
|
53
|
-
when 'date'
|
|
54
|
-
add_date c
|
|
55
|
-
when 'anchor'
|
|
56
|
-
set_anchor c
|
|
57
|
-
when 'label'
|
|
58
|
-
add_label c
|
|
59
|
-
when 'reference'
|
|
60
|
-
add_reference c
|
|
61
|
-
else
|
|
62
|
-
fail "Unexpected type #{c[:type]} in #{c.inspect}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
@anchor = Anchor.new(nil, self) unless @anchor
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def type_prefix
|
|
69
|
-
'dataset'
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
##
|
|
73
|
-
# Underlying fact table name
|
|
74
|
-
#
|
|
75
|
-
def table
|
|
76
|
-
@table ||= FACT_COLUMN_PREFIX + name
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
##
|
|
80
|
-
# Generates MAQL DDL script to drop this data set and included pieces
|
|
81
|
-
#
|
|
82
|
-
def to_maql_drop
|
|
83
|
-
maql = ''
|
|
84
|
-
[attributes, facts].each do |obj|
|
|
85
|
-
maql += obj.to_maql_drop
|
|
86
|
-
end
|
|
87
|
-
maql += "DROP {#{identifier}};\n"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
##
|
|
91
|
-
# Generates MAQL DDL script to create this data set and included pieces
|
|
92
|
-
#
|
|
93
|
-
def to_maql_create
|
|
94
|
-
# TODO: Use template (.erb)
|
|
95
|
-
maql = "# Create the '#{title}' data set\n"
|
|
96
|
-
maql += "CREATE DATASET {#{identifier}} VISUAL (TITLE \"#{title}\");\n\n"
|
|
97
|
-
[attributes, facts, { 1 => @anchor }].each do |objects|
|
|
98
|
-
objects.values.each do |obj|
|
|
99
|
-
maql += "# Create '#{obj.title}' and add it to the '#{title}' data set.\n"
|
|
100
|
-
maql += obj.to_maql_create
|
|
101
|
-
maql += "ALTER DATASET {#{identifier}} ADD {#{obj.identifier}};\n\n"
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
labels.each do |label|
|
|
106
|
-
maql += "# Creating Labels\n"
|
|
107
|
-
maql += label.to_maql_create
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
references.values.each do |ref|
|
|
111
|
-
maql += "# Creating references\n"
|
|
112
|
-
maql += ref.to_maql_create
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
folders_maql = "# Create folders\n"
|
|
116
|
-
(folders[:attributes].values + folders[:facts].values).each { |folder| folders_maql += folder.to_maql_create }
|
|
117
|
-
folders_maql + "\n" + maql + "SYNCHRONIZE {#{identifier}};\n"
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def upload(path, project = nil, mode = 'FULL')
|
|
121
|
-
if path =~ URI.regexp
|
|
122
|
-
Tempfile.open('remote_file') do |temp|
|
|
123
|
-
temp << open(path).read
|
|
124
|
-
temp.flush
|
|
125
|
-
upload_data(temp, mode)
|
|
126
|
-
end
|
|
127
|
-
else
|
|
128
|
-
upload_data(path, mode)
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def upload_data(path, mode)
|
|
133
|
-
GoodData::Model.upload_data(path, to_manifest(mode))
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Generates the SLI manifest describing the data loading
|
|
137
|
-
#
|
|
138
|
-
def to_manifest(mode = 'FULL')
|
|
139
|
-
{
|
|
140
|
-
'dataSetSLIManifest' => {
|
|
141
|
-
'parts' => fields.reduce([]) do |memo, f|
|
|
142
|
-
val = f.to_manifest_part(mode)
|
|
143
|
-
memo << val unless val.nil?
|
|
144
|
-
memo
|
|
145
|
-
end,
|
|
146
|
-
'dataSet' => identifier,
|
|
147
|
-
'file' => 'data.csv', # should be configurable
|
|
148
|
-
'csvParams' => {
|
|
149
|
-
'quoteChar' => '"',
|
|
150
|
-
'escapeChar' => '"',
|
|
151
|
-
'separatorChar' => ',',
|
|
152
|
-
'endOfLine' => "\n"
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def to_wire_model
|
|
159
|
-
{
|
|
160
|
-
'dataset' => {
|
|
161
|
-
'identifier' => identifier,
|
|
162
|
-
'title' => title,
|
|
163
|
-
'anchor' => @anchor.to_wire_model,
|
|
164
|
-
'facts' => facts.map { |f| f.to_wire_model },
|
|
165
|
-
'attributes' => attributes.map { |a| a.to_wire_model },
|
|
166
|
-
'references' => references.map { |r| r.is_a?(DateReference) ? r.schema_ref : type_prefix + '.' + r.schema_ref }
|
|
167
|
-
} }
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
private
|
|
171
|
-
|
|
172
|
-
def add_attribute(column)
|
|
173
|
-
attribute = Attribute.new column, self
|
|
174
|
-
fields << attribute
|
|
175
|
-
attributes << attribute
|
|
176
|
-
add_attribute_folder(attribute.folder)
|
|
177
|
-
# folders[AttributeFolder.new(attribute.folder)] = 1 if attribute.folder
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def add_attribute_folder(name)
|
|
181
|
-
return if name.nil?
|
|
182
|
-
return if folders[:attributes].key?(name)
|
|
183
|
-
folders[:attributes][name] = AttributeFolder.new(name)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def add_fact(column)
|
|
187
|
-
fact = Fact.new column, self
|
|
188
|
-
fields << fact
|
|
189
|
-
facts << fact
|
|
190
|
-
add_fact_folder(fact.folder)
|
|
191
|
-
# folders[FactFolder.new(fact.folder)] = 1 if fact.folder
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def add_fact_folder(name)
|
|
195
|
-
return if name.nil?
|
|
196
|
-
return if folders[:facts].key?(name)
|
|
197
|
-
folders[:facts][name] = FactFolder.new(name)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def add_label(column)
|
|
201
|
-
label = Label.new(column, nil, self)
|
|
202
|
-
labels << label
|
|
203
|
-
fields << label
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def add_reference(column)
|
|
207
|
-
reference = Reference.new(column, self)
|
|
208
|
-
fields << reference
|
|
209
|
-
references << reference
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def add_date(column)
|
|
213
|
-
date = DateColumn.new column, self
|
|
214
|
-
@fields << date
|
|
215
|
-
date.parts.values.each { |p| @fields << p }
|
|
216
|
-
date.facts.each { |f| facts << f }
|
|
217
|
-
date.attributes.each { |a| attributes << a }
|
|
218
|
-
date.references.each { |r| references << r }
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def set_anchor(column) # rubocop:disable AccessorMethodName
|
|
222
|
-
@anchor = Anchor.new column, self
|
|
223
|
-
@fields << @anchor
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|