gooddata 0.6.19 → 0.6.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/Rakefile +17 -3
  4. data/gooddata.gemspec +8 -7
  5. data/lib/gooddata/bricks/middleware/base_middleware.rb +1 -1
  6. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +2 -2
  7. data/lib/gooddata/cli/shared.rb +2 -1
  8. data/lib/gooddata/commands/auth.rb +58 -5
  9. data/lib/gooddata/commands/runners.rb +2 -6
  10. data/lib/gooddata/extensions/big_decimal.rb +4 -0
  11. data/lib/gooddata/extensions/false.rb +11 -0
  12. data/lib/gooddata/extensions/hash.rb +6 -17
  13. data/lib/gooddata/extensions/nil.rb +11 -0
  14. data/lib/gooddata/extensions/numeric.rb +11 -0
  15. data/lib/gooddata/extensions/object.rb +11 -0
  16. data/lib/gooddata/extensions/symbol.rb +11 -0
  17. data/lib/gooddata/extensions/true.rb +11 -0
  18. data/lib/gooddata/helpers/auth_helpers.rb +32 -2
  19. data/lib/gooddata/helpers/data_helper.rb +1 -1
  20. data/lib/gooddata/helpers/global_helpers.rb +98 -31
  21. data/lib/gooddata/mixins/md_finders.rb +15 -15
  22. data/lib/gooddata/mixins/md_object_query.rb +12 -2
  23. data/lib/gooddata/models/blueprint/blueprint_field.rb +2 -2
  24. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +2 -2
  25. data/lib/gooddata/models/blueprint/project_blueprint.rb +3 -3
  26. data/lib/gooddata/models/blueprint/schema_blueprint.rb +1 -1
  27. data/lib/gooddata/models/datawarehouse.rb +1 -0
  28. data/lib/gooddata/models/domain.rb +13 -16
  29. data/lib/gooddata/models/from_wire.rb +0 -2
  30. data/lib/gooddata/models/membership.rb +1 -1
  31. data/lib/gooddata/models/metadata/attribute.rb +1 -1
  32. data/lib/gooddata/models/metadata/dashboard.rb +1 -1
  33. data/lib/gooddata/models/metadata/dataset.rb +1 -1
  34. data/lib/gooddata/models/metadata/dimension.rb +1 -1
  35. data/lib/gooddata/models/metadata/fact.rb +1 -1
  36. data/lib/gooddata/models/metadata/label.rb +16 -17
  37. data/lib/gooddata/models/metadata/metric.rb +1 -1
  38. data/lib/gooddata/models/metadata/report.rb +1 -1
  39. data/lib/gooddata/models/metadata/report_definition.rb +7 -7
  40. data/lib/gooddata/models/metadata/variable.rb +1 -1
  41. data/lib/gooddata/models/model.rb +2 -2
  42. data/lib/gooddata/models/profile.rb +2 -2
  43. data/lib/gooddata/models/project.rb +21 -23
  44. data/lib/gooddata/models/project_role.rb +3 -3
  45. data/lib/gooddata/models/schedule.rb +18 -4
  46. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +12 -15
  47. data/lib/gooddata/models/user_filters/user_filter.rb +8 -8
  48. data/lib/gooddata/models/user_filters/user_filter_builder.rb +16 -13
  49. data/lib/gooddata/models/user_filters/variable_user_filter.rb +1 -1
  50. data/lib/gooddata/rest/client.rb +4 -2
  51. data/lib/gooddata/rest/connection.rb +37 -30
  52. data/lib/gooddata/rest/connections/rest_client_connection.rb +1 -1
  53. data/lib/gooddata/version.rb +1 -1
  54. data/spec/environment/develop.rb +4 -4
  55. data/spec/environment/hotfix.rb +1 -1
  56. data/spec/environment/release.rb +1 -1
  57. data/spec/integration/full_project_spec.rb +3 -3
  58. data/spec/integration/over_to_user_filters_spec.rb +1 -0
  59. data/spec/integration/project_spec.rb +1 -1
  60. data/spec/integration/user_filters_spec.rb +0 -1
  61. data/spec/unit/commands/command_auth_spec.rb +10 -0
  62. data/spec/unit/extensions/hash_spec.rb +1 -1
  63. data/spec/unit/helpers_spec.rb +0 -8
  64. data/spec/unit/models/domain_spec.rb +1 -9
  65. data/spec/unit/models/from_wire_spec.rb +1 -19
  66. data/spec/unit/models/membership_spec.rb +1 -1
  67. data/spec/unit/models/metadata_spec.rb +1 -1
  68. data/spec/unit/models/profile_spec.rb +23 -47
  69. data/spec/unit/models/schedule_spec.rb +47 -3
  70. metadata +174 -50
  71. data/lib/gooddata/models/from_wire_parse.rb +0 -125
