Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ references:
matrix:
parameters:
ruby-version: ['2.7', '3.0', '3.1', '3.2']
bundle-version: ['Gemfile.rails-7.0', 'Gemfile.rails-7.1']
bundle-version: ['Gemfile.rails-7.0', 'Gemfile.rails-7.1', 'Gemfile.rails-7.2']
exclude:
- ruby-version: '2.7'
bundle-version: 'Gemfile.rails-7.2'
- ruby-version: '3.0'
bundle-version: 'Gemfile.rails-7.2'

workflows:
commit:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ To install torque-postgresql you need to add the following to your Gemfile:
gem 'torque-postgresql', '~> 2.0' # For Rails >= 6.0 < 6.1
gem 'torque-postgresql', '~> 2.0.4' # For Rails >= 6.1
gem 'torque-postgresql', '~> 3.0' # For Rails >= 7.0 < 7.1
gem 'torque-postgresql', '~> 3.3' # For Rails >= 7.1
gem 'torque-postgresql', '~> 3.3' # For Rails >= 7.1 < 7.2
gem 'torque-postgresql', '~> 3.4' # For Rails >= 7.2
```

Also, run:
Expand Down
7 changes: 7 additions & 0 deletions gemfiles/Gemfile.rails-7.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source 'https://rubygems.org'

gem 'rails', '~> 7.2', '< 7.3'
gem 'pg', '~> 1.4.0'
gem "byebug"

gemspec path: "../"
8 changes: 5 additions & 3 deletions lib/torque/postgresql/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,11 @@ def belongs_to_many(name, scope = nil, **options, &extension)
end

# Allow extra keyword arguments to be sent to +InsertAll+
def upsert_all(attributes, **xargs)
xargs = xargs.merge(on_duplicate: :update)
::ActiveRecord::InsertAll.new(self, attributes, **xargs).execute
unless Torque::PostgreSQL::AR720
def upsert_all(attributes, **xargs)
xargs = xargs.reverse_merge(on_duplicate: :update)
::ActiveRecord::InsertAll.new(self, attributes, **xargs).execute
end
end

protected
Expand Down
1 change: 1 addition & 0 deletions lib/torque/postgresql/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module PostgreSQL

# Stores a version check for compatibility purposes
AR710 = (ActiveRecord.gem_version >= Gem::Version.new('7.1.0'))
AR720 = (ActiveRecord.gem_version >= Gem::Version.new('7.2.0'))

# Use the same logger as the Active Record one
def self.logger
Expand Down
10 changes: 9 additions & 1 deletion lib/torque/postgresql/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def get_value(name)
# Compatibility method with 5.0
unless ActiveRecord::Relation.method_defined?(:set_value)
def set_value(name, value)
assert_mutability!
assert_mutability! if respond_to?(:assert_mutability!)
@values[name] = value
end
end
Expand Down Expand Up @@ -133,6 +133,14 @@ def initialize(klass, *, **)
klass.superclass.send(:relation) if klass.define_attribute_methods &&
klass.superclass != ActiveRecord::Base && !klass.superclass.abstract_class?
end

# Allow extra keyword arguments to be sent to +InsertAll+
if Torque::PostgreSQL::AR720
def upsert_all(attributes, **xargs)
xargs = xargs.reverse_merge(on_duplicate: :update)
::ActiveRecord::InsertAll.execute(self, attributes, **xargs)
end
end
end
end

Expand Down
29 changes: 17 additions & 12 deletions lib/torque/postgresql/schema_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ def add_model_name(*args)
end

# Get all the tables that the given one inherits from
def dependencies(conn, table_name = conn)
reload_inheritance_data!(conn == table_name ? connection : conn)
def dependencies(source, table_name = source)
reload_inheritance_data!(source == table_name ? connection : source)
@inheritance_dependencies[table_name]
end

# Get the list of all tables that are associated (direct or indirect
# inheritance) with the provided one
def associations(conn, table_name = conn)
reload_inheritance_data!(conn == table_name ? connection : conn)
def associations(source, table_name = source)
reload_inheritance_data!(source == table_name ? connection : source)
@inheritance_associations[table_name]
end

Expand All @@ -127,11 +127,15 @@ def lookup_model(*args, **xargs)

# Reload information about tables inheritance and dependencies, uses a
# cache to not perform additional checks
def reload_inheritance_data!(connection)
def reload_inheritance_data!(source)
return if @inheritance_loaded
@inheritance_dependencies = connection.inherited_tables
@inheritance_associations = generate_associations
@inheritance_loaded = true

method_name = Torque::PostgreSQL::AR720 ? :with_connection : :then
source.public_send(method_name) do |connection|
@inheritance_dependencies = connection.inherited_tables
@inheritance_associations = generate_associations
@inheritance_loaded = true
end
end

# Calculates the inverted dependency (association), where even indirect
Expand All @@ -141,11 +145,12 @@ def generate_associations
end

# Use this method to also load any irregular model name
def prepare_data_sources(connection = nil)
Torque::PostgreSQL::AR710 ? super : super()
method_name = Torque::PostgreSQL::AR720 ? :add_all : :prepare_data_sources
define_method(method_name) do |source = nil|
Torque::PostgreSQL::AR710 ? super(source) : super()

sources = connection.present? ? tables_to_cache(connection) : @data_sources.keys
@data_sources_model_names = prepare_irregular_models(sources)
data_sources = source.present? ? tables_to_cache(source) : @data_sources.keys
@data_sources_model_names = prepare_irregular_models(data_sources)
end

end
Expand Down
12 changes: 8 additions & 4 deletions lib/torque/postgresql/schema_cache/bound_schema_reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ module Torque
module PostgreSQL
module BoundSchemaReflection
def add_model_name(table_name, model)
@schema_reflection.add_model_name(@connection, table_name, model)
source = defined?(@pool) ? @pool : @connection
@schema_reflection.add_model_name(source, table_name, model)
end

def dependencies(table_name)
@schema_reflection.dependencies(@connection, table_name)
source = defined?(@pool) ? @pool : @connection
@schema_reflection.dependencies(source, table_name)
end

def associations(table_name)
@schema_reflection.associations(@connection, table_name)
source = defined?(@pool) ? @pool : @connection
@schema_reflection.associations(source, table_name)
end

def lookup_model(table_name, scoped_class = '')
@schema_reflection.lookup_model(@connection, table_name, scoped_class)
source = defined?(@pool) ? @pool : @connection
@schema_reflection.lookup_model(source, table_name, scoped_class)
end
end

Expand Down
16 changes: 8 additions & 8 deletions lib/torque/postgresql/schema_cache/schema_reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
module Torque
module PostgreSQL
module SchemaReflection
def add_model_name(connection, table_name, model)
cache(connection).add_model_name(connection, table_name, model)
def add_model_name(source, table_name, model)
cache(source).add_model_name(source, table_name, model)
end

def dependencies(connection, table_name)
cache(connection).dependencies(connection, table_name)
def dependencies(source, table_name)
cache(source).dependencies(source, table_name)
end

def associations(connection, table_name)
cache(connection).associations(connection, table_name)
def associations(source, table_name)
cache(source).associations(source, table_name)
end

def lookup_model(connection, table_name, scoped_class)
cache(connection).lookup_model(table_name, scoped_class)
def lookup_model(source, table_name, scoped_class)
cache(source).lookup_model(table_name, scoped_class)
end
end

Expand Down
33 changes: 25 additions & 8 deletions spec/mocks/cache_query.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
module Mocks
module CacheQuery
def get_last_executed_query(&block)
conn = ActiveRecord::Base.connection
conn.instance_variable_set(:@query_cache_enabled, true)
if Torque::PostgreSQL::AR720
def get_last_executed_query(&block)
cache = ActiveRecord::Base.connection.query_cache
cache.instance_variable_set(:@enabled, true)

block.call
result = conn.query_cache.keys.first
map = cache.instance_variable_get(:@map)

conn.instance_variable_set(:@query_cache_enabled, false)
conn.instance_variable_get(:@query_cache).delete(result)
block.call
result = map.keys.first

result
cache.instance_variable_set(:@enabled, false)
map.delete(result)

result
end
else
def get_last_executed_query(&block)
conn = ActiveRecord::Base.connection
conn.instance_variable_set(:@query_cache_enabled, true)

block.call
result = conn.query_cache.keys.first

conn.instance_variable_set(:@query_cache_enabled, false)
conn.instance_variable_get(:@query_cache).delete(result)

result
end
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
# Handles acton before rspec initialize
config.before(:suite) do
Torque::PostgreSQL.config.schemas.whitelist << 'internal'
ActiveSupport::Deprecation.silenced = true
ActiveSupport::Deprecation.try(:silenced=, true)
DatabaseCleaner.clean_with(:truncation)
end

Expand Down
4 changes: 2 additions & 2 deletions spec/tests/auxiliary_statement_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@
result << ' SELECT COUNT(*) FROM "users"'
result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'

query = get_last_executed_query{ subject.with(:comments).count }
query = get_last_executed_query { subject.with(:comments).count }
expect(query).to eql(result)
end

Expand All @@ -687,7 +687,7 @@
result << ' SELECT SUM("comments"."value") FROM "users"'
result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'

query = get_last_executed_query{ subject.with(:comments).sum(comments: :value) }
query = get_last_executed_query { subject.with(:comments).sum(comments: :value) }
expect(query).to eql(result)
end

Expand Down
9 changes: 6 additions & 3 deletions spec/tests/belongs_to_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
let(:model) { Video }
let(:builder) { Torque::PostgreSQL::Associations::Builder::BelongsToMany }
let(:reflection) { Torque::PostgreSQL::Reflection::BelongsToManyReflection }
let(:key) { Torque::PostgreSQL::AR720 ? :tests : 'tests' }

after { model._reflections = {} }

it 'has the builder method' do
Expand All @@ -24,7 +26,7 @@
it 'allows setting up foreign key and primary_key as symbol' do
model.belongs_to_many(:tests, foreign_key: :test_ids, primary_key: :test_id)

reflection = model._reflections['tests']
reflection = model._reflections[key]
expect(reflection.foreign_key).to be_eql('test_ids')
expect(reflection.active_record_primary_key).to be_eql('test_id')
end
Expand All @@ -33,6 +35,7 @@
context 'on association' do
let(:other) { Tag }
let(:initial) { FactoryBot.create(:tag) }
let(:key) { Torque::PostgreSQL::AR720 ? :tags : 'tags' }

before { Video.belongs_to_many(:tags) }
subject { Video.create(title: 'A') }
Expand All @@ -44,11 +47,11 @@

it 'has the method' do
expect(subject).to respond_to(:tags)
expect(subject._reflections).to include('tags')
expect(subject._reflections).to include(key)
end

it 'has correct foreign key' do
item = subject._reflections['tags']
item = subject._reflections[key]
expect(item.foreign_key).to be_eql('tag_ids')
end

Expand Down
10 changes: 9 additions & 1 deletion spec/tests/enum_set_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@ def decorate(model, field, options = {})
end

context 'on schema' do
let(:source) do
if Torque::PostgreSQL::AR720
ActiveRecord::Base.connection_pool
else
ActiveRecord::Base.connection
end
end

let(:dump_result) do
ActiveRecord::SchemaDumper.dump(connection, (dump_result = StringIO.new))
ActiveRecord::SchemaDumper.dump(source, (dump_result = StringIO.new))
dump_result.string
end

Expand Down
10 changes: 6 additions & 4 deletions spec/tests/has_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@

context 'on original' do
let(:other) { Text }
let(:key) { Torque::PostgreSQL::AR720 ? :texts : 'texts' }

before { User.has_many :texts }
subject { User.create(name: 'User 1') }
after { User._reflections = {} }

it 'has the method' do
expect(subject).to respond_to(:texts)
expect(subject._reflections).to include('texts')
expect(subject._reflections).to include(key)
end

it 'has correct foreign key' do
item = subject._reflections['texts']
item = subject._reflections[key]
expect(item.foreign_key).to be_eql('user_id')
end

Expand Down Expand Up @@ -246,18 +247,19 @@

context 'on array' do
let(:other) { Video }
let(:key) { Torque::PostgreSQL::AR720 ? :videos : 'videos' }

before { Tag.has_many :videos, array: true }
subject { Tag.create(name: 'A') }
after { Tag._reflections = {} }

it 'has the method' do
expect(subject).to respond_to(:videos)
expect(subject._reflections).to include('videos')
expect(subject._reflections).to include(key)
end

it 'has correct foreign key' do
item = subject._reflections['videos']
item = subject._reflections[key]
expect(item.foreign_key).to be_eql('tag_ids')
end

Expand Down
11 changes: 9 additions & 2 deletions spec/tests/interval_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
require 'spec_helper'

RSpec.describe 'Interval' do
let(:connection) { ActiveRecord::Base.connection }
let(:table_definition) { ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition }
let(:connection) { ActiveRecord::Base.connection }
let(:source) do
if Torque::PostgreSQL::AR720
ActiveRecord::Base.connection_pool
else
ActiveRecord::Base.connection
end
end

context 'on settings' do
it 'must be set to ISO 8601' do
Expand All @@ -27,7 +34,7 @@
context 'on schema' do
it 'can be used on tables too' do
dump_io = StringIO.new
ActiveRecord::SchemaDumper.dump(connection, dump_io)
ActiveRecord::SchemaDumper.dump(source, dump_io)
expect(dump_io.string).to match /t\.interval +"duration"/
end
end
Expand Down
Loading