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
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby 3.4.7
ruby 3.4.8
2 changes: 1 addition & 1 deletion closure_tree.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'zeitwerk', '~> 2.7'

gem.add_development_dependency 'database_cleaner'
gem.add_development_dependency 'minitest'
gem.add_development_dependency 'minitest', '~> 5.0'
gem.add_development_dependency 'minitest-reporters'
gem.add_development_dependency 'parallel'
gem.add_development_dependency 'simplecov'
Expand Down
2 changes: 1 addition & 1 deletion lib/closure_tree/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def abstract_base_class
klass = model_class
while klass.superclass != ActiveRecord::Base
parent = klass.superclass
# Stop at abstract class (ApplicationRecord, MysqlRecord, etc.)
# Stop at abstract class (ApplicationRecord, SecondaryRecord, etc.)
return parent if parent.abstract_class?
# Stop at connection boundary (handles non-abstract parents with custom connections)
return parent if parent.connection_specification_name != parent.superclass.connection_specification_name
Expand Down
4 changes: 2 additions & 2 deletions test/closure_tree/adopt_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def run_adopt_tests_for(model_class)
run_adopt_tests_for(AdoptableTag) if postgresql?(ApplicationRecord.connection)

# Test with MySQL
run_adopt_tests_for(MysqlAdoptableTag) if mysql?(MysqlRecord.connection)
run_adopt_tests_for(SecondaryAdoptableTag) if mysql?(SecondaryRecord.connection)

# Test with SQLite
run_adopt_tests_for(MemoryAdoptableTag) if sqlite?(SqliteRecord.connection)
run_adopt_tests_for(MemoryAdoptableTag) if sqlite?(LiteRecord.connection)
26 changes: 13 additions & 13 deletions test/closure_tree/multi_database_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ class MultiDatabaseTest < ActiveSupport::TestCase
def setup
super
# Create memory tables - always recreate for clean state
SqliteRecord.connection.create_table :memory_tags, force: true do |t|
LiteRecord.connection.create_table :memory_tags, force: true do |t|
t.string :name
t.integer :parent_id
t.timestamps
end

SqliteRecord.connection.create_table :memory_tag_hierarchies, id: false, force: true do |t|
LiteRecord.connection.create_table :memory_tag_hierarchies, id: false, force: true do |t|
t.integer :ancestor_id, null: false
t.integer :descendant_id, null: false
t.integer :generations, null: false
end

SqliteRecord.connection.add_index :memory_tag_hierarchies, %i[ancestor_id descendant_id generations],
LiteRecord.connection.add_index :memory_tag_hierarchies, %i[ancestor_id descendant_id generations],
unique: true, name: 'memory_tag_anc_desc_idx'
SqliteRecord.connection.add_index :memory_tag_hierarchies, [:descendant_id], name: 'memory_tag_desc_idx'
LiteRecord.connection.add_index :memory_tag_hierarchies, [:descendant_id], name: 'memory_tag_desc_idx'
end

def teardown
# Clean up SQLite tables after each test
SqliteRecord.connection.drop_table :memory_tag_hierarchies, if_exists: true
SqliteRecord.connection.drop_table :memory_tags, if_exists: true
LiteRecord.connection.drop_table :memory_tag_hierarchies, if_exists: true
LiteRecord.connection.drop_table :memory_tags, if_exists: true
super
end

Expand All @@ -46,13 +46,13 @@ def test_postgresql_with_advisory_lock
end

def test_mysql_with_advisory_lock
skip 'MySQL not configured' unless mysql?(MysqlRecord.connection)
skip 'MySQL not configured' unless mysql?(SecondaryRecord.connection)

tag = MysqlTag.create!(name: 'MySQL Root')
tag = SecondaryTag.create!(name: 'MySQL Root')
child = nil

# Advisory locks should work on MySQL
MysqlTag.with_advisory_lock('test_lock') do
SecondaryTag.with_advisory_lock('test_lock') do
child = tag.children.create!(name: 'MySQL Child')
end

Expand Down Expand Up @@ -80,21 +80,21 @@ def test_concurrent_operations_different_databases
pg_tag.children.create!(name: 'PG Child 1')
end

mysql_tag = MysqlTag.create!(name: 'MySQL Root')
mysql_tag = SecondaryTag.create!(name: 'MySQL Root')
sqlite_tag = MemoryTag.create!(name: 'SQLite Root')

# Test concurrent operations only for MySQL and SQLite
threads = []