@@ -54,25 +54,24 @@ module GoodData
54
54
  # @option options [Number] :limit limits the number of values to certain number. Default is 100
55
55
  # @return [Array]
56
56
  def values(options = {})
57
- limit = options[:limit] || 100
58
- page_limit = 100
59
- offset = 0
60
- vals = []
61
- loop do
62
- results = GoodData.post("#{uri}/validElements?limit=#{page_limit}&offset=#{offset}&order=asc", {})
63
- elements = results['validElements']
64
- items = elements['items'].map do |el|
65
- v = el['element']
66
- {
67
- :value => v['title'],
68
- :uri => v['uri']
69
- }
57
+ client = client(options)
58
+ Enumerator.new do |y|
59
+ offset = options[:offset] || 0
60
+ page_limit = options[:limit] || 100
61
+ loop do
62
+ results = client.post("#{uri}/validElements?limit=#{page_limit}&offset=#{offset}&order=asc", {})
63
+ elements = results['validElements']
64
+ elements['items'].map do |el|
65
+ v = el['element']
66
+ y << {
67
+ :value => v['title'],
68
+ :uri => v['uri']
69
+ }
70
+ end
71
+ break if elements['items'].count < page_limit
72
+ offset += page_limit
70
73
  end
71
- vals.concat(items)
72
- break if vals.length > limit || vals.length == elements['paging']['total'].to_i
73
- offset += page_limit
74
74
  end
75
- vals.take(limit)
76
75
  end
77
76
 
78
77
  def values_count
@@ -24,7 +24,7 @@ module GoodData
24
24
  # @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
25
25
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
26
26
  def all(options = { :client => GoodData.connection, :project => GoodData.project })
27
- query('metrics', Metric, options)
27
+ query('metric', Metric, options)
28
28
  end
29
29
 
30
30
  def xcreate(metric, options = { :client => GoodData.connection, :project => GoodData.project })
@@ -16,7 +16,7 @@ module GoodData
16
16
  # @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
17
17
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
18
18
  def all(options = { :client => GoodData.connection, :project => GoodData.project })
19
- query('reports', Report, options)
19
+ query('report', Report, options)
20
20
  end
21
21
 
22
22
  def create(options = { :client => GoodData.connection, :project => GoodData.project })
@@ -17,7 +17,7 @@ module GoodData
17
17
  # @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
18
18
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
19
19
  def all(options = { :client => GoodData.connection, :project => GoodData.project })
20
- query('reportdefinition', ReportDefinition, options)
20
+ query('reportDefinition', ReportDefinition, options)
21
21
  end
22
22
 
23
23
  def create_metrics_part(left, top)
@@ -276,7 +276,7 @@ module GoodData
276
276
  uri_for_what = for_what.respond_to?(:uri) ? for_what.uri : for_what
277
277
 
278
278
  content['grid']['metrics'] = metric_parts.map do |item|
279
- item.deep_dup.tap do |i|
279
+ GoodData::Helpers.deep_dup(item).tap do |i|
280
280
  i['uri'].gsub!("[#{uri_what}]", "[#{uri_for_what}]")
281
281
  end
282
282
  end
@@ -284,7 +284,7 @@ module GoodData
284
284
  cols = content['grid']['columns'] || []
285
285
  content['grid']['columns'] = cols.map do |item|
286
286
  if item.is_a?(Hash)
287
- item.deep_dup.tap do |i|
287
+ GoodData::Helpers.deep_dup(item).tap do |i|
288
288
  i['attribute']['uri'].gsub!("[#{uri_what}]", "[#{uri_for_what}]")
289
289
  end
290
290
  else
@@ -295,7 +295,7 @@ module GoodData
295
295
  rows = content['grid']['rows'] || []
296
296
  content['grid']['rows'] = rows.map do |item|
297
297
  if item.is_a?(Hash)
