gooddata 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +4 -0
  3. data/README.md +1 -0
  4. data/lib/gooddata/cli/commands/project_cmd.rb +2 -7
  5. data/lib/gooddata/client.rb +0 -2
  6. data/lib/gooddata/commands/project.rb +10 -0
  7. data/lib/gooddata/core/rest.rb +12 -2
  8. data/lib/gooddata/exceptions/attr_element_not_found.rb +12 -0
  9. data/lib/gooddata/extensions/enumerable.rb +12 -0
  10. data/lib/gooddata/helpers/global_helpers.rb +20 -0
  11. data/lib/gooddata/mixins/author.rb +16 -0
  12. data/lib/gooddata/mixins/content_getter.rb +11 -0
  13. data/lib/gooddata/mixins/content_property_reader.rb +13 -0
  14. data/lib/gooddata/mixins/content_property_writer.rb +13 -0
  15. data/lib/gooddata/mixins/contributor.rb +16 -0
  16. data/lib/gooddata/mixins/data_getter.rb +11 -0
  17. data/lib/gooddata/mixins/data_property_reader.rb +13 -0
  18. data/lib/gooddata/mixins/data_property_writer.rb +13 -0
  19. data/lib/gooddata/mixins/is_attribute.rb +13 -0
  20. data/lib/gooddata/mixins/is_fact.rb +13 -0
  21. data/lib/gooddata/mixins/is_label.rb +15 -0
  22. data/lib/gooddata/mixins/links.rb +11 -0
  23. data/lib/gooddata/mixins/md_finders.rb +36 -0
  24. data/lib/gooddata/mixins/md_id_to_uri.rb +29 -0
  25. data/lib/gooddata/mixins/md_json.rb +11 -0
  26. data/lib/gooddata/mixins/md_object_id.rb +11 -0
  27. data/lib/gooddata/mixins/md_object_indexer.rb +36 -0
  28. data/lib/gooddata/mixins/md_object_query.rb +83 -0
  29. data/lib/gooddata/mixins/md_relations.rb +39 -0
  30. data/lib/gooddata/mixins/meta_getter.rb +11 -0
  31. data/lib/gooddata/mixins/meta_property_reader.rb +13 -0
  32. data/lib/gooddata/mixins/meta_property_writer.rb +13 -0
  33. data/lib/gooddata/mixins/mixins.rb +15 -0
  34. data/lib/gooddata/mixins/not_attribute.rb +13 -0
  35. data/lib/gooddata/mixins/not_exportable.rb +11 -0
  36. data/lib/gooddata/mixins/not_fact.rb +13 -0
  37. data/lib/gooddata/mixins/not_label.rb +15 -0
  38. data/lib/gooddata/mixins/not_metric.rb +13 -0
  39. data/lib/gooddata/mixins/obj_id.rb +11 -0
  40. data/lib/gooddata/mixins/rest_getters.rb +13 -0
  41. data/lib/gooddata/mixins/rest_resource.rb +19 -0
  42. data/lib/gooddata/mixins/root_key_getter.rb +11 -0
  43. data/lib/gooddata/mixins/root_key_setter.rb +11 -0
  44. data/lib/gooddata/mixins/timestamps.rb +15 -0
  45. data/lib/gooddata/models/from_wire.rb +153 -0
  46. data/lib/gooddata/models/metadata.rb +28 -230
  47. data/lib/gooddata/models/metadata/attribute.rb +4 -6
  48. data/lib/gooddata/models/metadata/fact.rb +4 -6
  49. data/lib/gooddata/models/metadata/{display_form.rb → label.rb} +17 -11
  50. data/lib/gooddata/models/metadata/metric.rb +1 -1
  51. data/lib/gooddata/models/metadata/report_definition.rb +2 -2
  52. data/lib/gooddata/models/model.rb +55 -23
  53. data/lib/gooddata/models/models.rb +0 -2
  54. data/lib/gooddata/models/module_constants.rb +0 -2
  55. data/lib/gooddata/models/process.rb +1 -1
  56. data/lib/gooddata/models/project.rb +117 -76
  57. data/lib/gooddata/models/project_blueprint.rb +322 -42
  58. data/lib/gooddata/models/project_creator.rb +5 -4
  59. data/lib/gooddata/models/project_role.rb +20 -55
  60. data/lib/gooddata/models/schema_blueprint.rb +287 -84
  61. data/lib/gooddata/models/schema_builder.rb +0 -4
  62. data/lib/gooddata/models/to_manifest.rb +160 -0
  63. data/lib/gooddata/models/to_wire.rb +150 -0
  64. data/lib/gooddata/version.rb +1 -1
  65. data/spec/data/blueprint_invalid.json +3 -1
  66. data/spec/data/gd_gse_data_blueprint.json +1370 -0
  67. data/spec/data/gd_gse_data_manifest.json +1424 -0
  68. data/spec/data/gd_gse_data_model.json +1772 -0
  69. data/spec/data/manifest_test_project.json +116 -0
  70. data/spec/data/model_view.json +1772 -0
  71. data/spec/data/superfluous_titles_view.json +81 -0
  72. data/spec/data/test_project_model_spec.json +7 -4
  73. data/spec/data/wire_test_project.json +143 -0
  74. data/spec/helpers/crypto_helper.rb +9 -0
  75. data/spec/helpers/project_helper.rb +2 -0
  76. data/spec/integration/command_projects_spec.rb +4 -2
  77. data/spec/integration/full_project_spec.rb +51 -18
  78. data/spec/integration/partial_md_export_import_spec.rb +1 -1
  79. data/spec/spec_helper.rb +2 -1
  80. data/spec/unit/models/attribute_column_spec.rb +7 -7
  81. data/spec/unit/models/domain_spec.rb +2 -2
  82. data/spec/unit/models/from_wire_spec.rb +119 -0
  83. data/spec/unit/models/metadata_spec.rb +4 -2
  84. data/spec/unit/models/project_blueprint_spec.rb +32 -16
  85. data/spec/unit/models/project_role_spec.rb +6 -4
  86. data/spec/unit/models/project_spec.rb +26 -3
  87. data/spec/unit/models/schema_builder_spec.rb +5 -6
  88. data/spec/unit/models/to_manifest_spec.rb +24 -0
  89. data/spec/unit/models/to_wire_spec.rb +63 -0
  90. metadata +53 -29
  91. data/lib/gooddata/models/attributes/anchor.rb +0 -37
  92. data/lib/gooddata/models/attributes/attributes.rb +0 -8
  93. data/lib/gooddata/models/attributes/date_attribute.rb +0 -25
  94. data/lib/gooddata/models/attributes/time_attribute.rb +0 -24
  95. data/lib/gooddata/models/columns/attribute.rb +0 -71
  96. data/lib/gooddata/models/columns/columns.rb +0 -8
  97. data/lib/gooddata/models/columns/date_column.rb +0 -63
  98. data/lib/gooddata/models/columns/fact_model.rb +0 -54
  99. data/lib/gooddata/models/columns/label.rb +0 -55
  100. data/lib/gooddata/models/columns/reference.rb +0 -57
  101. data/lib/gooddata/models/facts/facts.rb +0 -8
  102. data/lib/gooddata/models/facts/time_fact.rb +0 -20
  103. data/lib/gooddata/models/folders/attribute_folder.rb +0 -20
  104. data/lib/gooddata/models/folders/fact_folder.rb +0 -20
  105. data/lib/gooddata/models/folders/folders.rb +0 -8
  106. data/lib/gooddata/models/metadata/column.rb +0 -61
  107. data/lib/gooddata/models/metadata/data_set.rb +0 -32
  108. data/lib/gooddata/models/metadata/date_dimension.rb +0 -26
  109. data/lib/gooddata/models/metadata/schema.rb +0 -227
  110. data/lib/gooddata/models/references/date_reference.rb +0 -44
  111. data/lib/gooddata/models/references/references.rb +0 -8
  112. data/lib/gooddata/models/references/time_reference.rb +0 -13
  113. data/spec/helpers/schema_helper.rb +0 -16
  114. data/spec/unit/models/anchor_spec.rb +0 -32
  115. data/spec/unit/models/tools_spec.rb +0 -95
  116. data/test/test_upload.rb +0 -79
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 215639f8217dd917939a3b1d6174b99fb72c8b95
4
- data.tar.gz: 2adebe715e73ba4391123a4c61495130d79ae409
3
+ metadata.gz: 54e1b70b556c4eeb491e93325a56f66847a26267
4
+ data.tar.gz: cd49dad5c46a4cc8750bf789f49fc4be8311730c
5
5
  SHA512:
