From 757b2cea37ef2e6140508cf52d5e9285afec659b Mon Sep 17 00:00:00 2001 From: Ross Kaffenberger Date: Wed, 11 Dec 2024 22:14:04 -0500 Subject: [PATCH 1/4] Bundle to edge Rails for extension loading --- Gemfile | 2 +- Gemfile.lock | 159 ++++++++++++++++++++++++++------------------------- 2 files changed, 83 insertions(+), 78 deletions(-) diff --git a/Gemfile b/Gemfile index 27e3a8bd..3053f901 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby file: ".ruby-version" -gem "rails" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", github: "rails/rails" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem "puma", ">= 5.0" # Use the Puma web server [https://github.com/puma/puma] gem "sqlite3", force_ruby_platform: true # Use sqlite3 as the database for Active Record [https://github.com/sparklemotion/sqlite3-ruby] diff --git a/Gemfile.lock b/Gemfile.lock index 9cf01823..78009d05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,41 +1,30 @@ GIT - remote: https://github.com/railsadminteam/rails_admin.git - revision: e38c12d98e3e11b858d2f3caa752013b7478f926 - specs: - rails_admin (3.2.1) - activemodel-serializers-xml (>= 1.0) - csv - kaminari (>= 0.14, < 2.0) - nested_form (~> 0.3) - rails (>= 6.0, < 9) - turbo-rails (>= 1.0, < 3) - -GEM - remote: https://rubygems.org/ + remote: https://github.com/rails/rails.git + revision: 8149a919848182018d061392136342ebc955d709 specs: - actioncable (8.0.0.1) - actionpack (= 8.0.0.1) - activesupport (= 8.0.0.1) + actioncable (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.0.1) - actionpack (= 8.0.0.1) - activejob (= 8.0.0.1) - activerecord (= 8.0.0.1) - activestorage (= 8.0.0.1) - activesupport (= 8.0.0.1) + actionmailbox (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + activejob (= 8.1.0.alpha) + activerecord (= 8.1.0.alpha) + activestorage (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) mail (>= 2.8.0) - actionmailer (8.0.0.1) - actionpack (= 8.0.0.1) - actionview (= 8.0.0.1) - activejob (= 8.0.0.1) - activesupport (= 8.0.0.1) + actionmailer (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + actionview (= 8.1.0.alpha) + activejob (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.0.1) - actionview (= 8.0.0.1) - activesupport (= 8.0.0.1) + actionpack (8.1.0.alpha) + actionview (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -43,39 +32,35 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.0.1) - actionpack (= 8.0.0.1) - activerecord (= 8.0.0.1) - activestorage (= 8.0.0.1) - activesupport (= 8.0.0.1) + actiontext (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + activerecord (= 8.1.0.alpha) + activestorage (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.0.1) - activesupport (= 8.0.0.1) + actionview (8.1.0.alpha) + activesupport (= 8.1.0.alpha) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.0.0.1) - activesupport (= 8.0.0.1) + activejob (8.1.0.alpha) + activesupport (= 8.1.0.alpha) globalid (>= 0.3.6) - activemodel (8.0.0.1) - activesupport (= 8.0.0.1) - activemodel-serializers-xml (1.0.3) - activemodel (>= 5.0.0.a) - activesupport (>= 5.0.0.a) - builder (~> 3.1) - activerecord (8.0.0.1) - activemodel (= 8.0.0.1) - activesupport (= 8.0.0.1) + activemodel (8.1.0.alpha) + activesupport (= 8.1.0.alpha) + activerecord (8.1.0.alpha) + activemodel (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) timeout (>= 0.4.0) - activestorage (8.0.0.1) - actionpack (= 8.0.0.1) - activejob (= 8.0.0.1) - activerecord (= 8.0.0.1) - activesupport (= 8.0.0.1) + activestorage (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + activejob (= 8.1.0.alpha) + activerecord (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) marcel (~> 1.0) - activesupport (8.0.0.1) + activesupport (8.1.0.alpha) base64 benchmark (>= 0.3) bigdecimal @@ -88,6 +73,48 @@ GEM securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) + rails (8.1.0.alpha) + actioncable (= 8.1.0.alpha) + actionmailbox (= 8.1.0.alpha) + actionmailer (= 8.1.0.alpha) + actionpack (= 8.1.0.alpha) + actiontext (= 8.1.0.alpha) + actionview (= 8.1.0.alpha) + activejob (= 8.1.0.alpha) + activemodel (= 8.1.0.alpha) + activerecord (= 8.1.0.alpha) + activestorage (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) + bundler (>= 1.15.0) + railties (= 8.1.0.alpha) + railties (8.1.0.alpha) + actionpack (= 8.1.0.alpha) + activesupport (= 8.1.0.alpha) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + +GIT + remote: https://github.com/railsadminteam/rails_admin.git + revision: e38c12d98e3e11b858d2f3caa752013b7478f926 + specs: + rails_admin (3.2.1) + activemodel-serializers-xml (>= 1.0) + csv + kaminari (>= 0.14, < 2.0) + nested_form (~> 0.3) + rails (>= 6.0, < 9) + turbo-rails (>= 1.0, < 3) + +GEM + remote: https://rubygems.org/ + specs: + activemodel-serializers-xml (1.0.3) + activemodel (>= 5.0.0.a) + activesupport (>= 5.0.0.a) + builder (~> 3.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) annotaterb (4.13.0) @@ -407,20 +434,6 @@ GEM rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails (8.0.0.1) - actioncable (= 8.0.0.1) - actionmailbox (= 8.0.0.1) - actionmailer (= 8.0.0.1) - actionpack (= 8.0.0.1) - actiontext (= 8.0.0.1) - actionview (= 8.0.0.1) - activejob (= 8.0.0.1) - activemodel (= 8.0.0.1) - activerecord (= 8.0.0.1) - activestorage (= 8.0.0.1) - activesupport (= 8.0.0.1) - bundler (>= 1.15.0) - railties (= 8.0.0.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -436,14 +449,6 @@ GEM json require_all (~> 3.0) ruby-progressbar - railties (8.0.0.1) - actionpack (= 8.0.0.1) - activesupport (= 8.0.0.1) - irb (~> 1.13) - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.2.1) rdoc (6.8.1) @@ -662,7 +667,7 @@ DEPENDENCIES propshaft puma (>= 5.0) rack-mini-profiler - rails + rails! rails_admin! rails_best_practices reek From 95e18af52dc56cf8c5c2a03885100d28b6d6c870 Mon Sep 17 00:00:00 2001 From: Ross Kaffenberger Date: Wed, 11 Dec 2024 22:16:13 -0500 Subject: [PATCH 2/4] Bump sqlite3 for extension loading --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 78009d05..3e1490a9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -557,7 +557,7 @@ GEM sqlite-ulid (0.2.1-x86_64-linux) sqlite-vec (0.1.6-arm64-darwin) sqlite-vec (0.1.6-x86_64-linux) - sqlite3 (2.3.1) + sqlite3 (2.4.1) mini_portile2 (~> 2.8.0) sqlpkg (0.2.3.1-arm64-darwin) sqlpkg (0.2.3.1-x86_64-linux) From 5c4aeba25cbb849720a81e9dd892de95cf490709 Mon Sep 17 00:00:00 2001 From: Ross Kaffenberger Date: Wed, 11 Dec 2024 23:43:28 -0500 Subject: [PATCH 3/4] Adopt sqlite extension loading features of rails and sqlite3 Lib files are necessary to adapt to the to_path interface expected by the extension loading mechansim Make Zeitwerk happy when eager loading enabled --- config/database.yml | 4 +- config/initializers/sqlite.rb | 1 + config/initializers/sqlpkg.rb | 12 ----- lib/enhanced_sqlite3.rb | 4 -- lib/enhanced_sqlite3/adapter.rb | 56 ----------------------- lib/sqlite_ext.rb | 2 + lib/sqlite_ext/ulid.rb | 9 ++++ lib/sqlite_ext/vec.rb | 7 +++ lib/sqlpkg_loader.rb | 11 ----- spec/lib/enhanced_sqlite3/adapter_spec.rb | 5 -- 10 files changed, 21 insertions(+), 90 deletions(-) create mode 100644 config/initializers/sqlite.rb delete mode 100644 config/initializers/sqlpkg.rb delete mode 100644 lib/enhanced_sqlite3.rb delete mode 100644 lib/enhanced_sqlite3/adapter.rb create mode 100644 lib/sqlite_ext.rb create mode 100644 lib/sqlite_ext/ulid.rb create mode 100644 lib/sqlite_ext/vec.rb delete mode 100644 lib/sqlpkg_loader.rb delete mode 100644 spec/lib/enhanced_sqlite3/adapter_spec.rb diff --git a/config/database.yml b/config/database.yml index 13ca5c9b..6ad84cb3 100644 --- a/config/database.yml +++ b/config/database.yml @@ -10,8 +10,8 @@ default: &default pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 3 } %> timeout: 5000 extensions: - - sqlite_ulid - - sqlite_vec + - SqliteExt::Ulid + - SqliteExt::Vec development: primary: diff --git a/config/initializers/sqlite.rb b/config/initializers/sqlite.rb new file mode 100644 index 00000000..57544314 --- /dev/null +++ b/config/initializers/sqlite.rb @@ -0,0 +1 @@ +require_relative "../../lib/sqlite_ext" diff --git a/config/initializers/sqlpkg.rb b/config/initializers/sqlpkg.rb deleted file mode 100644 index 2a8f6ea9..00000000 --- a/config/initializers/sqlpkg.rb +++ /dev/null @@ -1,12 +0,0 @@ -require_relative "../../lib/sqlpkg_loader" - -ActiveSupport.on_load(:active_record_sqlite3adapter) do - prepend SqlpkgLoader -end - -# Legacy -require_relative "../../lib/enhanced_sqlite3" - -ActiveSupport.on_load(:active_record_sqlite3adapter) do - prepend EnhancedSqlite3::Adapter -end diff --git a/lib/enhanced_sqlite3.rb b/lib/enhanced_sqlite3.rb deleted file mode 100644 index f351d010..00000000 --- a/lib/enhanced_sqlite3.rb +++ /dev/null @@ -1,4 +0,0 @@ -module EnhancedSqlite3 -end - -require_relative "enhanced_sqlite3/adapter" diff --git a/lib/enhanced_sqlite3/adapter.rb b/lib/enhanced_sqlite3/adapter.rb deleted file mode 100644 index 605e6f5c..00000000 --- a/lib/enhanced_sqlite3/adapter.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -# Adapted from https://github.com/fractaledmind/activerecord-enhancedsqlite3-adapter -# https://github.com/fractaledmind/activerecord-enhancedsqlite3-adapter/blob/305795a2be47c66695ecda56d8df64ec9f92b880/lib/enhanced_sqlite3/adapter.rb - -require "active_record/connection_adapters/sqlite3_adapter" - -module EnhancedSqlite3 - module Adapter - # Perform any necessary initialization upon the newly-established - # @raw_connection -- this is the place to modify the adapter's - # connection settings, run queries to configure any application-global - # "session" variables, etc. - # - # Implementations may assume this method will only be called while - # holding @lock (or from #initialize). - # - # overrides https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L691 - def configure_connection - super - configure_extensions - end - - # Patch the #transaction method to ensure that all transactions are sent to the writing role database connection pool. - def transaction(...) - ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role, prevent_writes: false) do - super - end - end - - # Patch the #log method to ensure that all log messages are tagged with the database connection name. - def log(...) - db_connection_name = ActiveRecord::Base.connection_db_config.name - if Rails.logger.formatter.current_tags.include? db_connection_name - super - else - Rails.logger.tagged(db_connection_name) { super } - end - end - - private - - def configure_extensions - @raw_connection.enable_load_extension(true) - @config.fetch(:extensions, []).each do |extension_name| - require extension_name - extension_classname = extension_name.camelize - extension_class = extension_classname.constantize - extension_class.load(@raw_connection) - rescue NameError - Rails.logger.error("Failed to find the SQLite extension class: #{extension_classname}. Skipping...") - end - @raw_connection.enable_load_extension(false) - end - end -end diff --git a/lib/sqlite_ext.rb b/lib/sqlite_ext.rb new file mode 100644 index 00000000..ccad481d --- /dev/null +++ b/lib/sqlite_ext.rb @@ -0,0 +1,2 @@ +require_relative "sqlite_ext/ulid" +require_relative "sqlite_ext/vec" diff --git a/lib/sqlite_ext/ulid.rb b/lib/sqlite_ext/ulid.rb new file mode 100644 index 00000000..a8b182dd --- /dev/null +++ b/lib/sqlite_ext/ulid.rb @@ -0,0 +1,9 @@ +require "sqlite_ulid" + +module SqliteExt + module Ulid + def self.to_path + SqliteUlid.ulid_loadable_path + end + end +end diff --git a/lib/sqlite_ext/vec.rb b/lib/sqlite_ext/vec.rb new file mode 100644 index 00000000..a2cfb447 --- /dev/null +++ b/lib/sqlite_ext/vec.rb @@ -0,0 +1,7 @@ +require "sqlite_vec" + +module SqliteExt + module Vec + def self.to_path = SqliteVec.loadable_path + end +end diff --git a/lib/sqlpkg_loader.rb b/lib/sqlpkg_loader.rb deleted file mode 100644 index 78051660..00000000 --- a/lib/sqlpkg_loader.rb +++ /dev/null @@ -1,11 +0,0 @@ -module SqlpkgLoader - def configure_connection - super - - @raw_connection.enable_load_extension(true) - Dir.glob(".sqlpkg/**/*.{dll,so,dylib}") do |extension_path| - @raw_connection.load_extension(extension_path) - end - @raw_connection.enable_load_extension(false) - end -end diff --git a/spec/lib/enhanced_sqlite3/adapter_spec.rb b/spec/lib/enhanced_sqlite3/adapter_spec.rb deleted file mode 100644 index 64c77c43..00000000 --- a/spec/lib/enhanced_sqlite3/adapter_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require "rails_helper" - -RSpec.describe EnhancedSqlite3::Adapter do - it { expect(ActiveRecord::ConnectionAdapters::SQLite3Adapter).to be < described_class } -end From db183caab0023bb9883eb3645ea04a24102df82d Mon Sep 17 00:00:00 2001 From: Ross Kaffenberger Date: Wed, 18 Dec 2024 17:27:46 -0500 Subject: [PATCH 4/4] Update fixtures --- app/javascript/test/fixtures/views/searches/combobox.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/test/fixtures/views/searches/combobox.html b/app/javascript/test/fixtures/views/searches/combobox.html index 103346b5..9634ad97 100644 --- a/app/javascript/test/fixtures/views/searches/combobox.html +++ b/app/javascript/test/fixtures/views/searches/combobox.html @@ -8,4 +8,4 @@ \ No newline at end of file + " placeholder="Search Joy of Rails" class="w-full step-1" type="search" name="query" /> \ No newline at end of file