298
- item.deep_dup.tap do |i|
298
+ GoodData::Helpers.deep_dup(item).tap do |i|
299
299
  i['attribute']['uri'].gsub!("[#{uri_what}]", "[#{uri_for_what}]")
300
300
  end
301
301
  else
@@ -306,7 +306,7 @@ module GoodData
306
306
  widths = content['grid']['columnWidths'] || []
307
307
  content['grid']['columnWidths'] = widths.map do |item|
308
308
  if item.is_a?(Hash)
309
- item.deep_dup.tap do |i|
309
+ GoodData::Helpers.deep_dup(item).tap do |i|
310
310
  if i['locator'][0].key?('attributeHeaderLocator')
311
311
  i['locator'][0]['attributeHeaderLocator']['uri'].gsub!("[#{uri_what}]", "[#{uri_for_what}]")
312
312
  end
@@ -319,7 +319,7 @@ module GoodData
319
319
  sort = content['grid']['sort']['columns'] || []
320
320
  content['grid']['sort']['columns'] = sort.map do |item|
321
321
  if item.is_a?(Hash)
322
- item.deep_dup.tap do |i|
322
+ GoodData::Helpers.deep_dup(item).tap do |i|
323
323
  next unless i.key?('metricSort')
324
324
  next unless i['metricSort'].key?('locators')
325
325
  next unless i['metricSort']['locators'][0].key?('attributeLocator2')
@@ -336,7 +336,7 @@ module GoodData
336
336
  key = e[0]
337
337
  val = e[1]
338
338
  a[key] = val.map do |item|
339
- item.deep_dup.tap do |i|
339
+ GoodData::Helpers.deep_dup(item).tap do |i|
340
340
  i['uri'].gsub!("[#{uri_what}]", "[#{uri_for_what}]")
341
341
  end
342
342
  end
@@ -15,7 +15,7 @@ module GoodData
15
15
  # @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
16
16
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
17
17
  def all(options = { :client => GoodData.connection, :project => GoodData.project })
18
- query('prompts', Variable, options)
18
+ query('prompt', Variable, options)
19
19
  end
20
20
 
21
21
  def create(data, options = { :client => GoodData.connection, :project => GoodData.project })
@@ -93,7 +93,7 @@ module GoodData
93
93
 
94
94
  class << self
95
95
  def title(item)
96
- item[:title] || item[:id].titleize
96
+ item[:title] || GoodData::Helpers.titleize(item[:id])
97
97
  end
98
98
 
99
99
  def column_name(item)
@@ -222,7 +222,7 @@ module GoodData
222
222
  def merge_dataset_columns(a_schema_blueprint, b_schema_blueprint)
223
223
  a_schema_blueprint = a_schema_blueprint.to_hash
224
224
  b_schema_blueprint = b_schema_blueprint.to_hash
225
- d = a_schema_blueprint.deep_dup
225
+ d = GoodData::Helpers.deep_dup(a_schema_blueprint)
226
226
  d[:columns] = d[:columns] + b_schema_blueprint[:columns]
227
227
  d[:columns].uniq!
228
228
  columns_that_failed_to_merge = d[:columns].group_by { |x| [:reference, :date].include?(x[:type]) ? x[:dataset] : x[:id] }.map { |k, v| [k, v.count, v] }.select { |x| x[1] > 1 }
@@ -79,7 +79,7 @@ module GoodData
79
79
  end
80
80
 
81
81
  def create_object(attributes)
82
- json = EMPTY_OBJECT.deep_dup
82
+ json = GoodData::Helpers.deep_dup(EMPTY_OBJECT)
83
83
  json['accountSetting']['links']['self'] = attributes[:uri] if attributes[:uri]
84
84
  res = client.create(GoodData::Profile, json)
85
85
 
@@ -393,7 +393,7 @@ module GoodData
393
393
  end
394
394
 
395
395
  def to_hash