6
- metadata.gz: cc87893e984b96990174e8dbd257361e3ee86d16ffda17d199d635bc66b6070665decd5bc0ed6d64e1730185130d97b9d814f23479158864eadbbeea250ad582
7
- data.tar.gz: ebcdbeca2dc7ccb94a5a36a6e718277e9bfcf40ac9bc0ae23bc8280ff402868931d941076f64e9e35631a9983df380a6ed07bbe11586e526df5c49490866f943
6
+ metadata.gz: 33dda151e930e04f08cfb89331d152e81991cab5a6bd45e3d7bb7a5da792787a4c55340e7259c9e59b2e40189fccb0678a99079e637e1e53e94e338b6fe63a0d
7
+ data.tar.gz: 23b844a8c0cab54bd9db1f4fb36150e4fd0e1cb936f524d96177ad5e1a547294c4e537d1b1c3586f0ec1fa7f6f23d07fc28adc712fc792ae519adf56b0a3553a
@@ -1,5 +1,9 @@
1
1
  # GoodData Ruby SDK Changelog
2
2
 
3
+ ## 0.6.4
4
+ - Ability to get blueprint directly through API. This way you can work with projects that was not created using SDK
5
+ - Added basis for GD_LINT that checks your project for typical problems
6
+
3
7
  ## 0.6.3