threads << Thread.new do
MysqlRecord.connection_pool.with_connection do
tag = MysqlTag.find(mysql_tag.id)
SecondaryRecord.connection_pool.with_connection do
tag = SecondaryTag.find(mysql_tag.id)
tag.children.create!(name: 'MySQL Child 1')
end
end

threads << Thread.new do
SqliteRecord.connection_pool.with_connection do
LiteRecord.connection_pool.with_connection do
tag = MemoryTag.find(sqlite_tag.id)
tag.children.create!(name: 'SQLite Child 1')
end
Expand Down
4 changes: 2 additions & 2 deletions test/closure_tree/parallel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def work
# Clean up SQLite database file if it exists
db_file = 'test/dummy/db/test.sqlite3'
if File.exist?(db_file)
SqliteRecord.connection.disconnect!
LiteRecord.connection.disconnect!
File.delete(db_file)
SqliteRecord.connection.reconnect!
LiteRecord.connection.reconnect!
end
Tag.delete_all
Tag.hierarchy_class.delete_all
Expand Down
6 changes: 6 additions & 0 deletions test/dummy/app/models/lite_record.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class LiteRecord < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :lite, reading: :lite }
end
2 changes: 1 addition & 1 deletion test/dummy/app/models/memory_adoptable_tag.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class MemoryAdoptableTag < SqliteRecord
class MemoryAdoptableTag < LiteRecord
has_closure_tree dependent: :adopt, name_column: 'name'
end
2 changes: 1 addition & 1 deletion test/dummy/app/models/memory_tag.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class MemoryTag < SqliteRecord
class MemoryTag < LiteRecord
has_closure_tree
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class MysqlAdoptableTag < MysqlRecord
class SecondaryAdoptableTag < SecondaryRecord
has_closure_tree dependent: :adopt, name_column: 'name'
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class MysqlRecord < ApplicationRecord
class SecondaryRecord < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :secondary, reading: :secondary }
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class MysqlTag < MysqlRecord
class SecondaryTag < SecondaryRecord
has_closure_tree
end
6 changes: 0 additions & 6 deletions test/dummy/app/models/sqlite_record.rb

This file was deleted.

2 changes: 1 addition & 1 deletion test/dummy/config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test:
url: "<%= ENV['DATABASE_URL_MYSQL'] || 'mysql2://closure_tree:[email protected]:3367/closure_tree_test' %>"
properties:
allowPublicKeyRetrieval: true
sqlite:
lite:
<<: *default
adapter: sqlite3
database: "test/dummy/db/test.sqlite3"
15 changes: 0 additions & 15 deletions test/dummy/db/mysql_schema.rb

This file was deleted.

30 changes: 15 additions & 15 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,37 +170,37 @@
add_foreign_key(:tag_hierarchies, :tags, column: 'descendant_id', on_delete: :cascade)

# Multi-database test models
create_table 'mysql_tags' do |t|
create_table 'secondary_tags' do |t|
t.string 'name'
t.references 'parent'
t.timestamps null: false
end

create_table 'mysql_tag_hierarchies', id: false do |t|
create_table 'secondary_tag_hierarchies', id: false do |t|
t.references 'ancestor', null: false
t.references 'descendant', null: false
t.integer 'generations', null: false
end

add_index 'mysql_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'mysql_tag_anc_desc_idx'
add_index 'mysql_tag_hierarchies', [:descendant_id], name: 'mysql_tag_desc_idx'
add_index 'secondary_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'secondary_tag_anc_desc_idx'
add_index 'secondary_tag_hierarchies', [:descendant_id], name: 'secondary_tag_desc_idx'

create_table 'sqlite_tags' do |t|
create_table 'lite_tags' do |t|
t.string 'name'
t.references 'parent'
t.timestamps null: false
end

create_table 'sqlite_tag_hierarchies', id: false do |t|
create_table 'lite_tag_hierarchies', id: false do |t|
t.references 'ancestor', null: false
t.references 'descendant', null: false
t.integer 'generations', null: false
end

add_index 'sqlite_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'sqlite_tag_anc_desc_idx'
add_index 'sqlite_tag_hierarchies', [:descendant_id], name: 'sqlite_tag_desc_idx'
add_index 'lite_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'lite_tag_anc_desc_idx'
add_index 'lite_tag_hierarchies', [:descendant_id], name: 'lite_tag_desc_idx'

create_table 'scoped_items' do |t|
t.string 'name'
Expand Down Expand Up @@ -237,21 +237,21 @@
name: 'adoptable_tag_anc_desc_idx'
add_index 'adoptable_tag_hierarchies', [:descendant_id], name: 'adoptable_tag_desc_idx'