396
- tmp = content.merge(uri: uri).symbolize_keys
396
+ tmp = GoodData::Helpers.symbolize_keys(content.merge(uri: uri))
397
397
  [
398
398
  [:companyName, :company],
399
399
  [:phoneNumber, :phone],
@@ -9,6 +9,8 @@ require 'zip'
9
9
 
10
10
  require_relative '../exceptions/no_project_error'
11
11
 
12
+ require_relative '../helpers/auth_helpers'
13
+
12
14
  require_relative '../rest/resource'
13
15
  require_relative '../mixins/author'
14
16
  require_relative '../mixins/contributor'
@@ -25,6 +27,7 @@ module GoodData
25
27
  PROJECT_PATH = '/gdc/projects/%s'
26
28
  SLIS_PATH = '/ldm/singleloadinterface'
27
29
  DEFAULT_INVITE_MESSAGE = 'Join us!'
30
+ DEFAULT_ENVIRONMENT = 'PRODUCTION'
28
31
 
29
32
  EMPTY_OBJECT = {
30
33
  'project' => {
@@ -34,7 +37,7 @@ module GoodData
34
37
  'content' => {
35
38
  'guidedNavigation' => 1,
36
39
  'driver' => 'Pg',
37
- 'environment' => 'PRODUCTION'
40
+ 'environment' => GoodData::Helpers::AuthHelper.read_environment
38
41
  }
39
42
  }
40
43
  }
@@ -87,7 +90,7 @@ module GoodData
87
90
 
88
91
  def create_object(data = {})
89
92
  c = client(data)
90
- new_data = EMPTY_OBJECT.deep_dup.tap do |d|
93
+ new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
91
94
  d['project']['meta']['title'] = data[:title]
92
95
  d['project']['meta']['summary'] = data[:summary] if data[:summary]
93
96
  d['project']['meta']['projectTemplate'] = data[:template] if data[:template]
@@ -114,6 +117,7 @@ module GoodData
114
117
  c = client(opts)
115
118
  fail ArgumentError, 'No :client specified' if c.nil?
116
119
 
120
+ opts = { :auth_token => Helpers::AuthHelper.read_token }.merge(opts)
117
121
  auth_token = opts[:auth_token] || opts[:token]
118
122
  fail ArgumentError, 'You have to provide your token for creating projects as :auth_token parameter' if auth_token.nil? || auth_token.empty?
119
123
 
@@ -1011,7 +1015,7 @@ module GoodData
1011
1015
 
1012
1016
  # Saves project
1013
1017
  def save
1014
- data_to_send = raw_data.deep_dup
1018
+ data_to_send = GoodData::Helpers.deep_dup(raw_data)
1015
1019
  data_to_send['project']['content'].delete('cluster')
1016
1020
  data_to_send['project']['content'].delete('isPublic')
1017
1021
  data_to_send['project']['content'].delete('state')
@@ -1094,27 +1098,21 @@ module GoodData
1094
1098
  #
1095
1099
  #
1096
1100
  # @return [Array<GoodData::User>] List of users
1097
- def users(opts = { offset: 0, limit: 1_000 })
1098
- result = []
1099
-
1100
- # TODO: @korczis, review this after WA-3953 get fixed
1101
- offset = 0 || opts[:offset]
1102
- uri = "/gdc/projects/#{pid}/users?offset=#{offset}&limit=#{opts[:limit]}"
1103
- loop do
1104
- break unless uri
1105
- tmp = client(opts).get(uri)
1106
- tmp['users'].each do |user|
1107
- result << client.factory.create(GoodData::Membership, user, project: self)
1108
- end
1109
- offset += opts[:limit]
1110
- if tmp['users'].length == opts[:limit]
1111
- uri = "/gdc/projects/#{pid}/users?offset=#{offset}&limit=#{opts[:limit]}"
1112
- else
1113
- uri = nil
1101
+ def users(opts = {})
1102
+ client = client(opts)
1103
+ Enumerator.new do |y|
1104
+ offset = opts[:offset] || 0
1105
+ limit = opts[:limit] || 1_000
1106
+ loop do
1107
+ tmp = client.get("/gdc/projects/#{pid}/users", params: { offset: offset, limit: limit })
1108
+ tmp['users'].each do |user_data|
1109
+ user = client.create(GoodData::Membership, user_data, project: self)
1110
+ y << user if opts[:all] || user.enabled?
1111
+ end
1112
+ break if tmp['users'].count < limit
1113
+ offset += limit
1114
1114
  end
1115
1115
  end
1116
-
1117
- opts[:all] ? result : result.select(&:enabled?).reject(&:deleted?)
1118
1116
  end
1119
1117
 
1120
1118
  alias_method :members, :users
@@ -1137,7 +1135,7 @@ module GoodData
1137
1135
  def import_users(new_users, options = {})
1138
1136
  domain = options[:domain]
1139
1137
  role_list = roles
1140
- users_list = users(all: true, offset: 0, limit: 1_000)
1138
+ users_list = users(all: true)
1141
1139
  new_users = new_users.map { |x| (x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash }
1142
1140
 
1143
1141
  GoodData.logger.warn("Importing users to project (#{pid})")
@@ -36,10 +36,10 @@ module GoodData
36
36
  d[:title] = data[:title]
37
37
  d[:summary] = data[:summary]
38
38
  end
39
- new_data = EMPTY_OBJECT.deep_dup.tap do |d|
39
+ new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
40
40
  d['projectRole']['links']['self'] = data[:uri] if data[:uri]
41
- d['projectRole']['meta'] = d['projectRole']['meta'].merge(meta_data.stringify_keys)
42
- d['projectRole']['permissions'] = d['projectRole']['permissions'].merge((data[:permissions] || {}).stringify_keys)
41
+ d['projectRole']['meta'] = d['projectRole']['meta'].merge(GoodData::Helpers.stringify_keys(meta_data))
42
+ d['projectRole']['permissions'] = d['projectRole']['permissions'].merge(GoodData::Helpers.stringify_keys(data[:permissions] || {}))
43
43
  end
44
44
  new(new_data)
45
45
  end
@@ -101,7 +101,7 @@ module GoodData
101
101
  :reschedule => 0
102
102
  }
103
103
 
104
- schedule = c.create(GoodData::Schedule, GoodData::Helpers.stringify_keys_deep!(SCHEDULE_TEMPLATE.deep_dup), client: c, project: p)
104
+ schedule = c.create(GoodData::Schedule, GoodData::Helpers.deep_stringify_keys(GoodData::Helpers.deep_dup(SCHEDULE_TEMPLATE)), client: c, project: p)
105
105
 
106
106
  schedule.name = options[:name]
107
107
  schedule.hidden_params = options[:hidden_params]
@@ -119,7 +119,7 @@ module GoodData
119
119
  # @param json [Object] Raw JSON
120
120
  # @return [GoodData::Schedule] New GoodData::Schedule instance
121
121
  def initialize(json)
122
- json = GoodData::Helpers.stringify_keys_deep!(json)
122
+ json = GoodData::Helpers.deep_stringify_keys(json)
123
123
  super
124
124
  GoodData::Helpers.decode_params(json['schedule']['params'] || {})
125
125
  GoodData::Helpers.decode_params(json['schedule']['hiddenParams'] || {})
@@ -179,7 +179,8 @@ module GoodData
179
179
  # @param [Hash] opts execution options.
180
180
  # @option opts [Boolean] :wait Wait for execution result
181
181
  # @return [Object] Raw Response
182
- def execute(opts = { :wait => true })
182
+ def execute(opts = {})
183
+ opts = { :wait => true }.merge(opts)
183
184
  data = {
184
185
  :execution => {}
185
186
  }
@@ -187,7 +188,7 @@ module GoodData
187
188
  execution = client.create(GoodData::Execution, res, client: client, project: project)
188
189
 
189
190
  return execution unless opts[:wait]
190
- execution.wait_for_result
191
+ execution.wait_for_result(opts)
191
192
  end
192
193
 
193
194
  # Returns execution URL
@@ -265,6 +266,13 @@ module GoodData
265
266
  @dirty = true
266
267
  end
267
268
 
269
+ # Returns execution process related to this schedule
270
+ #
271
+ # @return [GoodData::Process] Process ID
272
+ def process
273
+ project.processes(process_id)
274
+ end
275
+
268
276
  # Returns execution process ID
269
277
  #
270
278
  # @return [String] Process ID
@@ -398,6 +406,8 @@ module GoodData
398
406
 
399
407
  def schedule_type=(type)
400
408
  json['schedule']['type'] = type
409
+ @dirty = true
410
+ self
401
411
  end
402
412
 
403
413
  def trigger_id
@@ -406,6 +416,8 @@ module GoodData
406
416
 
407
417
  def trigger_id=(a_trigger)
408
418
  json['schedule']['triggerScheduleId'] = a_trigger
419
+ @dirty = true
420
+ self
409
421
  end
410
422
 
411
423
  def name
@@ -414,6 +426,8 @@ module GoodData
414
426
 
415
427
  def name=(name)
416
428
  json['schedule']['name'] = name
429
+ @dirty = true
430
+ self
417
431
  end
418
432
 
419
433
  def set_trigger(trigger) # rubocop:disable Style/AccessorMethodName
@@ -16,7 +16,7 @@ module GoodData
16
16
  def all(options = { client: GoodData.connection, project: GoodData.project })
17
17
  c = client(options)
18
18
  project = options[:project]
19
- vars = c.get(project.md['query'] + '/userfilters/')['query']['entries']
19
+ filters = query('userFilter', nil, options)
20
20
  count = 10_000
21
21
  offset = 0
22
22
  user_lookup = {}
@@ -30,20 +30,17 @@ module GoodData
30
30
  break if result['userFilters']['length'] < offset
31
31
  offset += count
32
32
  end
33
- vars.each_slice(100).mapcat do |batch|
34
- batch.pmap do |a|
35
- uri = a['link']
36
- data = c.get(uri)
37
- payload = {
38
- 'expression' => data['userFilter']['content']['expression'],
39
- 'related' => user_lookup[a['link']],
40
- 'level' => :user,
41
- 'type' => :filter,
42
- 'uri' => a['link']
43
- }
44
- c.create(GoodData::MandatoryUserFilter, payload, project: project)
45
- end
33
+ mufs = filters.map do |filter_data|
34
+ payload = {
35
+ 'expression' => filter_data['userFilter']['content']['expression'],
36
+ 'related' => user_lookup[filter_data['userFilter']['meta']['uri']],
37
+ 'level' => :user,
38
+ 'type' => :filter,
39
+ 'uri' => filter_data['userFilter']['meta']['uri']
40
+ }
41
+ c.create(GoodData::MandatoryUserFilter, payload, project: project)
46
42
  end
43
+ mufs.enum_for
47
44
  end
48
45
 
49
46
  def count(options = { client: GoodData.connection, project: GoodData.project })
@@ -69,7 +66,7 @@ module GoodData
69
66
  }
