From 9c3faafe4250bbdb9119794d4ac4b9a012da3f8b Mon Sep 17 00:00:00 2001 From: Rabbit Date: Mon, 11 Dec 2023 15:14:38 +0800 Subject: [PATCH] refactor: address transaction query (#1498) * refactor: address transaction query * chore: add total_count to paginate meta generator --- .../api/v1/address_transactions_controller.rb | 88 ++++++++++--------- .../fast_jsonapi/pagination_meta_generator.rb | 4 +- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/app/controllers/api/v1/address_transactions_controller.rb b/app/controllers/api/v1/address_transactions_controller.rb index 43f15b434..debafcb4e 100644 --- a/app/controllers/api/v1/address_transactions_controller.rb +++ b/app/controllers/api/v1/address_transactions_controller.rb @@ -6,39 +6,45 @@ class AddressTransactionsController < ApplicationController before_action :set_address_transactions, only: [:show, :download_csv] def show - @tx_ids = AccountBook.joins(:ckb_transaction). - where(account_books: { address_id: @address.id }, - ckb_transactions: { tx_status: "committed" }) - - params[:sort] ||= "ckb_transaction_id.desc" - order_by, asc_or_desc = params[:sort].split(".", 2) - order_by = - case order_by - when "time" then "ckb_transactions.block_timestamp" - else order_by - end - - head :not_found and return unless order_by.in? %w[ - ckb_transaction_id block_timestamp - ckb_transactions.block_timestamp - ] + expires_in 10.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds - @tx_ids = @tx_ids. + order_by, asc_or_desc = account_books_ordering + tx_ids = AccountBook.joins(:ckb_transaction). + where(account_books: { address_id: @address.id }, + ckb_transactions: { tx_status: "committed" }). order(order_by => asc_or_desc). - select("ckb_transaction_id"). page(@page).per(@page_size).fast_page - order_by = "id" if order_by == "ckb_transaction_id" - @ckb_transactions = CkbTransaction.where(id: @tx_ids.map(&:ckb_transaction_id)). - select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at, :capacity_involved). + total_count = AccountBook.where(address_id: @address.id).count + total_count = tx_ids.total_count if total_count < 1_000 + + ckb_transaction_ids = tx_ids.map(&:ckb_transaction_id) + ckb_transactions = CkbTransaction.where(id: ckb_transaction_ids). + select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, + :is_cellbase, :updated_at, :capacity_involved). order(order_by => asc_or_desc) + options = FastJsonapi::PaginationMetaGenerator.new( + request: request, + records: ckb_transactions, + page: @page, + page_size: @page_size, + total_count: total_count + ).call + ckb_transaction_serializer = CkbTransactionsSerializer.new( + ckb_transactions, + options.merge(params: { previews: true, address: @address }) + ) + json = - Rails.cache.realize("#{@ckb_transactions.cache_key}/#{@address.query_address}", - version: @ckb_transactions.cache_version) do - @options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: @ckb_transactions, - page: @page, page_size: @page_size, records_counter: @tx_ids).call - json_result + if QueryKeyUtils.valid_address?(params[:id]) + if @address.address_hash == @address.query_address + ckb_transaction_serializer.serialized_json + else + ckb_transaction_serializer.serialized_json.gsub(@address.address_hash, @address.query_address) + end + else + ckb_transaction_serializer.serialized_json end render json: json @@ -71,26 +77,24 @@ def pagination_params @page_size = params[:page_size] || CkbTransaction.default_per_page end - def json_result - ckb_transaction_serializer = CkbTransactionsSerializer.new(@ckb_transactions, - @options.merge(params: { - previews: true, - address: @address })) + def set_address_transactions + @address = Address.find_address!(params[:id]) + raise Api::V1::Exceptions::AddressNotFoundError if @address.is_a?(NullAddress) + end - if QueryKeyUtils.valid_address?(params[:id]) - if @address.address_hash == @address.query_address - ckb_transaction_serializer.serialized_json - else - ckb_transaction_serializer.serialized_json.gsub(@address.address_hash, @address.query_address) + def account_books_ordering + sort, order = params.fetch(:sort, "ckb_transaction_id.desc").split(".", 2) + sort = + case sort + when "time" then "ckb_transactions.block_timestamp" + else "ckb_transactions.id" end - else - ckb_transaction_serializer.serialized_json + + if order.nil? || !order.match?(/^(asc|desc)$/i) + order = "asc" end - end - def set_address_transactions - @address = Address.find_address!(params[:id]) - raise Api::V1::Exceptions::AddressNotFoundError if @address.is_a?(NullAddress) + [sort, order] end end end diff --git a/app/lib/fast_jsonapi/pagination_meta_generator.rb b/app/lib/fast_jsonapi/pagination_meta_generator.rb index db242c789..09aad67f8 100644 --- a/app/lib/fast_jsonapi/pagination_meta_generator.rb +++ b/app/lib/fast_jsonapi/pagination_meta_generator.rb @@ -3,13 +3,13 @@ class PaginationMetaGenerator DEFAULT_PAGE = 1 DEFAULT_PER_PAGE = 20 - def initialize(request:, records:, page:, page_size:, records_counter: nil) + def initialize(request:, records:, page:, page_size:, records_counter: nil, total_count: nil) @url = request.base_url + request.path + query_string(request.query_parameters) @page = page.to_i @page_size = limit_page_size(records, page_size.to_i) @records = records @records_counter = records_counter || records - @total_count = @records_counter.total_count.to_i + @total_count = total_count || @records_counter.total_count.to_i @total_pages = total_pages @hash = { links: {}, meta: { total: @total_count, page_size: @page_size } } end