Git Product home page Git Product logo

activerecord-enhancedsqlite3-adapter's Introduction

Hi there 👋

I’m Stephen. I am an American expat living in Berlin with my wife and 2 dogs—Tuck 🐶 and Ruby 🐕 (weirdly both emoji are pretty accurate depictions). I am someone who sweats the details, someone that would rather design in CodePen than Figma, someone who can learn both deeply and quickly because they aren't afraid to read obscure low-level source code or keep tabs on upcoming HTML, CSS, and JS features, and someone that enjoys sharing problems, solutions, tips and tricks with others.

I'm a quick learner

At this point two years ago, I had never read or written a line of C, knew nearly nothing about SQLite, and had only contributed one small documentation fix to Rails core. Fast forward to today, I am now a top-500 Rails core contributor. I have written multiple PRs to the sqlite3-ruby gem (I'm now a top-5 contributor), including a few in C. I have also now read large swathes of the SQLite C source code, and I am in the process of writing a lexer and parser for SQLite by translating the entagled C code into Ruby. I am now recognized as one of the the experts in SQLite in the Ruby community.

Similarly, when I got my first job in tech after leaving graduate school in Classical Studies, I had never written a line of Ruby and knew nothing about Rails. Nonetheless, within 6 months of starting I was promoted from junior to mid-level Rails developer. In my second job, I was again promoted after 6 months in the role. This time, though, I was promoted to an engineering management role, and I have spent the last 4 years growing our team from 6 on-site, full-stack engineers maintaining one product to a department of 45+ remote engineers who have built and now maintain 4 products.

My key to learning new topics, tools, or technologies is to dive in head first and build something. I am a hands-on learner. Whether it is things for work or things I am simply interested in, I learn by doing. Being such a hands-on "manager-of-one" has granted me essentially all of my opportunities. I got into tech by building tools to be a more effective and efficient scholar. I got my first job from building Alfred workflows. And I now have a reputation in the Ruby community for my work on SQLite because I built various applications using SQLite and numerous tools on top of SQLite.

I'm a minimalist perfectionist

I like to focus on leverage—how you I produce the absolute best possible interface, component, DX with the absolute minimal bloat. I think of myself as a minimalist perfectionists.

I recently tried to implement the Superlist inbox page in Tailwind CSS, which I could only do by eye as the source code is not available. I then spent the next two weeks before leaving for my wedding working to build a Rails clone using cutting-egde browser features (e.g. popovers and anchor positioning) and morphing. I streamed the whole process. It isn't perfect, I am still not satisfied with it, but I also didn't let that stop me from iterating, shipping, and sharing.

I also love to explore UX patterns to try and find an optimal balance between beauty, usability, and simplicity. As one example, I experimented with two different approaches to building a multiple file input in an edit form. In one version, I split the already saved files from the newly attached files and displayed them in two separate lists. In the other, I combined them into a single list but varied their styling. I believe that the second approach is more intuitive and user-friendly, but I am not sure. I would love to hear your thoughts. For one other example, I tried a few different approaches to an avatar component. I started off with a simple screen name text input that generates a deterministic avatar from Boring avatars. I then tried using a generated avatar from avvvatars along with a file upload button. Finally, I allowed the user to choose if they wanted a shape or initial-based avatar or upload a custom image. Polish isn't simply how it looks statically, but how it works and feels to use.

I want to delight

Where I am from in Louisiana, we have the concept of lagniappe, or a little something extra. I want the things I build to have lagniappe. When I was exploring inline text editing, I wanted to keep things simple by simply stying regular form inputs to either look like static content or editable fields depending on focus, but I also wanted that transition between states to be delightful. I've experimented with both single line and multi-line inputs, which each utilizing slight Tailwind animations. In fact, my very first larger project was a CSS library to provide a collection of icons that you could visually toggle between, like an up-chevron morphing into a down-chevron.

I will spend hours tweaking slides, even just for our company's bi-weekly Townhalls, where I have ended up incidentally defining much of the aesthetic of our slide deck. In the slide deck for my most recent conference talk, I spent days scouring the internet, working with GPTs, and experimenting in Sketch just to create this one image of a red ruby and a blue feather that I only use for a few seconds.

I also care deeply about the polish and delight in the code interfaces I build. I had been experimenting with Tachyons for a bit and liked atomic CSS, but I found their terse class names to be a bit too terse. I strive to strike a similar balance in the code that I write, especially that code that is meant to be consumed by other developers. I want my code to be a joy to use, delightful to read, and a pleasure to maintain.

Finally, I look to delight people through speaking and sharing. I will give talks at no less than 4 conferences this year. I have also been a guest on various podcasts, and I am writing regularly on various topics in web development. This year I also started a Youtube channel where I have done a two week sprint building the Superlist clone. When I look into the future of my career, I see myself continuing to share and teach, whether that be through speaking, writing, or mentoring.

activerecord-enhancedsqlite3-adapter's People

Contributors

fractaledmind avatar npezza93 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

activerecord-enhancedsqlite3-adapter's Issues

Compatibility with sqlite3 v2?

This gem depends on sqlite3 ~> 1.6. Is it possible to release a new version which allows using sqlite3 v2.0.x? (Assuming they're compatible?)

corrupting disk image

ehh - hate to be the guy to cry: wolf!

but I've just spoiled my development.sqlite3 with 10MB of payload - which is not a big deal (but if my production with 50 times that will perform likewise ...)

couldn't help notice the mention on your gem in the plot and as this is my first corrupted DB file since MySQL changed their password strategy back in the day, I'm somewhat edgy 🥹

anything I can do to rule out enhancedsqlite3 being the culprit?

An error occurred when inspecting the object: #<ActiveRecord::StatementInvalid: SQLite3::CorruptException: database disk image is malformed>
An error occurred when running Kernel#inspect: #<ActiveRecord::StatementInvalid: SQLite3::CorruptException: database disk image is malformed>
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/sqlite3-2.0.1-arm64-darwin/lib/sqlite3/statement.rb:36:in `prepare'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/sqlite3-2.0.1-arm64-darwin/lib/sqlite3/statement.rb:36:in `initialize'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/sqlite3-2.0.1-arm64-darwin/lib/sqlite3/database.rb:166:in `new'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/sqlite3-2.0.1-arm64-darwin/lib/sqlite3/database.rb:166:in `prepare'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb:36:in `block (2 levels) in internal_exec_query'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:997:in `block in with_raw_connection'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:969:in `with_raw_connection'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb:33:in `block in internal_exec_query'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:1112:in `log'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-enhancedsqlite3-adapter-0.7.0/lib/enhanced_sqlite3/adapter.rb:67:in `block in log'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/tagged_logging.rb:139:in `block in tagged'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/tagged_logging.rb:39:in `tagged'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/tagged_logging.rb:139:in `tagged'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activesupport/lib/active_support/broadcast_logger.rb:240:in `method_missing'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-enhancedsqlite3-adapter-0.7.0/lib/enhanced_sqlite3/adapter.rb:67:in `log'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb:32:in `internal_exec_query'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:114:in `query'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:110:in `query_values'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb:35:in `data_sources'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/schema_cache.rb:430:in `block in tables_to_cache'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:399:in `with_connection'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/schema_cache.rb:429:in `tables_to_cache'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/schema_cache.rb:313:in `data_source_exists?'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/schema_cache.rb:38:in `data_source_exists?'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/connection_adapters/schema_cache.rb:182:in `data_source_exists?'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/model_schema.rb:418:in `table_exists?'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/activerecord/lib/active_record/core.rb:358:in `inspect'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb/inspector.rb:101:in `inspect'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb/inspector.rb:101:in `bind_call'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb/inspector.rb:101:in `rescue in inspect_value'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb/inspector.rb:95:in `inspect_value'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb/context.rb:639:in `inspect_last_value'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1387:in `output_value'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1057:in `block (2 levels) in eval_input'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1380:in `signal_status'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1041:in `block in eval_input'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1120:in `block in each_top_level_statement'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1117:in `loop'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1117:in `each_top_level_statement'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1040:in `eval_input'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1021:in `block in run'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1020:in `catch'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.13.1/lib/irb.rb:1020:in `run'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/commands/console/irb_console.rb:106:in `start'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/commands/console/console_command.rb:59:in `start'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/commands/console/console_command.rb:8:in `start'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/commands/console/console_command.rb:87:in `perform'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor/command.rb:28:in `run'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor/invocation.rb:127:in `invoke_command'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/command/base.rb:178:in `invoke_command'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor.rb:527:in `dispatch'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/command/base.rb:73:in `perform'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/command.rb:71:in `block in invoke'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/command.rb:149:in `with_argv'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/command.rb:69:in `invoke'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/rails-e3867798a001/railties/lib/rails/commands.rb:18:in `<main>'
<internal:/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
<internal:/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
/Users/walther/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/bootsnap-1.18.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'

ActiveRecord::ReadOnlyError: Write query attempted while in readonly mode: UPDATE

been wanting to report on this one for a bit now - here goes:

I have a routine which I foresee will get hit quite a lot thus I push it into a background job. When I call it - I somewhat anticipated the subject error (whilst crossing my fingers for enhancedsqlite3 having my back); you could say fearing the worst, hoping the best:

This is what I see in my log

Started PUT "/pos/employee?api_key=[FILTERED]&id=14" for 127.0.0.1 at 2024-05-29 16:25:10 +0200
Processing by Pos::EmployeeController#update as TURBO_STREAM
  Parameters: {"punch"=>{"punched_at"=>"2024-05-27T16:05"}, "api_key"=>"[FILTERED]", "id"=>"14"}
[reader]   Employee Load (0.1ms)  SELECT "employees".* FROM "employees" WHERE "employees"."access_token" = ? LIMIT ?  [["access_token", "[FILTERED]"], ["LIMIT", 1]]
[reader]   ↳ app/controllers/pos/employee_controller.rb:112:in `verify_employee'
[reader]   Account Load (0.0ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[reader]   ↳ app/controllers/pos/employee_controller.rb:118:in `verify_employee'
[reader]   Punch Load (0.0ms)  SELECT "punches".* FROM "punches" WHERE "punches"."id" = ? LIMIT ?  [["id", 14], ["LIMIT", 1]]
[reader]   ↳ app/controllers/pos/employee_controller.rb:72:in `update'
[writer]   TRANSACTION (0.0ms)  begin transaction
[writer]   ↳ app/controllers/pos/employee_controller.rb:73:in `update'
[writer]   Punch Update (0.5ms)  UPDATE "punches" SET "punched_at" = ?, "updated_at" = ? WHERE "punches"."id" = ?  [["punched_at", "2024-05-27 14:05:00"], ["updated_at", "2024-05-29 14:25:10.685468"], ["id", 14]]
[writer]   ↳ app/controllers/pos/employee_controller.rb:73:in `update'
[writer]   TRANSACTION (0.0ms)  commit transaction
[writer]   ↳ app/controllers/pos/employee_controller.rb:73:in `update'
[reader]   Employee Load (0.0ms)  SELECT "employees".* FROM "employees" WHERE "employees"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
[reader]   ↳ app/controllers/pos/employee_controller.rb:74:in `update'
-----------------
Recalculating abrahamski on 2024-05-27
-----------------
[reader]   Account Load (0.1ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[reader]   ↳ app/models/concerns/sum_punches.rb:14:in `recalculate'
[reader]   PunchCard Load (0.3ms)  SELECT "punch_cards".* FROM "punch_cards" WHERE "punch_cards"."account_id" = ? AND "punch_cards"."employee_id" = ? AND "punch_cards"."work_date" = ? ORDER BY "punch_cards"."id" ASC LIMIT ?  [["account_id", 1], ["employee_id", 4], ["work_date", "2024-05-27"], ["LIMIT", 1]]
[reader]   ↳ app/models/concerns/sum_punches.rb:14:in `recalculate'
[reader]   Punch Exists? (0.1ms)  SELECT 1 AS one FROM "punches" WHERE "punches"."employee_id" = ? AND "punches"."punched_at" BETWEEN ? AND ? LIMIT ?  [["employee_id", 4], ["punched_at", "2024-05-26 22:00:00"], ["punched_at", "2024-05-27 21:59:59.999999"], ["LIMIT", 1]]
[reader]   ↳ app/models/concerns/sum_punches.rb:22:in `recalculate'
[reader]   Punch Count (0.0ms)  SELECT COUNT(*) FROM "punches" WHERE "punches"."employee_id" = ? AND "punches"."punched_at" BETWEEN ? AND ?  [["employee_id", 4], ["punched_at", "2024-05-26 22:00:00"], ["punched_at", "2024-05-27 21:59:59.999999"]]
[reader]   ↳ app/models/concerns/sum_punches.rb:17:in `recalculate'
-----------------
#<ActiveRecord::ReadOnlyError: Write query attempted while in readonly mode: UPDATE "punches" SET "punch_card_id" = ? WHERE ("punches"."id") IN (SELECT "punches"."id" FROM "punches" WHERE "punches"."employee_id" = ? AND "punches"."punched_at" BETWEEN ? AND ? ORDER BY "punches"."punched_at" DESC)>
-----------------
  Rendered pos/employee/_punch.html.erb (Duration: 0.5ms | GC: 0.0ms)
Completed 200 OK in 71ms (Views: 0.2ms | ActiveRecord: 1.2ms (9 queries, 0 cached) | GC: 1.0ms)

The method in question looks like this:

    punches = employee.punches.where(punched_at: date.beginning_of_day..date.end_of_day).order(punched_at: :desc)
    ...
    when 2; two_punches pc, punches
    ...

    def two_punches(pc, punches)
      punches.update_all punch_card_id: pc.id
      return unless punches.second.in? && punches.first.out?
      pc.update work_minutes: (punches.first.punched_at - punches.second.punched_at) / 60
    end

It is - in fact easily remedied by

          ActiveRecord::Base.connected_to(role: :writing) do
              punches = employee.punches.where(punched_at: date.beginning_of_day..date.end_of_day).order(punched_at: :desc)
              ...
              when 2; two_punches pc, punches
          end

- so my only issue with this is, I guess, I was hoping for enhanced to band-aid this 😉

Unable to run db:migrate

As the title says, I receive the following in the error log whenever I attempt to run db:migrate:

ActiveRecord::StatementInvalid: SQLite3::ReadOnlyException: attempt to write a readonly database 

My database.yml is setup as follows:

default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  reader:
    <<: *default
    readonly: true
    database: storage/development.sqlite3
  writer:
    <<: *default
    pool: 1
    database: storage/development.sqlite3

The test and production databases are setup accordingly but have been left out for brevity. I was largely following the guide found here. Thanks in advance :-)

Using this gem in another rails gem for testing

Hi there @fractaledmind, I was just wondering if there was anything special required in order to use this gem to assist with SQLite3::BusyException in testing another gem?

I'm working on https://github.com/brendon/positioning and have run into conflicts in the following test when I ramp up the number of threads:

class TestTransactionSafety < Minitest::Test
  def test_no_duplicate_row_values
    ActiveRecord::Base.connection_handler.clear_all_connections!

    list = List.create name: "List"
    students = []

    10.times do
      threads = 200.times.map do
        Thread.new do
          ActiveRecord::Base.connection_pool.with_connection do
            students << list.authors.create(name: "Student", type: "Author::Student")
          end
        end
      end
      threads.each(&:join)
    end

    assert_equal (1..students.length).to_a, list.authors.map(&:position)

    list.destroy
  end
end

I've put together an advisory lock based on a file lock technique I saw in the Advisory Lock gem but was still encountering errors and your mention of the default treatment of transactions with the sqlite3 gem in Rails made me think that perhaps that's what's going on here too.

Not the most fun thing to try and figure out unfortunately :D

Any chance of adding AUTOINCREMENT?

I'm using the new Rails composite primary keys. There doesn't seem to be a way to make those those columns increment via ActiveRecord, even though SQLite has AUTOINCREMENT and there is an :auto_increment option for MySQL.

Any chance of adding an :autoincrement option to this gem? I can potentially assist with the PR, but I'll likely need help.

`bin/rails db:prepare` breaks virtual/generated columns in `db/schema.rb`

Thanks for everything you're doing for Rails and SQLite. The content you've been putting out and the code contributions you've been making are super helpful in my SQLite journey ❤️ And a great gem that lets us use these features in a tagged Rails version today.

I think I found a bug with virtual/generated columns. The summary is bin/rails db:migrate correctly adds virtual columns to db/schema.rb while bin/rails db:prepare changes the column type to the concrete type in db/schema.rb. I put together a minimal reproduction at https://github.com/cmoel/rails_sqlite_generated_column_schema_bug.

Overview of the bug

Generate 2 migrations, one to create the table and one to add the generated column. This is the create_table entry in db/schema.rb after running bin/rails db:migrate:

  create_table "syncs", force: :cascade do |t|
    t.integer "person_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.datetime "unblocked_at"
    t.virtual "blocked", type: :boolean, as: "case when unblocked_at is null then '1' else null end", stored: false
    t.index ["person_id", "blocked"], name: "index_syncs_on_person_id_and_blocked", unique: true
  end

I then ran bin/rails db:prepare and the create_table entry was changed. This is the diff

diff --git a/db/schema.rb b/db/schema.rb
index 5594677..9bc0e13 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -21,7 +21,7 @@
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.datetime "unblocked_at"
-    t.virtual "blocked", type: :boolean, as: "case when unblocked_at is null then '1' else null end", stored: false
+    t.boolean "blocked"
     t.index ["person_id", "blocked"], name: "index_syncs_on_person_id_and_blocked", unique: true
   end

I wouldn't have expected bin/rails db:prepare to change db/schema.rb, and particularly wouldn't have expected it to change a column type.

Do you have any advice on a way forward? Is this possibly an issue with Rails and not activerecord-enhancedsqlite3-adapter?

I ran through the same reproduction steps on a new Rails main app (rails new app_name --minimal --main) without activerecord-enhancedsqlite3-adapter and bin/rails db:prepare yielded the same change to db/schema.rb. Would it make more sense to open this issue on the Rails repo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.