70
67
  }
71
68
  res = client.post(project.md['obj'], data)
72
- @json['uri'] = res['uri']
69
+ @json[:uri] = res['uri']
73
70
  end
74
71
  end
75
72
  end
@@ -4,7 +4,7 @@ module GoodData
4
4
  class UserFilter < GoodData::MdObject
5
5
  def initialize(data)
6
6
  @dirty = false
7
- @json = data
7
+ @json = GoodData::Helpers.symbolize_keys(data)
8
8
  end
9
9
 
10
10
  def ==(other)
@@ -20,7 +20,7 @@ module GoodData
20
20
  #
21
21
  # @return [String] Uri of related object
22
22
  def related_uri
23
- @json['related']
23
+ @json[:related]
24
24
  end
25
25
 
26
26
  # Returns the the object of this filter is related to. It can be either project or a user
@@ -35,7 +35,7 @@ module GoodData
35
35
  #
36
36
  # @return [GoodData::Project | GoodData::Profile] Related object
37
37
  def variable
38
- uri = @json['prompt']
38
+ uri = @json[:prompt]
39
39
  GoodData::Variable[uri, client: client, project: project]
40
40
  end
41
41
 
@@ -46,14 +46,14 @@ module GoodData
46
46
  #
47
47
  # @return [Symbol] level on which this filter will be applied
48
48
  def level
49
- @json['level'].to_sym
49
+ @json[:level].to_sym
50
50
  end
51
51
 
52
52
  # Returns the MAQL expression of the filter
53
53
  #
54
54
  # @return [String] MAQL expression
55
55
  def expression
56
- @json['expression']
56
+ @json[:expression]
57
57
  end
58
58
 
59
59
  # Allows to set the MAQL expression of the filter
@@ -62,21 +62,21 @@ module GoodData
62
62
  # @return [String] MAQL expression
63
63
  def expression=(expression)
64
64
  @dirty = true
65
- @json['expression'] = expression
65
+ @json[:expression] = expression
66
66
  end
67
67
 
68
68
  # Gives you URI of the filter
69
69
  #
70
70
  # @return [String]
71
71
  def uri
72
- @json['uri']
72
+ @json[:uri]
73
73
  end
74
74
 
75
75
  # Allows to set URI of the filter
76
76
  #
77
77
  # @return [String]
78
78
  def uri=(uri)
79
- @json['uri'] = uri
79
+ @json[:uri] = uri
80
80
  end
81
81
 
82
82
  # Returns pretty version of the expression