From 71f776ac1f1e843796bc78d74d2501cc3044ecfe Mon Sep 17 00:00:00 2001 From: Adam Hutchison Date: Tue, 26 Nov 2024 19:56:54 -0700 Subject: [PATCH 1/4] Target Rails 7.1 Upgrade to Rails 7.1 (specs fail under 7.2). ARJDBC does not currently support Rails 7.1. Update the Gemfile to target the source, and target jruby-head to keep CI passing. --- .github/workflows/main.yml | 6 +++--- .gitignore | 2 +- Gemfile | 15 ++++++++++++--- spectacles.gemspec | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2cc129b..a0161e8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: [2.7, jruby-9.4, head, jruby-head] + ruby-version: [2.7, head, jruby-head] continue-on-error: ${{ endsWith(matrix.ruby-version, 'head') || matrix.ruby-version == 'debug' }} services: @@ -60,7 +60,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: [2.7, jruby-9.4, head, jruby-head] + ruby-version: [2.7, head, jruby-head] continue-on-error: ${{ endsWith(matrix.ruby-version, 'head') || matrix.ruby-version == 'debug' }} services: @@ -101,7 +101,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: [2.7, jruby-9.4, head, jruby-head] + ruby-version: [2.7, head, jruby-head] continue-on-error: ${{ endsWith(matrix.ruby-version, 'head') || matrix.ruby-version == 'debug' }} env: diff --git a/.gitignore b/.gitignore index d5c67a8..bd6f7fc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,5 @@ /doc/ /pkg/ /spec/reports/ -/test/*.db +/test/*.db* /tmp/ diff --git a/Gemfile b/Gemfile index dd8c853..82b528e 100644 --- a/Gemfile +++ b/Gemfile @@ -4,9 +4,18 @@ source "https://rubygems.org" gemspec platforms :jruby do - gem "activerecord-jdbcmysql-adapter" - gem "activerecord-jdbcpostgresql-adapter" - gem "activerecord-jdbcsqlite3-adapter" + gem "activerecord-jdbc-adapter", + git: "https://github.com/jruby/activerecord-jdbc-adapter", + glob: "activerecord-jdbc-adapter.gemspec" + gem "activerecord-jdbcsqlite3-adapter", + git: "https://github.com/jruby/activerecord-jdbc-adapter", + glob: "activerecord-jdbcsqlite3-adapter/activerecord-jdbcsqlite3-adapter.gemspec" + gem "activerecord-jdbcpostgresql-adapter", + git: "https://github.com/jruby/activerecord-jdbc-adapter", + glob: "activerecord-jdbcpostgresql-adapter/activerecord-jdbcpostgresql-adapter.gemspec" + gem "activerecord-jdbcmysql-adapter", + git: "https://github.com/jruby/activerecord-jdbc-adapter", + glob: "activerecord-jdbcmysql-adapter/activerecord-jdbcmysql-adapter.gemspec" end platforms :ruby do diff --git a/spectacles.gemspec b/spectacles.gemspec index 806b061..6c37532 100644 --- a/spectacles.gemspec +++ b/spectacles.gemspec @@ -31,8 +31,8 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "activerecord", "~> 7.0.0" - spec.add_dependency "activesupport", "~> 7.0.0" + spec.add_dependency "activerecord", "~> 7.1.0" + spec.add_dependency "activesupport", "~> 7.1.0" spec.add_development_dependency "minitest", ">= 5.0" spec.add_development_dependency "rake" From 048310fc6ee0cb6e690aea9c4bbfd07b7cfd8697 Mon Sep 17 00:00:00 2001 From: Adam Hutchison Date: Wed, 27 Nov 2024 11:22:10 -0700 Subject: [PATCH 2/4] Add spectacles tests to the CI workflow The CI workflow was only running the adapter specs. Add a job that runs the remaining gem tests as well. --- .github/workflows/main.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0161e8..7c5f13d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,22 @@ jobs: bundler-cache: true - run: bundle exec standardrb --format github + test: + name: Tests (Spectacles) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ruby-version: [2.7, head, jruby-head] + continue-on-error: ${{ endsWith(matrix.ruby-version, 'head') || matrix.ruby-version == 'debug' }} + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + - run: bundle exec rake test:spectacles + test-mysql: name: Tests (MySQL) runs-on: ubuntu-latest From 904ac7b7fe8ca4517d6b1881033af208ac342add Mon Sep 17 00:00:00 2001 From: Adam Hutchison Date: Wed, 27 Nov 2024 11:52:16 -0700 Subject: [PATCH 3/4] Remove #tables overrides Rails now handles filtering views from the tables query, so these overrides are no longer needed. --- .../schema_statements/mysql2_adapter.rb | 19 ------------------- .../schema_statements/sqlite3_adapter.rb | 15 --------------- 2 files changed, 34 deletions(-) diff --git a/lib/spectacles/schema_statements/mysql2_adapter.rb b/lib/spectacles/schema_statements/mysql2_adapter.rb index 5bdfc73..4f02358 100644 --- a/lib/spectacles/schema_statements/mysql2_adapter.rb +++ b/lib/spectacles/schema_statements/mysql2_adapter.rb @@ -3,25 +3,6 @@ module SchemaStatements module Mysql2Adapter include Spectacles::SchemaStatements::AbstractAdapter - # overrides the #tables method from ActiveRecord's MysqlAdapter - # to return only tables, and not views. - def tables(name = nil, database = nil, like = nil) - database = database ? quote_table_name(database) : "DATABASE()" - by_name = like ? "AND table_name LIKE #{quote(like)}" : "" - - sql = <<-SQL.squish - SELECT table_name, table_type - FROM information_schema.tables - WHERE table_schema = #{database} - AND table_type = 'BASE TABLE' - #{by_name} - SQL - - execute_and_free(sql, "SCHEMA") do |result| - rows_from(result).map(&:first) - end - end - def views(name = nil) # :nodoc: result = execute("SHOW FULL TABLES WHERE TABLE_TYPE='VIEW'") diff --git a/lib/spectacles/schema_statements/sqlite3_adapter.rb b/lib/spectacles/schema_statements/sqlite3_adapter.rb index dc2c683..69f3fd6 100644 --- a/lib/spectacles/schema_statements/sqlite3_adapter.rb +++ b/lib/spectacles/schema_statements/sqlite3_adapter.rb @@ -5,21 +5,6 @@ module SchemaStatements module SQLite3Adapter include Spectacles::SchemaStatements::AbstractAdapter - # overrides the #tables method from ActiveRecord's SQLite3Adapter - # to return only tables, and not views. - def tables(name = nil, table_name = nil) - sql = <<-SQL - SELECT name - FROM sqlite_master - WHERE type = 'table' AND NOT name = 'sqlite_sequence' - SQL - sql << " AND name = #{quote_table_name(table_name)}" if table_name - - exec_query(sql, "SCHEMA").map do |row| - row["name"] - end - end - def generate_view_query(*columns) <<-SQL SELECT #{columns.join(",")} From bd3dd3e1cb0a672124f63c9feaab9ab64f96824f Mon Sep 17 00:00:00 2001 From: Adam Hutchison Date: Wed, 27 Nov 2024 12:34:15 -0700 Subject: [PATCH 4/4] Properly handle MySQL results from JDBC --- lib/spectacles/schema_statements/mysql2_adapter.rb | 9 ++++----- test/support/schema_statement_examples.rb | 6 ++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/spectacles/schema_statements/mysql2_adapter.rb b/lib/spectacles/schema_statements/mysql2_adapter.rb index 4f02358..d5f7b74 100644 --- a/lib/spectacles/schema_statements/mysql2_adapter.rb +++ b/lib/spectacles/schema_statements/mysql2_adapter.rb @@ -5,13 +5,12 @@ module Mysql2Adapter def views(name = nil) # :nodoc: result = execute("SHOW FULL TABLES WHERE TABLE_TYPE='VIEW'") - - rows_from(result).map(&:first) + values_from(result).map(&:first) end def view_build_query(view, name = nil) result = execute("SHOW CREATE VIEW #{view}", name) - algorithm_string = rows_from(result).first[1] + algorithm_string = values_from(result).first[1] algorithm_string.gsub(/CREATE .*? (AS)+/i, "") rescue ActiveRecord::StatementInvalid => e @@ -20,8 +19,8 @@ def view_build_query(view, name = nil) private - def rows_from(result) - result.respond_to?(:rows) ? result.rows : result + def values_from(result) + result.first.respond_to?(:values) ? result.map(&:values) : result end end end diff --git a/test/support/schema_statement_examples.rb b/test/support/schema_statement_examples.rb index df7a144..29b6cdc 100644 --- a/test/support/schema_statement_examples.rb +++ b/test/support/schema_statement_examples.rb @@ -17,12 +17,18 @@ def self.execute(query) describe "ActiveRecord::SchemaDumper#dump" do before(:each) do ActiveRecord::Base.connection.drop_view(:new_product_users) + ActiveRecord::Base.connection.drop_view(:other_product_users) ActiveRecord::Base.connection.create_view(:new_product_users) do "SELECT name AS product_name, first_name AS username FROM products JOIN users ON users.id = products.user_id" end + ActiveRecord::Base.connection.create_view(:other_product_users) do + "SELECT name AS product_name, first_name AS username FROM + products JOIN users ON users.id = products.user_id" + end + if ActiveRecord::Base.connection.supports_materialized_views? ActiveRecord::Base.connection.drop_materialized_view(:materialized_product_users) ActiveRecord::Base.connection.drop_materialized_view(:empty_materialized_product_users)