create_table 'mysql_adoptable_tags' do |t|
create_table 'secondary_adoptable_tags' do |t|
t.string 'name'
t.references 'parent'
t.timestamps null: false
end

create_table 'mysql_adoptable_tag_hierarchies', id: false do |t|
create_table 'secondary_adoptable_tag_hierarchies', id: false do |t|
t.references 'ancestor', null: false
t.references 'descendant', null: false
t.integer 'generations', null: false
end

add_index 'mysql_adoptable_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'mysql_adoptable_tag_anc_desc_idx'
add_index 'mysql_adoptable_tag_hierarchies', [:descendant_id], name: 'mysql_adoptable_tag_desc_idx'
add_index 'secondary_adoptable_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'secondary_adoptable_tag_anc_desc_idx'
add_index 'secondary_adoptable_tag_hierarchies', [:descendant_id], name: 'secondary_adoptable_tag_desc_idx'

create_table 'memory_adoptable_tags' do |t|
t.string 'name'
Expand Down
20 changes: 10 additions & 10 deletions test/dummy/db/secondary_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,37 @@
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 0) do
create_table 'mysql_tags', force: true do |t|
create_table 'secondary_tags', force: true do |t|
t.string 'name'
t.integer 'parent_id'
t.datetime 'created_at'
t.datetime 'updated_at'
end

create_table 'mysql_tag_hierarchies', id: false, force: true do |t|
create_table 'secondary_tag_hierarchies', id: false, force: true do |t|
t.integer 'ancestor_id', null: false
t.integer 'descendant_id', null: false
t.integer 'generations', null: false
end

add_index 'mysql_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'mysql_tag_anc_des_idx'
add_index 'mysql_tag_hierarchies', [:descendant_id], name: 'mysql_tag_desc_idx'
add_index 'secondary_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'secondary_tag_anc_des_idx'
add_index 'secondary_tag_hierarchies', [:descendant_id], name: 'secondary_tag_desc_idx'

create_table 'mysql_adoptable_tags', force: true do |t|
create_table 'secondary_adoptable_tags', force: true do |t|
t.string 'name'
t.integer 'parent_id'
t.datetime 'created_at'
t.datetime 'updated_at'
end

create_table 'mysql_adoptable_tag_hierarchies', id: false, force: true do |t|
create_table 'secondary_adoptable_tag_hierarchies', id: false, force: true do |t|
t.integer 'ancestor_id', null: false
t.integer 'descendant_id', null: false
t.integer 'generations', null: false
end

add_index 'mysql_adoptable_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'mysql_adoptable_tag_anc_desc_idx'
add_index 'mysql_adoptable_tag_hierarchies', [:descendant_id], name: 'mysql_adoptable_tag_desc_idx'
add_index 'secondary_adoptable_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'secondary_adoptable_tag_anc_desc_idx'
add_index 'secondary_adoptable_tag_hierarchies', [:descendant_id], name: 'secondary_adoptable_tag_desc_idx'
end
10 changes: 5 additions & 5 deletions test/dummy/db/sqlite_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 0) do
create_table 'sqlite_tags', force: true do |t|
create_table 'lite_tags', force: true do |t|
t.string 'name'
t.integer 'parent_id'
t.datetime 'created_at'
t.datetime 'updated_at'
end

create_table 'sqlite_tag_hierarchies', id: false, force: true do |t|
create_table 'lite_tag_hierarchies', id: false, force: true do |t|
t.integer 'ancestor_id', null: false
t.integer 'descendant_id', null: false
t.integer 'generations', null: false
end

add_index 'sqlite_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'sqlite_tag_anc_desc_idx'
add_index 'sqlite_tag_hierarchies', [:descendant_id], name: 'sqlite_tag_desc_idx'
add_index 'lite_tag_hierarchies', %i[ancestor_id descendant_id generations], unique: true,
name: 'lite_tag_anc_desc_idx'
add_index 'lite_tag_hierarchies', [:descendant_id], name: 'lite_tag_desc_idx'

create_table 'memory_adoptable_tags', force: true do |t|
t.string 'name'
Expand Down
4 changes: 2 additions & 2 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def self.startup
setup do
# Configure DatabaseCleaner for each database connection
DatabaseCleaner[:active_record, db: ApplicationRecord].strategy = :truncation
DatabaseCleaner[:active_record, db: MysqlRecord].strategy = :truncation
DatabaseCleaner[:active_record, db: SqliteRecord].strategy = :truncation
DatabaseCleaner[:active_record, db: SecondaryRecord].strategy = :truncation
DatabaseCleaner[:active_record, db: LiteRecord].strategy = :truncation

DatabaseCleaner.start
end
Expand Down