Skip to content

Commit

Permalink
Fixed connection leasing for Active Record 7.2+
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Oct 7, 2024
1 parent b9f316c commit 8fdf313
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 6.5.1 (unreleased)

- Fixed connection leasing for Active Record 7.2+

## 6.5.0 (2024-10-01)

- Added support for Active Record 8
Expand Down
3 changes: 2 additions & 1 deletion lib/groupdate/adapters/base_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Adapters
class BaseAdapter
attr_reader :period, :column, :day_start, :week_start, :n_seconds

def initialize(relation, column:, period:, time_zone:, time_range:, week_start:, day_start:, n_seconds:)
def initialize(relation, column:, period:, time_zone:, time_range:, week_start:, day_start:, n_seconds:, adapter_name: nil)
@relation = relation
@column = column
@period = period
Expand All @@ -12,6 +12,7 @@ def initialize(relation, column:, period:, time_zone:, time_range:, week_start:,
@week_start = week_start
@day_start = day_start
@n_seconds = n_seconds
@adapter_name = adapter_name

if ActiveRecord::VERSION::MAJOR >= 7
if ActiveRecord.default_timezone == :local
Expand Down
2 changes: 1 addition & 1 deletion lib/groupdate/adapters/postgresql_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def group_clause
when :week
["(DATE_TRUNC('day', #{day_start_column} - INTERVAL '1 day' * ((? + EXTRACT(DOW FROM #{day_start_column})::integer) % 7)) + INTERVAL ?)::date", time_zone, day_start_interval, 13 - week_start, time_zone, day_start_interval, day_start_interval]
when :custom
if @relation.connection.adapter_name == "Redshift"
if @adapter_name == "Redshift"
["TIMESTAMP 'epoch' + (FLOOR(EXTRACT(EPOCH FROM #{column}::timestamp) / ?) * ?) * INTERVAL '1 second'", n_seconds, n_seconds]
else
["TO_TIMESTAMP(FLOOR(EXTRACT(EPOCH FROM #{column}::timestamptz) / ?) * ?)", n_seconds, n_seconds]
Expand Down
20 changes: 11 additions & 9 deletions lib/groupdate/magic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,13 @@ def cast_result(result, multiple_groups)
end

def time_zone_support?(relation)
if relation.connection.adapter_name.match?(/mysql/i)
# need to call klass for Rails < 5.2
sql = relation.klass.send(:sanitize_sql_array, ["SELECT CONVERT_TZ(NOW(), '+00:00', ?)", time_zone.tzinfo.name])
!relation.connection.select_all(sql).to_a.first.values.first.nil?
else
true
relation.connection_pool.with_connection do |connection|
if connection.adapter_name.match?(/mysql|trilogy/i)
sql = relation.send(:sanitize_sql_array, ["SELECT CONVERT_TZ(NOW(), '+00:00', ?)", time_zone.tzinfo.name])
!connection.select_all(sql).to_a.first.values.first.nil?
else
true
end
end
end

Expand All @@ -203,7 +204,7 @@ def check_nils(result, multiple_groups, relation)
def self.generate_relation(relation, field:, **options)
magic = Groupdate::Magic::Relation.new(**options)

adapter_name = relation.connection.adapter_name
adapter_name = relation.connection_pool.with_connection { |c| c.adapter_name }
adapter = Groupdate.adapters[adapter_name]
raise Groupdate::Error, "Connection adapter not supported: #{adapter_name}" unless adapter

Expand All @@ -221,7 +222,8 @@ def self.generate_relation(relation, field:, **options)
time_range: magic.time_range,
week_start: magic.week_start,
day_start: magic.day_start,
n_seconds: magic.n_seconds
n_seconds: magic.n_seconds,
adapter_name: adapter_name
).generate

# add Groupdate info
Expand Down Expand Up @@ -251,7 +253,7 @@ def validate_column(column)
def resolve_column(relation, column)
node = relation.send(:relation).send(:arel_columns, [column]).first
node = Arel::Nodes::SqlLiteral.new(node) if node.is_a?(String)
relation.connection.visitor.accept(node, Arel::Collectors::SQLString.new).value
relation.connection_pool.with_connection { |c| c.visitor.accept(node, Arel::Collectors::SQLString.new).value }
end
end

Expand Down
9 changes: 9 additions & 0 deletions test/database_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ def test_n_duration
assert_equal({}, User.group_by_second(:created_at, n: 2.minutes).count)
end

def test_connection_leasing
ActiveRecord::Base.connection_handler.clear_active_connections!
assert_nil ActiveRecord::Base.connection_pool.active_connection?
ActiveRecord::Base.connection_pool.with_connection do
User.group_by_day(:created_at).count
end
assert_nil ActiveRecord::Base.connection_pool.active_connection?
end

private

def this_year
Expand Down

0 comments on commit 8fdf313

Please sign in to comment.