4
8
  - Able to do save_as on metadata objects (Report, Metric, Dashboard)
5
9
  - Model is now not created through build and update if it is not passing validations
data/README.md CHANGED
@@ -56,3 +56,4 @@ Special thanks to Thomas Watson Steen [ <mailto:w@tson.dk> / [@wa7son](http://tw
56
56
  ## Copyright
57
57
 
58
58
  Copyright (c) 2010 - 2014 GoodData Corporation and Thomas Watson Steen. See LICENSE for details.
59
+
@@ -24,13 +24,8 @@ GoodData::CLI.module_eval do
24
24
  GoodData.connect(opts)
25
25
 
26
26
  begin
27
- GoodData.with_project(project_id) do |project|
28
- puts "Use 'exit' to quit the live session. Use 'q' to jump out of displaying a large output."
29
- binding.pry(:quiet => true,
30
- :prompt => [proc do |target_self, nest_level, pry|
31
- 'project_live_sesion: '
32
- end])
33
- end
27
+ require 'gooddata'
28
+ GoodData::Command::Project.jack_in(project_id)
34
29
  rescue GoodData::ProjectNotFound
35
30
  puts "Project with id \"#{project_id}\" could not be found. Make sure that the id you provided is correct."
36
31
  end
@@ -6,8 +6,6 @@ require_relative 'version'
6
6
  require_relative 'connection'
7
7
  require_relative 'helpers/helpers'
8
8
 
9
- FasterCSV = CSV
10
-
11
9
  # # GoodData API wrapper
12
10
  #
13
11
  # A convenient Ruby wrapper around the GoodData RESTful API.
@@ -141,6 +141,16 @@ module GoodData
141
141
  p.validate
142
142
  end
143
143
  end
144
+
145
+ def jack_in(project_id)
146
+ GoodData.with_project(project_id) do |project|
147
+ puts "Use 'exit' to quit the live session. Use 'q' to jump out of displaying a large output."
148
+ binding.pry(:quiet => true,
149
+ :prompt => [proc do |target_self, nest_level, pry|
150
+ 'project_live_sesion: '
151
+ end])
152
+ end
153
+ end
144
154
  end
145
155
  end
146
156
  end
@@ -95,9 +95,9 @@ module GoodData
95
95
  connection.download(file, where, options.merge(:staging_url => url))
96
96
  end
97
97
 
98
- def poll(result, key, options = {})
98
+ def poll(result, key = nil, options = {}, &bl)
99
99
  sleep_interval = options[:sleep_interval] || 10
100
- link = result[key]['links']['poll']
100
+ link = bl ? bl.call(result) : result[key]['links']['poll']
101
101
  response = GoodData.get(link, :process => false)
102
102
  while response.code != 204
103
103
  sleep sleep_interval
@@ -108,6 +108,16 @@ module GoodData
108
108
  end
109
109
  end
110
110
 
111
+ def poll_on_root(result, root, &bl)
112
+ polling_url = bl.call(result)
113
+ polling_result = GoodData.get(polling_url)
114
+ while polling_result[root]
115
+ sleep(3)
116
+ polling_result = GoodData.get(polling_url)
117
+ end
118
+ polling_result
119
+ end
120
+
111
121
  def wait_for_polling_result(polling_url)
112
122
  polling_result = GoodData.get(polling_url)
113
123
  while polling_result['wTaskStatus'] && polling_result['wTaskStatus']['status'] == 'RUNNING'
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ # Project Not Found
5
+ class AttributeElementNotFound < RuntimeError
6
+ DEFAULT_MSG = 'Attribute element "%s" was not found'
7
+
8
+ def initialize(value, msg = DEFAULT_MSG)
9
+ super(sprintf(DEFAULT_MSG, value))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+
3
+ module Enumerable
4
+ def mapcat(initial = [], &block)
5
+ reduce(initial) do |a, e|
6
+ block.call(e).each do |x|
7
+ a << x
8
+ end
9
+ a
10
+ end
11
+ end
12
+ end
@@ -60,6 +60,26 @@ module GoodData
60
60
  def humanize(str)
61
61
  ActiveSupport::Inflector.humanize(str)
62
62
  end
63
+
64
+ def underline(x)
65
+ '=' * x.size
66
+ end
67
+
68
+ # Recurscively changes the string keys of a hash to symbols.
69
+ #
70
+ # @param h [Hash] Data structure to change
71
+ # @return [Hash] Hash with symbolized keys
72
+ def symbolize_keys_deep!(h)
73
+ if Hash == h
74
+ Hash[
75
+ h.map do |k, v|
76
+ [k.respond_to?(:to_sym) ? k.to_sym : k, symbolize_keys_deep!(v)]
77
+ end
78
+ ]
79
+ else
80
+ h
81
+ end
82
+ end
63
83
  end
64
84
  end
65
85
  end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module Author
6
+ # Gets Project Role Author
7
+ #
8
+ # @return [GoodData::Profile] Project Role author
9
+ def author
10
+ url = meta['author']
11
+ tmp = GoodData.get url
12
+ GoodData::Profile.new(tmp)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module ContentGetter
6
+ def content
7
+ data && data['content']
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module ContentPropertyReader
6
+ def content_property_reader(*props)
7
+ props.each do |prop|
8
+ define_method prop, proc { content[prop.to_s] }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module ContentPropertyWriter
6
+ def content_property_writer(*props)
7
+ props.each do |prop|
8
+ define_method "#{prop}=", proc { |val| content[prop.to_s] = val }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module Contributor
6
+ # Gets Project Role Contributor
7
+ #
8
+ # @return [GoodData::Profile] Project Role Contributor
9
+ def contributor
10
+ url = meta['contributor']
11
+ tmp = GoodData.get url
12
+ GoodData::Profile.new(tmp)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module DataGetter
6
+ def data
7
+ json[root_key]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module DataPropertyReader
6
+ def data_property_reader(*props)
7
+ props.each do |prop|
8
+ define_method prop, proc { data[prop.to_s] }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module DataPropertyWriter
6
+ def data_property_writer(*props)
7
+ props.each do |prop|
8
+ define_method "#{prop}=", proc { |val| data[prop.to_s] = val }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module IsAttribute
6
+ # Returns true if the object is a attribute false otherwise
7
+ # @return [Boolean]
8
+ def attribute?
9
+ true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module IsFact
6
+ # Returns true if the object is a fact false otherwise
7
+ # @return [Boolean]
8
+ def fact?
9
+ true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module IsLabel
6
+ # Returns true if the object is a label false otherwise
7
+ # @return [Boolean]
8
+ def label?
9
+ true
10
+ end
11
+
12
+ alias_method :display_form?, :label?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module Links
6
+ def links
7
+ data['links']
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdFinders
6
+ def find_by_tag(tag)
7
+ self[:all].select { |r| r['tags'].split(',').include?(tag) }
8
+ end
9
+
10
+ def find_first_by_title(title)
11
+ all = self[:all]
12
+ item = if title.is_a?(Regexp)
13
+ all.find { |r| r['title'] =~ title }
14
+ else
15
+ all.find { |r| r['title'] == title }
16
+ end
17
+ self[item['link']] unless item.nil?
18
+ end
19
+
20
+ # Finds a specific type of the object by title. Returns all matches. Returns full object.
21
+ #
22
+ # @param title [String] title that has to match exactly
23
+ # @param title [Regexp] regular expression that has to match
24
+ # @return [Array<GoodData::MdObject>] Array of MdObject
25
+ def find_by_title(title)
26
+ all = self[:all]
27
+ items = if title.is_a?(Regexp)
28
+ all.select { |r| r['title'] =~ title }
29
+ else
30
+ all.select { |r| r['title'] == title }
31
+ end
32
+ items.map { |item| self[item['link']] unless item.nil? }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdIdToUri
6
+ IDENTIFIERS_CFG = 'instance-identifiers'
7
+
8
+ # TODO: Add test
9
+ def identifier_to_uri(*ids)
10
+ fail(NoProjectError, 'Connect to a project before searching for an object') unless GoodData.project
11
+ uri = GoodData.project.md[IDENTIFIERS_CFG]
12
+ response = GoodData.post uri, 'identifierToUri' => ids
13
+ if response['identifiers'].empty?
14
+ nil
15
+ else
16
+ identifiers = response['identifiers']
17
+ ids_lookup = identifiers.reduce({}) do |a, e|
18
+ a[e['identifier']] = e['uri']
19
+ a
20
+ end
21
+ uris = ids.map { |x| ids_lookup[x] }
22
+ uris.count == 1 ? uris.first : uris
23
+ end
24
+ end
25
+
26
+ alias_method :id_to_uri, :identifier_to_uri
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdJson
6
+ def to_json
7
+ json.to_json
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdObjId
6
+ def obj_id(uri)
7
+ uri.split('/').last
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ module Mixin
5
+ module MdObjectIndexer
6
+ MD_OBJ_CTG = 'obj'
7
+
8
+ # Returns either list of objects or a specific object. This method is reimplemented in subclasses to leverage specific implementation for specific type of objects. Options is used in subclasses specifically to provide shorthand for getting a full objects after getting a list of hashes from query resource
9
+ # @param [Object] id id can be either a number a String (as a URI). Subclasses should also be abel to deal with getting the instance of MdObject already and a :all symbol
10
+ # @param [Hash] options the options hash
11
+ # @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
12
+ # @return [MdObject] if id is a String or number single object is returned
13
+ # @return [Array] if :all was provided as an id, list of objects should be returned. Note that this is implemented only in the subclasses. MdObject does not support this since API has no means to return list of all types of objects
14
+ def [](id, options = {})
15
+ project = options[:project] || GoodData.project
16
+
17
+ fail "You have to provide an \"id\" to be searched for." unless id
18
+ fail(NoProjectError, 'Connect to a project before searching for an object') unless project
19
+ return all(options) if id == :all
20
+ return id if id.is_a?(MdObject)
21
+ uri = if id.is_a?(Integer) || id =~ /^\d+$/
22
+ "#{project.md[MD_OBJ_CTG]}/#{id}"
23
+ elsif id !~ /\//
24
+ identifier_to_uri id
25
+ elsif id =~ /^\//
26
+ id
27
+ else
28
+ fail 'Unexpected object id format: expected numeric ID, identifier with no slashes or an URI starting with a slash'
29
+ end
30
+ new(GoodData.get uri) unless uri.nil?
31
+ end
32
+
33
+ alias_method :get_by_id, :[]
34
+ end
35
+ end
36
+ end