#!/usr/bin/env ruby # frozen_string_literal: true require 'bundler/setup' require 'ace_of_base' require 'optionparser' options = {} OptionParser.new do |opts| opts.on('-h', '--help', 'Show this help message') do puts opts exit(0) end opts.on('-s FIELDS', '--select FIELDS', 'Specify fields to select out of the results. Defaults to all fields.') do |value| options[:select] = value.split(/\s*,\s*/).map { |f| f.split(/\s*:\s*/).take(2) } end opts.on('-f FUNCTION', '--filter FUNCTION', 'Restrict the results to those that match the specified filters.') do |value| options[:filter] = AceOfBase::Filter.new(value).to_query end opts.on('-g FIELDS', '--group FIELDS', 'Group the results by specified fields, required if the select contains aggregations.') do |value| options[:group] = value.split(/\s*,\s*/) end opts.on('-o FIELDS', '--order_by FIELDS', 'Sort the matching rows by the provided fields') do |value| options[:order_by] = value.split(/\s*,\s*/) end end.parse! def format_column(column) case column when Array result = column.map { |v| format_column(v) }.join(',') "[#{result}]" when Float format('%0.2f', column) else column.to_s end end storage = AceOfBase::Storage.new query = AceOfBase::Query.new(storage) fields = options.fetch(:select, []).map { |field| field.first.downcase.to_sym } query.select(*fields) unless fields.empty? aggregates = options .fetch(:select, []) .select { |field| field.size == 2 } .map { |(key, value)| [key.downcase.to_sym, value.downcase.to_sym] } query.aggregate(Hash[aggregates]) unless aggregates.empty? groups = options.fetch(:group, []).map { |field| field.downcase.to_sym } query.group_by(*groups) order_bys = options.fetch(:order_by, []).map { |field| field.downcase.to_sym } query.order_by(*order_bys) filters = options[:filter] query.filter(*filters) if options[:filter] query.execute.each do |row| puts row.map { |c| format_column(c) }.join(',') end