Class: Miscellany::ComplexQuery
- Inherits:
-
Object
- Object
- Miscellany::ComplexQuery
- Defined in:
- lib/miscellany/active_record/complex_query.rb
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
- #count ⇒ Object
- #find_each(batch_size: 1000, &block) ⇒ Object
- #in_batches(of: 1000) ⇒ Object
-
#initialize(options) ⇒ ComplexQuery
constructor
A new instance of ComplexQuery.
- #page(page, page_size: 40) ⇒ Object
- #slice(start, length, raw_sort: nil) ⇒ Object
- #sql ⇒ Object
- #valid_sort?(sort) ⇒ Boolean
Constructor Details
#initialize(options) ⇒ ComplexQuery
Returns a new instance of ComplexQuery.
5 6 7 |
# File 'lib/miscellany/active_record/complex_query.rb', line 5 def initialize() = .with_indifferent_access end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
3 4 5 |
# File 'lib/miscellany/active_record/complex_query.rb', line 3 def end |
Instance Method Details
#count ⇒ Object
9 10 11 12 |
# File 'lib/miscellany/active_record/complex_query.rb', line 9 def count res = ActiveRecord::Base.connection.execute(build_count_query) res[0].to_h.values[0] end |
#find_each(batch_size: 1000, &block) ⇒ Object
76 77 78 79 80 |
# File 'lib/miscellany/active_record/complex_query.rb', line 76 def find_each(batch_size: 1000, &block) in_batches(of: batch_size) do |batch| batch.each(&block) end end |
#in_batches(of: 1000) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/miscellany/active_record/complex_query.rb', line 55 def in_batches(of: 1000) conn = ActiveRecord::Base.connection tbl = "#{self.class.name.split('::').last.underscore}_#{SecureRandom.hex[0..10]}" conn.execute("CREATE TEMP TABLE #{tbl} AS (#{sql})") offset = 0 loop do batch = ActiveRecord::Base.connection.exec_query( "SELECT * FROM #{tbl} LIMIT #{of} OFFSET #{offset}", ) batch = batch.map(&:with_indifferent_access) augment_batch(batch) yield batch offset += of break if batch.empty? end ensure conn.execute("DROP TABLE IF EXISTS #{tbl}") end |
#page(page, page_size: 40) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/miscellany/active_record/complex_query.rb', line 14 def page(page, page_size: 40) total_items = count page = page.to_i || 1 page = 1 if page < 1 page_size = page_size.to_i page_size = 10 if page_size < 2 offset = (page - 1) * page_size psql = sql psql += " LIMIT #{page_size} OFFSET #{offset}" records = ActiveRecord::Base.connection.exec_query(psql).to_a augment_batch(records) { page: page, total_count: total_items, page_count: (total_items.to_f / page_size).ceil, page_size: page_size, sort: parsed_sort&.map do |s| "#{s[:key] || s[:column]} #{s[:order] || 'ASC'}" end&.join(', '), records: records, } end |
#slice(start, length, raw_sort: nil) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/miscellany/active_record/complex_query.rb', line 41 def slice(start, length, raw_sort: nil) psql = build_query if raw_sort.present? psql += " ORDER BY #{raw_sort}" elsif sort_sql.present? psql += " ORDER BY #{sort_sql}" end psql += " LIMIT #{length} OFFSET #{start}" records = ActiveRecord::Base.connection.exec_query(psql).to_a records = records.map(&:with_indifferent_access) augment_batch(records) records end |
#sql ⇒ Object
82 83 84 85 86 |
# File 'lib/miscellany/active_record/complex_query.rb', line 82 def sql sql = build_query sql += " ORDER BY #{sort_sql}" if sort_sql.present? sql end |
#valid_sort?(sort) ⇒ Boolean
88 89 90 91 |
# File 'lib/miscellany/active_record/complex_query.rb', line 88 def valid_sort?(sort) sort_parser.valid?(sort) return false unless sort.present? end |