# frozen_string_literal: true require 'etherscan' require 'google/cloud/bigquery' # config/initializers/etherscan.rb Etherscan.configure do |config| config.key = 'QA14GAMNM3AJIX8IEGA8MHEHBHJDTDSBPX' end module Etht DF = '%Y-%m-%d' DI = '%Y-%m-%d %H:%M:%S' # (see Bigquery) class Bigquery # @return [Google::Cloud::Bigquery] API bigquery attr_reader :apibq # @return [Roo::CSV] folha calculo a processar attr_reader :folha # @return [Hash] opcoes trabalho com linhas attr_reader :linha # @return [Array] row folha calculo em processamento attr_reader :row # @return [Google::Cloud::Bigquery::QueryJob] job bigquery attr_reader :job # @return (see sql_select) attr_reader :sql # @param [String] csv folha calculo para processar # @param [Hash] ops opcoes trabalho com linhas # @option ops [Boolean] :e (false) apaga linha igual? # @option ops [Boolean] :m (false) apaga linhas existencia multipla? # @option ops [Boolean] :i (false) insere linha nova? # @return [Bigquery] acesso folhas calculo bloks.io & correspondente bigquery dataset def initialize(csv = '', ops = { e: false, m: false, i: false }) # usa env GOOGLE_APPLICATION_CREDENTIALS para obter credentials # @see https://cloud.google.com/bigquery/docs/authentication/getting-started @apibq = Google::Cloud::Bigquery.new @folha = Roo::CSV.new(csv) if csv.size.positive? @linha = ops end # cria job bigquery & verifica execucao # # @param [String] sql a executar # @return [Boolean] job ok? def job_bigquery?(sql) @job = apibq.query_job(sql) @job.wait_until_done! puts @job.error['message'] if @job.failed? @job.failed? end # cria Data Manipulation Language (DML) job bigquery # # @param (see job_bigquery?) # @return [Integer] numero linhas afetadas def dml(sql) job_bigquery?(sql) ? 0 : job.num_dml_affected_rows end # pesquisa existencia linha folha calculo no bigquery # # @return [Google::Cloud::Bigquery::Data] resultado do sql num array def sql_select # array.count = 0 ==> pode carregar esta linha # array.count >= 1 ==> nao carregar esta linha @sql = job_bigquery?('select ' + eos_fields + ' ' + sql_where) ? [{}, {}] : job.data end # @return [String] parte sql para processamento linhas existentes def sql_where "from hernanirvaz.coins.eos where blocknumber=#{row[0]}" end # @return [Integer] numero linhas inseridas def sql_insert return 1 unless linha[:i] dml('insert hernanirvaz.coins.eos(' + eos_fields + ') VALUES(' + str_insert1) end # @return [String] campos da tabela no bigquery def eos_fields 'blocknumber,time,contract,action,acfrom,acto,amount,symbol,memo,data,dias' end # @return [String] campos insert da linha bigquery def str_insert1 "#{row[0]},'#{DateTime.parse(row[1]).strftime(DI)}','#{row[2]}'," + str_insert2 end # @return [String] campos insert da linha bigquery def str_insert2 "'#{row[3]}','#{row[4]}','#{row[5]}',#{row[6].to_f},'#{row[7]}','#{row[8]}','#{row[9]}',0)" end # @return [Integer] numero linhas apagadas def sql_delete dml('delete ' + sql_where) end end end