gooddata-edge 0.6.27.edge

Sign up to get free protection for your applications and to get access to all the features.
Files changed (364) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +36 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +89 -0
  6. data/.yardopts +22 -0
  7. data/CHANGELOG.md +196 -0
  8. data/CLI.md +439 -0
  9. data/DEPENDENCIES.md +817 -0
  10. data/Gemfile +4 -0
  11. data/Guardfile +5 -0
  12. data/LICENSE +22 -0
  13. data/LICENSE.rb +5 -0
  14. data/README.md +75 -0
  15. data/Rakefile +179 -0
  16. data/TODO.md +32 -0
  17. data/authors.sh +4 -0
  18. data/bin/gooddata +7 -0
  19. data/dependency_decisions.yml +104 -0
  20. data/gooddata +9 -0
  21. data/gooddata.gemspec +63 -0
  22. data/lib/gooddata.rb +31 -0
  23. data/lib/gooddata/app/app.rb +16 -0
  24. data/lib/gooddata/bricks/base_downloader.rb +86 -0
  25. data/lib/gooddata/bricks/brick.rb +38 -0
  26. data/lib/gooddata/bricks/bricks.rb +15 -0
  27. data/lib/gooddata/bricks/middleware/aws_middleware.rb +29 -0
  28. data/lib/gooddata/bricks/middleware/base_middleware.rb +56 -0
  29. data/lib/gooddata/bricks/middleware/bench_middleware.rb +24 -0
  30. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +37 -0
  31. data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +20 -0
  32. data/lib/gooddata/bricks/middleware/fs_download_middleware.rb +48 -0
  33. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +36 -0
  34. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +39 -0
  35. data/lib/gooddata/bricks/middleware/logger_middleware.rb +29 -0
  36. data/lib/gooddata/bricks/middleware/middleware.rb +12 -0
  37. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +61 -0
  38. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +23 -0
  39. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +29 -0
  40. data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +37 -0
  41. data/lib/gooddata/bricks/pipeline.rb +32 -0
  42. data/lib/gooddata/bricks/utils.rb +18 -0
  43. data/lib/gooddata/cli/cli.rb +27 -0
  44. data/lib/gooddata/cli/commands/auth_cmd.rb +29 -0
  45. data/lib/gooddata/cli/commands/domain_cmd.rb +28 -0
  46. data/lib/gooddata/cli/commands/project_cmd.rb +45 -0
  47. data/lib/gooddata/cli/hooks.rb +57 -0
  48. data/lib/gooddata/cli/shared.rb +61 -0
  49. data/lib/gooddata/cli/terminal.rb +20 -0
  50. data/lib/gooddata/client.rb +67 -0
  51. data/lib/gooddata/commands/api.rb +64 -0
  52. data/lib/gooddata/commands/auth.rb +107 -0
  53. data/lib/gooddata/commands/base.rb +12 -0
  54. data/lib/gooddata/commands/commands.rb +12 -0
  55. data/lib/gooddata/commands/datasets.rb +148 -0
  56. data/lib/gooddata/commands/datawarehouse.rb +20 -0
  57. data/lib/gooddata/commands/domain.rb +40 -0
  58. data/lib/gooddata/commands/process.rb +67 -0
  59. data/lib/gooddata/commands/project.rb +175 -0
  60. data/lib/gooddata/commands/projects.rb +20 -0
  61. data/lib/gooddata/commands/role.rb +36 -0
  62. data/lib/gooddata/commands/runners.rb +47 -0
  63. data/lib/gooddata/commands/scaffold.rb +69 -0
  64. data/lib/gooddata/commands/user.rb +39 -0
  65. data/lib/gooddata/connection.rb +127 -0
  66. data/lib/gooddata/core/core.rb +12 -0
  67. data/lib/gooddata/core/logging.rb +105 -0
  68. data/lib/gooddata/core/nil_logger.rb +23 -0
  69. data/lib/gooddata/core/project.rb +74 -0
  70. data/lib/gooddata/core/rest.rb +149 -0
  71. data/lib/gooddata/core/user.rb +20 -0
  72. data/lib/gooddata/data/data.rb +12 -0
  73. data/lib/gooddata/data/guesser.rb +122 -0
  74. data/lib/gooddata/exceptions/attr_element_not_found.rb +16 -0
  75. data/lib/gooddata/exceptions/command_failed.rb +11 -0
  76. data/lib/gooddata/exceptions/exceptions.rb +12 -0
  77. data/lib/gooddata/exceptions/execution_limit_exceeded.rb +13 -0
  78. data/lib/gooddata/exceptions/filter_maqlization.rb +16 -0
  79. data/lib/gooddata/exceptions/malformed_user.rb +15 -0
  80. data/lib/gooddata/exceptions/no_project_error.rb +15 -0
  81. data/lib/gooddata/exceptions/object_migration.rb +32 -0
  82. data/lib/gooddata/exceptions/project_not_found.rb +13 -0
  83. data/lib/gooddata/exceptions/segment_not_empty.rb +18 -0
  84. data/lib/gooddata/exceptions/uncomputable_report.rb +13 -0
  85. data/lib/gooddata/exceptions/user_in_different_domain.rb +15 -0
  86. data/lib/gooddata/exceptions/validation_error.rb +16 -0
  87. data/lib/gooddata/extensions/big_decimal.rb +17 -0
  88. data/lib/gooddata/extensions/enumerable.rb +39 -0
  89. data/lib/gooddata/extensions/extensions.rb +10 -0
  90. data/lib/gooddata/extensions/false.rb +15 -0
  91. data/lib/gooddata/extensions/hash.rb +38 -0
  92. data/lib/gooddata/extensions/nil.rb +15 -0
  93. data/lib/gooddata/extensions/numeric.rb +15 -0
  94. data/lib/gooddata/extensions/object.rb +27 -0
  95. data/lib/gooddata/extensions/symbol.rb +15 -0
  96. data/lib/gooddata/extensions/true.rb +15 -0
  97. data/lib/gooddata/extract.rb +21 -0
  98. data/lib/gooddata/goodzilla/goodzilla.rb +159 -0
  99. data/lib/gooddata/helpers/auth_helpers.rb +75 -0
  100. data/lib/gooddata/helpers/csv_helper.rb +61 -0
  101. data/lib/gooddata/helpers/data_helper.rb +116 -0
  102. data/lib/gooddata/helpers/global_helpers.rb +331 -0
  103. data/lib/gooddata/helpers/global_helpers_params.rb +172 -0
  104. data/lib/gooddata/helpers/helpers.rb +10 -0
  105. data/lib/gooddata/mixins/author.rb +26 -0
  106. data/lib/gooddata/mixins/content_getter.rb +15 -0
  107. data/lib/gooddata/mixins/content_property_reader.rb +17 -0
  108. data/lib/gooddata/mixins/content_property_writer.rb +17 -0
  109. data/lib/gooddata/mixins/contributor.rb +20 -0
  110. data/lib/gooddata/mixins/data_getter.rb +15 -0
  111. data/lib/gooddata/mixins/data_property_reader.rb +19 -0
  112. data/lib/gooddata/mixins/data_property_writer.rb +19 -0
  113. data/lib/gooddata/mixins/inspector.rb +53 -0
  114. data/lib/gooddata/mixins/is_attribute.rb +17 -0
  115. data/lib/gooddata/mixins/is_dimension.rb +17 -0
  116. data/lib/gooddata/mixins/is_fact.rb +17 -0
  117. data/lib/gooddata/mixins/is_label.rb +19 -0
  118. data/lib/gooddata/mixins/links.rb +15 -0
  119. data/lib/gooddata/mixins/md_finders.rb +77 -0
  120. data/lib/gooddata/mixins/md_grantees.rb +42 -0
  121. data/lib/gooddata/mixins/md_id_to_uri.rb +34 -0
  122. data/lib/gooddata/mixins/md_json.rb +15 -0
  123. data/lib/gooddata/mixins/md_lock.rb +87 -0
  124. data/lib/gooddata/mixins/md_object_id.rb +15 -0
  125. data/lib/gooddata/mixins/md_object_indexer.rb +64 -0
  126. data/lib/gooddata/mixins/md_object_query.rb +128 -0
  127. data/lib/gooddata/mixins/md_relations.rb +43 -0
  128. data/lib/gooddata/mixins/meta_getter.rb +17 -0
  129. data/lib/gooddata/mixins/meta_property_reader.rb +19 -0
  130. data/lib/gooddata/mixins/meta_property_writer.rb +19 -0
  131. data/lib/gooddata/mixins/mixins.rb +19 -0
  132. data/lib/gooddata/mixins/not_attribute.rb +17 -0
  133. data/lib/gooddata/mixins/not_exportable.rb +15 -0
  134. data/lib/gooddata/mixins/not_fact.rb +17 -0
  135. data/lib/gooddata/mixins/not_group.rb +17 -0
  136. data/lib/gooddata/mixins/not_label.rb +19 -0
  137. data/lib/gooddata/mixins/not_metric.rb +19 -0
  138. data/lib/gooddata/mixins/obj_id.rb +15 -0
  139. data/lib/gooddata/mixins/rest_getters.rb +17 -0
  140. data/lib/gooddata/mixins/rest_resource.rb +47 -0
  141. data/lib/gooddata/mixins/root_key_getter.rb +15 -0
  142. data/lib/gooddata/mixins/root_key_setter.rb +15 -0
  143. data/lib/gooddata/mixins/timestamps.rb +19 -0
  144. data/lib/gooddata/mixins/to_json.rb +11 -0
  145. data/lib/gooddata/mixins/uri_getter.rb +9 -0
  146. data/lib/gooddata/models/blueprint/anchor_field.rb +64 -0
  147. data/lib/gooddata/models/blueprint/attribute_field.rb +29 -0
  148. data/lib/gooddata/models/blueprint/blueprint.rb +11 -0
  149. data/lib/gooddata/models/blueprint/blueprint_field.rb +70 -0
  150. data/lib/gooddata/models/blueprint/dashboard_builder.rb +30 -0
  151. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +449 -0
  152. data/lib/gooddata/models/blueprint/date_dimension.rb +14 -0
  153. data/lib/gooddata/models/blueprint/fact_field.rb +20 -0
  154. data/lib/gooddata/models/blueprint/label_field.rb +43 -0
  155. data/lib/gooddata/models/blueprint/project_blueprint.rb +746 -0
  156. data/lib/gooddata/models/blueprint/project_builder.rb +83 -0
  157. data/lib/gooddata/models/blueprint/reference_field.rb +43 -0
  158. data/lib/gooddata/models/blueprint/schema_blueprint.rb +160 -0
  159. data/lib/gooddata/models/blueprint/schema_builder.rb +89 -0
  160. data/lib/gooddata/models/blueprint/to_manifest.rb +181 -0
  161. data/lib/gooddata/models/blueprint/to_wire.rb +154 -0
  162. data/lib/gooddata/models/client.rb +182 -0
  163. data/lib/gooddata/models/client_synchronization_result.rb +31 -0
  164. data/lib/gooddata/models/client_synchronization_result_details.rb +41 -0
  165. data/lib/gooddata/models/datawarehouse.rb +92 -0
  166. data/lib/gooddata/models/domain.rb +479 -0
  167. data/lib/gooddata/models/execution.rb +115 -0
  168. data/lib/gooddata/models/execution_detail.rb +81 -0
  169. data/lib/gooddata/models/from_wire.rb +160 -0
  170. data/lib/gooddata/models/invitation.rb +75 -0
  171. data/lib/gooddata/models/links.rb +50 -0
  172. data/lib/gooddata/models/membership.rb +441 -0
  173. data/lib/gooddata/models/metadata.rb +272 -0
  174. data/lib/gooddata/models/metadata/attribute.rb +134 -0
  175. data/lib/gooddata/models/metadata/dashboard.rb +108 -0
  176. data/lib/gooddata/models/metadata/dashboard/dashboard_item.rb +76 -0
  177. data/lib/gooddata/models/metadata/dashboard/filter_apply_item.rb +37 -0
  178. data/lib/gooddata/models/metadata/dashboard/filter_item.rb +64 -0
  179. data/lib/gooddata/models/metadata/dashboard/geo_chart_item.rb +56 -0
  180. data/lib/gooddata/models/metadata/dashboard/headline_item.rb +56 -0
  181. data/lib/gooddata/models/metadata/dashboard/iframe_item.rb +46 -0
  182. data/lib/gooddata/models/metadata/dashboard/report_item.rb +92 -0
  183. data/lib/gooddata/models/metadata/dashboard/text_item.rb +55 -0
  184. data/lib/gooddata/models/metadata/dashboard_tab.rb +141 -0
  185. data/lib/gooddata/models/metadata/dataset.rb +64 -0
  186. data/lib/gooddata/models/metadata/dimension.rb +54 -0
  187. data/lib/gooddata/models/metadata/fact.rb +44 -0
  188. data/lib/gooddata/models/metadata/label.rb +128 -0
  189. data/lib/gooddata/models/metadata/metadata.rb +12 -0
  190. data/lib/gooddata/models/metadata/metric.rb +198 -0
  191. data/lib/gooddata/models/metadata/report.rb +247 -0
  192. data/lib/gooddata/models/metadata/report_definition.rb +264 -0
  193. data/lib/gooddata/models/metadata/scheduled_mail.rb +274 -0
  194. data/lib/gooddata/models/metadata/scheduled_mail/dashboard_attachment.rb +62 -0
  195. data/lib/gooddata/models/metadata/scheduled_mail/report_attachment.rb +64 -0
  196. data/lib/gooddata/models/metadata/variable.rb +91 -0
  197. data/lib/gooddata/models/model.rb +282 -0
  198. data/lib/gooddata/models/models.rb +12 -0
  199. data/lib/gooddata/models/module_constants.rb +31 -0
  200. data/lib/gooddata/models/process.rb +316 -0
  201. data/lib/gooddata/models/profile.rb +426 -0
  202. data/lib/gooddata/models/project.rb +1514 -0
  203. data/lib/gooddata/models/project_creator.rb +126 -0
  204. data/lib/gooddata/models/project_metadata.rb +67 -0
  205. data/lib/gooddata/models/project_role.rb +79 -0
  206. data/lib/gooddata/models/report_data_result.rb +266 -0
  207. data/lib/gooddata/models/schedule.rb +518 -0
  208. data/lib/gooddata/models/segment.rb +201 -0
  209. data/lib/gooddata/models/tab_builder.rb +27 -0
  210. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +76 -0
  211. data/lib/gooddata/models/user_filters/user_filter.rb +100 -0
  212. data/lib/gooddata/models/user_filters/user_filter_builder.rb +512 -0
  213. data/lib/gooddata/models/user_filters/user_filters.rb +13 -0
  214. data/lib/gooddata/models/user_filters/variable_user_filter.rb +31 -0
  215. data/lib/gooddata/models/user_group.rb +241 -0
  216. data/lib/gooddata/rest/README.md +37 -0
  217. data/lib/gooddata/rest/client.rb +389 -0
  218. data/lib/gooddata/rest/connection.rb +765 -0
  219. data/lib/gooddata/rest/object.rb +69 -0
  220. data/lib/gooddata/rest/object_factory.rb +76 -0
  221. data/lib/gooddata/rest/resource.rb +27 -0
  222. data/lib/gooddata/rest/rest.rb +24 -0
  223. data/lib/gooddata/version.rb +23 -0
  224. data/lib/templates/bricks/brick.rb.erb +7 -0
  225. data/lib/templates/bricks/main.rb.erb +5 -0
  226. data/lib/templates/project/Goodfile.erb +4 -0
  227. data/lib/templates/project/data/commits.csv +4 -0
  228. data/lib/templates/project/data/devs.csv +4 -0
  229. data/lib/templates/project/data/repos.csv +3 -0
  230. data/lib/templates/project/model/model.rb.erb +20 -0
  231. data/spec/bricks/bricks_spec.rb +112 -0
  232. data/spec/bricks/default-config.json +8 -0
  233. data/spec/data/.gooddata +4 -0
  234. data/spec/data/blueprints/additional_dataset_module.json +32 -0
  235. data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
  236. data/spec/data/blueprints/invalid_blueprint.json +103 -0
  237. data/spec/data/blueprints/m_n_model.json +104 -0
  238. data/spec/data/blueprints/model_module.json +25 -0
  239. data/spec/data/blueprints/test_blueprint.json +38 -0
  240. data/spec/data/blueprints/test_project_model_spec.json +106 -0
  241. data/spec/data/cc/data/source/commits.csv +4 -0
  242. data/spec/data/cc/data/source/devs.csv +4 -0
  243. data/spec/data/cc/data/source/repos.csv +3 -0
  244. data/spec/data/cc/devel.prm +0 -0
  245. data/spec/data/cc/graph/graph.grf +11 -0
  246. data/spec/data/cc/workspace.prm +19 -0
  247. data/spec/data/column_based_permissions.csv +7 -0
  248. data/spec/data/column_based_permissions2.csv +6 -0
  249. data/spec/data/gd_gse_data_blueprint.json +1371 -0
  250. data/spec/data/gd_gse_data_manifest.json +1424 -0
  251. data/spec/data/gd_gse_data_model.json +1772 -0
  252. data/spec/data/gooddata_version_process/gooddata_version.rb +9 -0
  253. data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
  254. data/spec/data/hello_world_process/hello_world.rb +9 -0
  255. data/spec/data/hello_world_process/hello_world.zip +0 -0
  256. data/spec/data/line_based_permissions.csv +3 -0
  257. data/spec/data/manifests/test_blueprint.json +32 -0
  258. data/spec/data/manifests/test_project.json +107 -0
  259. data/spec/data/reports/left_attr_report.json +108 -0
  260. data/spec/data/reports/metric_only_one_line.json +83 -0
  261. data/spec/data/reports/report_1.json +197 -0
  262. data/spec/data/reports/top_attr_report.json +108 -0
  263. data/spec/data/ruby_params_process/ruby_params.rb +9 -0
  264. data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
  265. data/spec/data/ruby_process/process.rb +8 -0
  266. data/spec/data/ruby_process/stuff.txt +1 -0
  267. data/spec/data/superfluous_titles_view.json +81 -0
  268. data/spec/data/test-ci-data.csv +2 -0
  269. data/spec/data/users.csv +12 -0
  270. data/spec/data/wire_models/model_view.json +1775 -0
  271. data/spec/data/wire_models/nu_model.json +3046 -0
  272. data/spec/data/wire_models/test_blueprint.json +63 -0
  273. data/spec/data/wire_test_project.json +150 -0
  274. data/spec/environment/default.rb +41 -0
  275. data/spec/environment/develop.rb +31 -0
  276. data/spec/environment/environment.rb +18 -0
  277. data/spec/environment/hotfix.rb +21 -0
  278. data/spec/environment/production.rb +35 -0
  279. data/spec/environment/release.rb +21 -0
  280. data/spec/environment/staging.rb +30 -0
  281. data/spec/environment/staging_3.rb +36 -0
  282. data/spec/helpers/blueprint_helper.rb +26 -0
  283. data/spec/helpers/cli_helper.rb +36 -0
  284. data/spec/helpers/connection_helper.rb +41 -0
  285. data/spec/helpers/crypto_helper.rb +17 -0
  286. data/spec/helpers/csv_helper.rb +18 -0
  287. data/spec/helpers/process_helper.rb +33 -0
  288. data/spec/helpers/project_helper.rb +59 -0
  289. data/spec/helpers/schedule_helper.rb +31 -0
  290. data/spec/helpers/spec_helper.rb +15 -0
  291. data/spec/integration/blueprint_updates_spec.rb +101 -0
  292. data/spec/integration/blueprint_with_grain_spec.rb +72 -0
  293. data/spec/integration/clients_spec.rb +134 -0
  294. data/spec/integration/command_datawarehouse_spec.rb +39 -0
  295. data/spec/integration/command_projects_spec.rb +32 -0
  296. data/spec/integration/create_from_template_spec.rb +22 -0
  297. data/spec/integration/create_project_spec.rb +24 -0
  298. data/spec/integration/date_dim_switch_spec.rb +142 -0
  299. data/spec/integration/deprecated_load_spec.rb +58 -0
  300. data/spec/integration/full_process_schedule_spec.rb +298 -0
  301. data/spec/integration/full_project_spec.rb +569 -0
  302. data/spec/integration/over_to_user_filters_spec.rb +94 -0
  303. data/spec/integration/partial_md_export_import_spec.rb +42 -0
  304. data/spec/integration/project_spec.rb +264 -0
  305. data/spec/integration/rest_spec.rb +213 -0
  306. data/spec/integration/schedule_spec.rb +626 -0
  307. data/spec/integration/segments_spec.rb +141 -0
  308. data/spec/integration/user_filters_spec.rb +290 -0
  309. data/spec/integration/user_group_spec.rb +127 -0
  310. data/spec/integration/variables_spec.rb +188 -0
  311. data/spec/logging_in_logging_out_spec.rb +93 -0
  312. data/spec/spec_helper.rb +95 -0
  313. data/spec/unit/bricks/bricks_spec.rb +35 -0
  314. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +51 -0
  315. data/spec/unit/bricks/middleware/bench_middleware_spec.rb +15 -0
  316. data/spec/unit/bricks/middleware/bulk_salesforce_middleware_spec.rb +15 -0
  317. data/spec/unit/bricks/middleware/gooddata_middleware_spec.rb +15 -0
  318. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
  319. data/spec/unit/bricks/middleware/restforce_middleware_spec.rb +15 -0
  320. data/spec/unit/bricks/middleware/stdout_middleware_spec.rb +15 -0
  321. data/spec/unit/bricks/middleware/twitter_middleware_spec.rb +15 -0
  322. data/spec/unit/cli/cli_spec.rb +17 -0
  323. data/spec/unit/cli/commands/cmd_auth_spec.rb +17 -0
  324. data/spec/unit/commands/command_projects_spec.rb +22 -0
  325. data/spec/unit/core/connection_spec.rb +57 -0
  326. data/spec/unit/core/logging_spec.rb +133 -0
  327. data/spec/unit/core/nil_logger_spec.rb +13 -0
  328. data/spec/unit/core/project_spec.rb +54 -0
  329. data/spec/unit/extensions/hash_spec.rb +23 -0
  330. data/spec/unit/godzilla/goodzilla_spec.rb +78 -0
  331. data/spec/unit/helpers/csv_helper_spec.rb +22 -0
  332. data/spec/unit/helpers/data_helper_spec.rb +61 -0
  333. data/spec/unit/helpers/global_helpers_spec.rb +111 -0
  334. data/spec/unit/helpers_spec.rb +86 -0
  335. data/spec/unit/models/blueprint/attributes_spec.rb +29 -0
  336. data/spec/unit/models/blueprint/dataset_spec.rb +121 -0
  337. data/spec/unit/models/blueprint/labels_spec.rb +44 -0
  338. data/spec/unit/models/blueprint/project_blueprint_spec.rb +648 -0
  339. data/spec/unit/models/blueprint/reference_spec.rb +29 -0
  340. data/spec/unit/models/blueprint/schema_builder_spec.rb +38 -0
  341. data/spec/unit/models/blueprint/to_wire_spec.rb +174 -0
  342. data/spec/unit/models/domain_spec.rb +144 -0
  343. data/spec/unit/models/execution_spec.rb +108 -0
  344. data/spec/unit/models/from_wire_spec.rb +296 -0
  345. data/spec/unit/models/invitation_spec.rb +17 -0
  346. data/spec/unit/models/membership_spec.rb +132 -0
  347. data/spec/unit/models/metadata_spec.rb +104 -0
  348. data/spec/unit/models/metric_spec.rb +117 -0
  349. data/spec/unit/models/model_spec.rb +82 -0
  350. data/spec/unit/models/params_spec.rb +118 -0
  351. data/spec/unit/models/profile_spec.rb +215 -0
  352. data/spec/unit/models/project_creator_spec.rb +127 -0
  353. data/spec/unit/models/project_role_spec.rb +94 -0
  354. data/spec/unit/models/project_spec.rb +162 -0
  355. data/spec/unit/models/report_result_data_spec.rb +199 -0
  356. data/spec/unit/models/schedule_spec.rb +418 -0
  357. data/spec/unit/models/to_manifest_spec.rb +63 -0
  358. data/spec/unit/models/unit_project_spec.rb +125 -0
  359. data/spec/unit/models/user_filters_spec.rb +95 -0
  360. data/spec/unit/models/variable_spec.rb +265 -0
  361. data/spec/unit/rest/polling_spec.rb +89 -0
  362. data/spec/unit/rest/resource_spec.rb +10 -0
  363. data/yard-server.sh +3 -0
  364. metadata +1125 -0
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../metadata'
8
+ require_relative '../../mixins/is_dimension'
9
+ require_relative 'metadata'
10
+
11
+ module GoodData
12
+ class Dimension < GoodData::MdObject
13
+ include Mixin::IsDimension
14
+
15
+ class << self
16
+ # Method intended to get all objects of that type in a specified project
17
+ #
18
+ # @param options [Hash] the options hash
19
+ # @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
20
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
21
+ def all(options = { :client => GoodData.connection, :project => GoodData.project })
22
+ query('dimension', Dimension, options)
23
+ end
24
+
25
+ # Returns a Project object identified by given string
26
+ # The following identifiers are accepted
27
+ # - /gdc/md/<id>
28
+ # - /gdc/projects/<id>
29
+ # - <id>
30
+ #
31
+ def [](id, opts = { client: GoodData.connection })
32
+ return id if id.instance_of?(GoodData::Dimension) || id.respond_to?(:dimension?) && id.dimension?
33
+
34
+ if id == :all
35
+ Dimension.all({ client: GoodData.connection }.merge(opts))
36
+ else
37
+ uri = id
38
+
39
+ c = client(opts)
40
+ fail ArgumentError, 'No :client specified' if c.nil?
41
+
42
+ response = c.get(uri)
43
+ c.factory.create(Dimension, response)
44
+ end
45
+ end
46
+ end
47
+
48
+ def attributes
49
+ content['attributes'].map do |attribute|
50
+ client.create(Attribute, { 'attribute' => attribute }, project: project)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../metadata'
8
+ require_relative '../../core/rest'
9
+ require_relative '../../mixins/is_fact'
10
+
11
+ require_relative 'metadata'
12
+
13
+ module GoodData
14
+ class Fact < GoodData::MdObject
15
+ include Mixin::IsFact
16
+
17
+ # TODO: verify that we have all (which we do not right now)
18
+ FACT_BASE_AGGREGATIONS = [:sum, :min, :max, :avg, :median, :runsum, :runmin, :runmax, :runavg, :runstdev, :runstdevp, :runvar, :runvarp, :stdev, :stdevp, :var, :varp]
19
+
20
+ class << self
21
+ # Method intended to get all objects of that type in a specified project
22
+ #
23
+ # @param options [Hash] the options hash
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
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
26
+ def all(options = { :client => GoodData.connection, :project => GoodData.project })
27
+ query('fact', Fact, options)
28
+ end
29
+ end
30
+
31
+ # Creates the basic count metric with the fact used. The metric created is not saved.
32
+ # @param [Hash] options the options to pass to the value list
33
+ # @option options [Symbol] :type type of aggregation function. Default is :sum
34
+ # @return [GoodData::Metric]
35
+ def create_metric(options = { :type => :sum })
36
+ a_type = options[:type] || :sum
37
+ fail "Suggested aggreagtion function (#{a_type}) does not exist for base metric created out of fact. You can use only one of #{FACT_BASE_AGGREGATIONS.map { |x| ':' + x.to_s }.join(',')}" unless FACT_BASE_AGGREGATIONS.include?(a_type)
38
+ a_title = options[:title] || "#{a_type} of #{title}"
39
+ project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}])", title: a_title, extended_notation: false)
40
+ end
41
+
42
+ alias_method :create_measure, :create_metric
43
+ end
44
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../metadata'
8
+ require_relative '../../mixins/is_label'
9
+ require_relative 'metadata'
10
+
11
+ module GoodData
12
+ class Label < GoodData::MdObject
13
+ include Mixin::IsLabel
14
+
15
+ # Finds an attribute element URI for given value. This URI can be used by find_element_value to find the original value again
16
+ # @param [String] value value of an label you are looking for
17
+ # @return [String]
18
+ def find_value_uri(value)
19
+ results = get_valid_elements(filter: value)
20
+ items = results['validElements']['items']
21
+ if items.empty?
22
+ fail(AttributeElementNotFound, value)
23
+ else
24
+ items.first['element']['uri']
25
+ end
26
+ end
27
+
28
+ # For an element id find values (titles) for this label. Element id can be given as both number id or URI as a string beginning with /
29
+ # @param [Object] element_id Element identifier either Number or a uri as a String
30
+ # @return [String] value of the element if found
31
+ def find_element_value(element_id)
32
+ element_id = element_id.is_a?(String) ? element_id.match(/\?id=(\d+)/)[1] : element_id
33
+ uri = links['elements']
34
+ result = client.get(uri + "/?id=#{element_id}")
35
+ items = result['attributeElements']['elements']
36
+ if items.empty?
37
+ fail(AttributeElementNotFound, element_id)
38
+ else
39
+ items.first['title']
40
+ end
41
+ end
42
+
43
+ # Gets valid elements using /validElements? API
44
+ # @return [Array] Results
45
+ def get_valid_elements(url_or_params = {}, request_payload = {})
46
+ final_url = url_or_params
47
+
48
+ if url_or_params.is_a?(Hash)
49
+ default_params = {
50
+ limit: 1,
51
+ offset: 0,
52
+ order: 'asc'
53
+ }
54
+ params = default_params.merge(url_or_params).map { |x, v| "#{x}=#{CGI.escape(v.to_s)}" }.reduce { |a, e| "#{a}&#{e}" }
55
+ final_url = "#{uri}/validElements?#{params}"
56
+ end
57
+
58
+ results = client.post(final_url, 'validElementsRequest' => request_payload)
59
+
60
+ # Implementation of polling is based on
61
+ # https://opengrok.intgdc.com/source/xref/gdc-backend/src/test/java/com/gooddata/service/dao/ValidElementsDaoTest.java
62
+ status_url = results['uri']
63
+ if status_url
64
+ results = client.poll_on_response(status_url) do |body|
65
+ status = body['taskState'] && body['taskState']['status']
66
+ status == 'RUNNING' || status == 'PREPARED'
67
+ end
68
+ end
69
+
70
+ results
71
+ end
72
+
73
+ # Finds if a label has an attribute element for given value.
74
+ # @param [String] value value of an label you are looking for
75
+ # @return [Boolean]
76
+ def value?(value)
77
+ find_value_uri(value)
78
+ true
79
+ rescue AttributeElementNotFound
80
+ false
81
+ end
82
+
83
+ # Returns all values for this label. This is for inspection purposes only since obviously there can be huge number of elements.
84
+ # @param [Hash] options the options to pass to the value list
85
+ # @option options [Number] :limit limits the number of values to certain number. Default is 100
86
+ # @return [Array]
87
+ def values(options = {})
88
+ Enumerator.new do |y|
89
+ offset = options[:offset] || 0
90
+ page_limit = options[:limit] || 100
91
+ loop do
92
+ results = get_valid_elements(limit: page_limit, offset: offset)
93
+
94
+ elements = results['validElements']
95
+ elements['items'].map do |el|
96
+ v = el['element']
97
+ y << {
98
+ :value => v['title'],
99
+ :uri => v['uri']
100
+ }
101
+ end
102
+ break if elements['items'].count < page_limit
103
+ offset += page_limit
104
+ end
105
+ end
106
+ end
107
+
108
+ def values_count
109
+ results = get_valid_elements
110
+ count = GoodData::Helpers.get_path(results, %w(validElements paging total))
111
+ count && count.to_i
112
+ end
113
+
114
+ # Gives an attribute of current label
115
+ # @return [GoodData::Attibute]
116
+ def attribute
117
+ project.attributes(content['formOf'])
118
+ end
119
+
120
+ # Gives an attribute url of current label. Useful for mass actions when it does not introduce HTTP call.
121
+ # @return [GoodData::Attibute]
122
+ def attribute_uri
123
+ content['formOf']
124
+ end
125
+ end
126
+ end
127
+
128
+ GoodData::DisplayForm = GoodData::Label
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'pathname'
8
+
9
+ base = Pathname(__FILE__).dirname.expand_path
10
+ Dir.glob(base + '*.rb').each do |file|
11
+ require file
12
+ end
@@ -0,0 +1,198 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../../goodzilla/goodzilla'
8
+ require_relative '../../mixins/mixins'
9
+ require_relative '../metadata'
10
+ require_relative 'metadata'
11
+
12
+ module GoodData
13
+ # Metric representation
14
+ class Metric < MdObject
15
+ include Mixin::Lockable
16
+
17
+ class << self
18
+ # Method intended to get all objects of that type in a specified project
19
+ #
20
+ # @param options [Hash] the options hash
21
+ # @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
22
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
23
+ def all(options = { :client => GoodData.connection, :project => GoodData.project })
24
+ query('metric', Metric, options)
25
+ end
26
+
27
+ def xcreate(metric, options = { :client => GoodData.connection, :project => GoodData.project })
28
+ create(metric, { extended_notation: true }.merge(options))
29
+ end
30
+
31
+ def create(metric, options = { :client => GoodData.connection, :project => GoodData.project })
32
+ client, project = GoodData.get_client_and_project(options)
33
+
34
+ if metric.is_a?(String)
35
+ expression = metric || options[:expression]
36
+ extended_notation = options[:extended_notation] || false
37
+ title = options[:title]
38
+ summary = options[:summary]
39
+ else
40
+ metric ||= options
41
+ title = metric[:title] || options[:title]
42
+ summary = metric[:summary] || options[:summary]
43
+ expression = metric[:expression] || options[:expression] || fail('Metric has to have its expression defined')
44
+ extended_notation = metric[:extended_notation] || options[:extended_notation] || false
45
+ end
46
+
47
+ expression = if extended_notation
48
+ dict = {
49
+ :facts => project.facts.reduce({}) do |memo, item|
50
+ memo[item.title] = item.uri
51
+ memo
52
+ end,
53
+ :attributes => project.attributes.reduce({}) do |memo, item|
54
+ memo[item.title] = item.uri
55
+ memo
56
+ end,
57
+ :metrics => project.metrics.reduce({}) do |memo, item|
58
+ memo[item.title] = item.uri
59
+ memo
60
+ end
61
+ }
62
+ interpolated_metric = GoodData::SmallGoodZilla.interpolate_metric(expression, dict, options)
63
+ interpolated_metric
64
+ else
65
+ expression
66
+ end
67
+
68
+ metric = {
69
+ 'metric' => {
70
+ 'content' => {
71
+ 'format' => '#,##0',
72
+ 'expression' => expression
73
+ },
74
+ 'meta' => {
75
+ 'tags' => '',
76
+ 'summary' => summary,
77
+ 'title' => title
78
+ }
79
+ }
80
+ }
81
+ # TODO: add test for explicitly provided identifier
82
+ metric['metric']['meta']['identifier'] = options[:identifier] if options[:identifier]
83
+
84
+ client.create(Metric, metric, :project => project)
85
+ end
86
+
87
+ def execute(expression, options = { :client => GoodData.connection })
88
+ # client = options[:client]
89
+ # fail ArgumentError, 'No :client specified' if client.nil?
90
+
91
+ options = expression if expression.is_a?(Hash)
92
+
93
+ m = if expression.is_a?(String)
94
+ tmp = {
95
+ :title => 'Temporary metric to be deleted',
96
+ :expression => expression
97
+ }.merge(options)
98
+
99
+ GoodData::Metric.create(tmp, options)
100
+ else
101
+ tmp = {
102
+ :title => 'Temporary metric to be deleted'
103
+ }.merge(expression)
104
+ GoodData::Metric.create(tmp, options)
105
+ end
106
+ m.execute
107
+ end
108
+
109
+ def xexecute(expression, opts = { :client => GoodData.connection, :project => GoodData.project })
110
+ GoodData.get_client_and_project(opts)
111
+
112
+ execute(expression, opts.merge(:extended_notation => true))
113
+ end
114
+ end
115
+
116
+ def execute
117
+ opts = {
118
+ :client => client,
119
+ :project => project
120
+ }
121
+ res = GoodData::ReportDefinition.execute(opts.merge(:left => self))
122
+ res.data[0][0] if res && !res.empty?
123
+ end
124
+
125
+ def expression
126
+ content['expression']
127
+ end
128
+
129
+ def expression=(value)
130
+ content['expression'] = value
131
+ end
132
+
133
+ def validate
134
+ fail 'Metric needs to have title' if title.nil?
135
+ true
136
+ end
137
+
138
+ def metric?
139
+ true
140
+ end
141
+
142
+ # Checks that the expression contains certain metadata object. The difference between this and used_by using is in the fact that this is not a transitive closure. it searches only inside the expression
143
+ # @param [GoodData::MdObject] item Object that is going to be looked up
144
+ # @return [Boolean]
145
+ def contain?(item)
146
+ uri = item.respond_to?(:uri) ? item.uri : item
147
+ expression[uri] != nil
148
+ end
149
+
150
+ # Checks that the expression contains certain element of an attribute. The value is looked up through given label.
151
+ # @param [GoodData::Label] label Label though which the value is looked up
152
+ # @param [String] value Value that will be looked up through the label.
153
+ # @return [Boolean]
154
+ def contain_value?(label, value)
155
+ uri = label.find_value_uri(value)
156
+ contain?(uri)
157
+ end
158
+
159
+ # Method used for replacing values in their state according to mapping. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.
160
+ #
161
+ # @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
162
+ # @return [GoodData::Metric]
163
+ def replace(mapping)
164
+ x = GoodData::MdObject.replace_quoted(self, mapping)
165
+ x = GoodData::MdObject.replace_bracketed(x, mapping)
166
+ vals = GoodData::MdObject.find_replaceable_values(x, mapping)
167
+ GoodData::MdObject.replace_bracketed(x, vals)
168
+ end
169
+
170
+ # Method used for replacing attribute element values. Looks up certain value of a label in the MAQL expression and exchanges it for a different value of the same label.
171
+ # @param [GoodData::Label] label Label through which the value and for_value are resolved
172
+ # @param [String] value value that is going to be replaced
173
+ # @param [String] for_value value that is going to be the new one
174
+ # @return [GoodData::Metric]
175
+ def replace_value(label, value, for_label, for_value = nil)
176
+ label = label.respond_to?(:primary_label) ? label.primary_label : label
177
+ if for_value
178
+ for_label = for_label.respond_to?(:primary_label) ? for_label.primary_label : for_label
179
+ value_uri = label.find_value_uri(value)
180
+ for_value_uri = for_label.find_value_uri(for_value)
181
+ self.expression = expression.gsub(value_uri, for_value_uri)
182
+ self.expression = expression.gsub(label.attribute.uri, for_label.attribute.uri)
183
+ else
184
+ for_value = for_label
185
+ value_uri = label.find_value_uri(value)
186
+ for_value_uri = label.find_value_uri(for_value)
187
+ self.expression = expression.gsub(value_uri, for_value_uri)
188
+ end
189
+ self
190
+ end
191
+
192
+ # Looks up the readable values of the objects used inside of MAQL epxpressions. Labels and elements titles are based on the primary label.
193
+ # @return [String] Ther resulting MAQL like expression
194
+ def pretty_expression
195
+ SmallGoodZilla.pretty_print(expression, client: client, project: project)
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,247 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../metadata'
8
+ require_relative 'metadata'
9
+
10
+ module GoodData
11
+ class Report < GoodData::MdObject
12
+ include Mixin::Lockable
13
+
14
+ class << self
15
+ # Method intended to get all objects of that type in a specified project
16
+ #
17
+ # @param options [Hash] the options hash
18
+ # @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
19
+ # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
20
+ def all(options = { :client => GoodData.connection, :project => GoodData.project })
21
+ query('report', Report, options)
22
+ end
23
+
24
+ def create(options = { :client => GoodData.connection, :project => GoodData.project })
25
+ client, project = GoodData.get_client_and_project(options)
26
+
27
+ title = options[:title]
28
+ fail 'Report needs a title specified' unless title
29
+ summary = options[:summary] || ''
30
+
31
+ options_rd = options.dup
32
+ options_rd.delete(:identifier)
33
+
34
+ rd = options[:rd] || ReportDefinition.create(options_rd)
35
+ rd.save
36
+
37
+ report = {
38
+ 'report' => {
39
+ 'content' => {
40
+ 'domains' => [],
41
+ 'definitions' => [rd.uri]
42
+ },
43
+ 'meta' => {
44
+ 'tags' => '',
45
+ 'deprecated' => '0',
46
+ 'summary' => summary,
47
+ 'title' => title
48
+ }
49
+ }
50
+ }
51
+ # TODO: write test for report definitions with explicit identifiers
52
+ report['report']['meta']['identifier'] = options[:identifier] if options[:identifier]
53
+ client.create(Report, report, :project => project)
54
+ end
55
+
56
+ def data_result(result, options = {})
57
+ client = options[:client]
58
+ data_result_uri = result['execResult']['dataResult']
59
+ begin
60
+ result = client.poll_on_response(data_result_uri, options) do |body|
61
+ body && body['taskState'] && body['taskState']['status'] == 'WAIT'
62
+ end
63
+ rescue RestClient::BadRequest => e
64
+ resp = JSON.parse(e.response)
65
+ if GoodData::Helpers.get_path(resp, %w(error component)) == 'MD::DataResult'
66
+ raise GoodData::UncomputableReport
67
+ else
68
+ raise e
69
+ end
70
+ end
71
+
72
+ if result.empty?
73
+ ReportDataResult.new(data: [], top: 0, left: 0)
74
+ else
75
+ ReportDataResult.from_xtab(result)
76
+ end
77
+ end
78
+ end
79
+
80
+ # Add a report definition to a report. This will show on a UI as a new version.
81
+ #
82
+ # @param report_definition [GoodData::ReportDefinition | String] Report definition to add. Either it can be a URI of a report definition or an actual report definition object.
83
+ # @return [GoodData::Report] Return self
84
+ def add_definition(report_definition)
85
+ rep_def = project.report_definitions(report_definition)
86
+ content['definitions'] = definition_uris << rep_def.uri
87
+ self
88
+ end
89
+
90
+ # Add a report definition to a report. This will show on a UI as a new version.
91
+ #
92
+ # @param report_definition [GoodData::ReportDefinition | String] Report definition to add. Either it can be a URI of a report definition or an actual report definition object.
93
+ # @return [GoodData::Report] Return self
94
+ def add_definition!(report_definition)
95
+ res = add_definition(report_definition)
96
+ res.save
97
+ end
98
+
99
+ # Returns the newest (current version) report definition as an object
100
+ #
101
+ # @return [GoodData::ReportDefinition] Returns the newest report defintion
102
+ def definition
103
+ project.report_definitions(latest_report_definition_uri)
104
+ end
105
+
106
+ alias_method :latest_report_definition, :definition
107
+
108
+ # Returns the newest (current version) report definition uri
109
+ #
110
+ # @return [String] Returns uri of the newest report defintion
111
+ def definition_uri
112
+ definition_uris.last
113
+ end
114
+
115
+ alias_method :latest_report_definition_uri, :definition_uri
116
+
117
+ # Gets a report definitions (versions) of this report as objects.
118
+ #
119
+ # @return [Array<GoodData::ReportDefinition>] Returns list of report definitions. Oldest comes first
120
+ def definitions
121
+ content['definitions'].pmap { |uri| project.report_definitions(uri) }
122
+ end
123
+ alias_method :report_definitions, :definitions
124
+
125
+ # Gets list of uris of report definitions (versions) of this report.
126
+ #
127
+ # @return [Array<String>] Returns list of report definitions' uris. Oldest comes first
128
+ def definition_uris
129
+ content['definitions']
130
+ end
131
+
132
+ # Deletes report along with its report definitions.
133
+ #
134
+ # @return [GoodData::Report] Returns self
135
+ def delete
136
+ defs = definitions
137
+ super
138
+ defs.peach(&:delete)
139
+ self
140
+ end
141
+
142
+ # Computes the report and returns the result. If it is not computable returns nil.
143
+ #
144
+ # @return [GoodData::DataResult] Returns the result
145
+ def execute(options = {})
146
+ fail 'You have to save the report before executing. If you do not want to do that please use GoodData::ReportDefinition' unless saved?
147
+ result = client.post '/gdc/xtab2/executor3', 'report_req' => { 'report' => uri }
148
+ GoodData::Report.data_result(result, options.merge(client: client))
149
+ end
150
+
151
+ # Returns true if you can export and object
152
+ #
153
+ # @return [Boolean] Returns whether the report is exportable
154
+ def exportable?
155
+ true
156
+ end
157
+
158
+ # Returns binary data of the exported report in a given format. The format can be
159
+ # either 'csv', 'xls', 'xlsx' or 'pdf'.
160
+ #
161
+ # @return [String] Returns data
162
+ def export(format, options = {})
163
+ result = client.post('/gdc/xtab2/executor3', 'report_req' => { 'report' => uri })
164
+ result1 = client.post('/gdc/exporter/executor', :result_req => { :format => format, :result => result })
165
+ client.poll_on_code(result1['uri'], options.merge(process: false))
166
+ end
167
+
168
+ # Returns the newest (current version) report definition uri
169
+ #
170
+ # @return [String] Returns uri of the newest report defintion
171
+ def purge_report_of_unused_definitions!
172
+ full_list = definition_uris
173
+ remove_definition_but_latest
174
+ purged_list = definition_uris
175
+ to_remove = full_list - purged_list
176
+ save
177
+ to_remove.each { |uri| client.delete(uri) }
178
+ self
179
+ end
180
+
181
+ # Removes definition from the report. The definition to remove can be passed in any form that is accepted by
182
+ # GoodData::ReportDefintion[]
183
+ #
184
+ # @param definition [String | GoodData::ReportDefinition] Report defintion to remove
185
+ # @return [GoodData::Report] Returns report with removed definition
186
+ def remove_definition(definition)
187
+ a_def = GoodData::ReportDefinition[definition, project: project, client: client]
188
+ def_uri = a_def.uri
189
+ content['definitions'] = definition_uris.reject { |x| x == def_uri }
190
+ self
191
+ end
192
+
193
+ # TODO: Cover with test. You would probably need something that will be able to create a report easily from a definition
194
+ # Removes all definitions but the latest from the report. This is useful for cleaning up before you create
195
+ # a template out of a project.
196
+ #
197
+ # @return [GoodData::Report] Returns report with removed definitions
198
+ def remove_definition_but_latest
199
+ to_remove = definition_uris - [latest_report_definition_uri]
200
+ to_remove.each do |uri|
201
+ remove_definition(uri)
202
+ end
203
+ self
204
+ end
205
+
206
+ # Method used for replacing values in their state according to mapping. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.
207
+ #
208
+ # @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
209
+ # @return [GoodData::Report]
210
+ def replace(mapping)
211
+ new_defs = definitions.map do |rep_def|
212
+ rep_def.replace(mapping)
213
+ end
214
+ new_defs.pmap(&:save)
215
+ self
216
+ end
217
+
218
+ ## Update report definition and reflect the change in report
219
+ #
220
+ # @param [Hash] opts Options
221
+ # @option opts [Boolean] :new_definition (true) If true then new definition will be created
222
+ # @return [GoodData::ReportDefinition] Updated and saved report definition
223
+ def update_definition(opts = { :new_definition => true }, &block)
224
+ # TODO: Cache the latest report definition somehow
225
+ repdef = definition.dup
226
+
227
+ block.call(repdef, self) if block_given?
228
+
229
+ if opts[:new_definition]
230
+ new_def = GoodData::ReportDefinition.create(:client => client, :project => project)
231
+
232
+ rd = repdef.json['reportDefinition']
233
+ rd.delete('links')
234
+ %w(author uri created identifier updated contributor).each { |k| rd['meta'].delete(k) }
235
+ new_def.json['reportDefinition'] = rd
236
+ new_def.save
237
+
238
+ add_definition!(new_def)
239
+ return new_def
240
+ else
241
+ repdef.save
242
+ end
243
+
244
+ repdef
245
+ end
246
+ end
247
+ end