# encoding: UTF-8 # # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved. # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. require 'date' require_relative '../data/guesser' require_relative '../extract' require_relative '../exceptions/command_failed' module GoodData module Command class Datasets # List all data sets present in the project specified by the --project option # # ## Usage # # gooddata datasets --project # gooddata datasets:list --project # # * `--project` - GoodData project identifier # def index # TODO: Review following connect replacement/reimplementation # connect with_project do |project_id| Project[project_id].datasets.each do |ds| puts "#{ds.uri}\t#{ds.identifier}\t#{ds.title}" end end end # Describe a data set. Currently, only a CSV data set is supported. # # The command prescans the data set, picks possible LDM types for it's # fields and asks user for confirmation. # # ## Usage # # gooddata datasets:describe --file-csv --name --output # # * `--file-csv` - path to the CSV file (required) # * `--name` - name of the data set (user will be prompted unless provided) # * `--output` - name of the output JSON file with the model description (user will be prompted unless provided) # def describe columns = ask_for_fields name = extract_option('--name') || ask('Enter the dataset name') output = extract_option('--output') || ask('Enter path to the file where to save the model description', :default => "#{name}.json") open output, 'w' do |f| f << JSON.pretty_generate(:title => name, :columns => columns) + "\n" f.flush end end # Creates a server-side model based on local model description. The model description # is read from a JSON file that can be generated using the +datasets:describe+ command # # ## Usage # # gooddata datasets:apply --project # # * `--project`- GoodData project identifier # * `data set config` - JSON file with the model description (possibly generated by the datasets:describe command) # def apply # TODO: Review following connect replacement/reimplementation # connect with_project do |project_id| begin cfg_file = args.shift rescue raise(CommandFailed, 'Invalid arguments') end fail(CommandFailed, "Usage: #{$PROGRAM_NAME} ") unless cfg_file config = begin JSON.parse open(cfg_file) rescue raise(CommandFailed, "Error reading dataset config file '#{cfg_file}'") end objects = Project[project_id].add_dataset config['title'], config['columns'] puts "Dataset #{config['title']} added to the project, #{objects['uris'].length} metadata objects affected" end end # Loads a CSV file into an existing server-side data set # # ## Usage # # gooddata datasets:load --project < # # * `--project` - GoodData project identifier # * `file` - CSV file to load # * `data set config` - JSON file with the model description (possibly generated by the datasets:describe command) # def load # TODO: Review following connect replacement/reimplementation # connect with_project do |project_id| file, cfg_file = args fail(CommandFailed, "Usage: #{$PROGRAM_NAME} datasets:load ") unless cfg_file begin config = JSON.parse open(cfg_file) rescue raise(CommandFailed, "Error reading dataset config file '#{cfg_file}'") end schema = Model::Schema.new config Project[project_id].upload file, schema end end private def with_project unless @project_id @project_id = extract_option('--project') fail(CommandFailed, 'Project not specified, use the --project switch') unless @project_id end yield @project_id end def ask_for_fields guesser = GoodData::Data::Guesser.new create_dataset.read guess = guesser.guess(1000) model = [] connection_point_set = false question_fmt = 'Select data type of column #%i (%s)' guesser.headers.each_with_index do |header, i| options = guess[header].map(&:to_s) options = options.select { |t| t != :connection_point.to_s } if connection_point_set type = ask((question_fmt % [i + 1, header]), :answers => options) model.push :title => header, :name => header, :type => type.upcase connection_point_set = true if type == :connection_point.to_s end model end def create_dataset file = extract_option('--file-csv') return Extract::CsvFile.new(file) if file fail(CommandFailed, 'Unknown data set. Please specify a data set using --file-csv option (more supported data sources to come!)') end end end end