digital-fabric / extralite

Ruby on SQLite

Home Page:http://www.rubydoc.info/gems/extralite

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`sequel` binary fails when performing migrations

adam12 opened this issue · comments

At a cursory glance, the conn instance being called as the receiver of execute is not an instance of Sequel::Extralite::Database, but Extralite::Database.

(rdbg) ls conn    # outline command
Extralite::Database#methods: 
  changes    close       closed?              filename          last_insert_rowid   load_extension       prepare  query
  query_ary  query_hash  query_single_column  query_single_row  query_single_value  transaction_active?
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [aarch64-linux]
$ sequel -t -m migrate extralite://
/usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/logging.rb:76:in `public_send': undefined method `execute' for #<Extralite::Database:0x0000aaaaff614b08> (NoMethodError)
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/logging.rb:76:in `block in log_connection_execute'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/logging.rb:38:in `log_connection_yield'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/logging.rb:76:in `log_connection_execute'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/adapters/shared/sqlite.rb:293:in `begin_new_transaction'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/transactions.rb:360:in `begin_transaction'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/transactions.rb:248:in `_transaction'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/transactions.rb:233:in `block in transaction'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/connection_pool/threaded.rb:92:in `hold'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/connecting.rb:269:in `synchronize'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/transactions.rb:195:in `transaction'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/adapters/shared/sqlite.rb:203:in `apply_alter_table'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/schema_methods.rb:437:in `apply_alter_table_generator'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/database/schema_methods.rb:70:in `alter_table'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:628:in `schema_dataset'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:462:in `initialize'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:526:in `initialize'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:409:in `new'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:409:in `run'
        from /usr/local/bundle/gems/sequel-5.54.0/lib/sequel/extensions/migration.rb:374:in `apply'
        from /usr/local/bundle/gems/sequel-5.54.0/bin/sequel:163:in `<top (required)>'
        from /usr/local/bundle/bin/sequel:25:in `load'
        from /usr/local/bundle/bin/sequel:25:in `<main>'
$ gem list sequel extralite -l

*** LOCAL GEMS ***

sequel (5.54.0)

*** LOCAL GEMS ***

extralite-bundle (1.14)

Testing with sqlite:// as a connection string, the conn object (receiving #execute) is actually SQLite3::Database, so I think the object provided is actually correct.

I think what's missing is an Extralite method that can fire off queries, and not care about their return value. Then inside Sequel::Extralite::Database, we can define the private connection_execute_method method which returns the symbol for the name of that method.

I think what's missing is an Extralite method that can fire off queries, and not care about their return value.

I'm thinking this isn't entirely accurate, now that I've fiddled with it a bit more. If you override connection_execute_method to return :query, it starts to work somewhat, but fails when trying to set up the migration table.

When setting up the migration table, it creates the table, then tries to alter the same table. Experimenting with this manually, performing a SELECT * FROM schema_info with the SQLite adapter returns a fancy object. The same query when done with the Extralite adapter returns an empty Array. There's no way to determine the columns from there.

Maybe these are two separate issues. I'm not really sure where to proceed from here.

# test.rb
DB.create_table(:schema_info) { primary_key :id }

p DB.from(:schema_info).columns
$ sequel -E extralite:// test.rb 
I, [2022-04-07T16:43:42.003466 #60279]  INFO -- : (0.000028s) PRAGMA foreign_keys = 1
I, [2022-04-07T16:43:42.003516 #60279]  INFO -- : (0.000004s) PRAGMA case_sensitive_like = 1
I, [2022-04-07T16:43:42.006106 #60279]  INFO -- : (0.000164s) CREATE TABLE `schema_info` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT)
I, [2022-04-07T16:43:42.006221 #60279]  INFO -- : (0.000016s) SELECT sqlite_version()
I, [2022-04-07T16:43:42.006309 #60279]  INFO -- : (0.000012s) SELECT * FROM `schema_info` LIMIT 0
[]
$ sequel -E sqlite:// test.rb 
I, [2022-04-07T16:43:17.355544 #60128]  INFO -- : (0.000251s) PRAGMA foreign_keys = 1
I, [2022-04-07T16:43:17.355611 #60128]  INFO -- : (0.000011s) PRAGMA case_sensitive_like = 1
I, [2022-04-07T16:43:17.357938 #60128]  INFO -- : (0.000203s) CREATE TABLE `schema_info` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT)
I, [2022-04-07T16:43:17.358107 #60128]  INFO -- : (0.000063s) SELECT sqlite_version()
I, [2022-04-07T16:43:17.358238 #60128]  INFO -- : (0.000025s) SELECT * FROM `schema_info` LIMIT 0
[:id]

Could you give a script that reproduces this?

Could you give a script that reproduces this?

Here's one for the migrations. The missing columns are above.

#!/usr/bin/env ruby
require "bundler/inline"
require "tmpdir"

gemfile do
  source "https://rubygems.org"
  
  gem "sequel"
  gem "extralite"
end

Dir.mktmpdir("extralite-migration") do |dir|
  File.write(dir + "/001_migrate.rb", <<~RUBY)
    Sequel.migration do 
      change do
        create_table(:foobars) { primary_key :id } 
      end
    end
  RUBY

  Sequel.extension :migration
  DB = Sequel.connect("extralite://")
  Sequel::Migrator.run(DB, dir)
end