Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix unprepared statements #185

Merged
merged 14 commits into from
Jul 23, 2024
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def run_without_aborting(*tasks)
end

def configs
[ :default, :connects_to, :database, :no_database, :shards ]
[ :default, :connects_to, :database, :no_database, :shards, :unprepared_statements ]
end

task :test do
Expand Down
10 changes: 3 additions & 7 deletions app/models/solid_cache/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,8 @@ def get_sql
end

def get_all_sql(key_hashes)
if connection.prepared_statements?
@get_all_sql_binds ||= {}
@get_all_sql_binds[key_hashes.count] ||= build_sql(where(key_hash: key_hashes).select(:key, :value))
else
@get_all_sql_no_binds ||= build_sql(where(key_hash: [ 1, 2 ]).select(:key, :value)).gsub("?, ?", "?")
end
@get_all_sql ||= {}
@get_all_sql[key_hashes.count] ||= build_sql(where(key_hash: key_hashes).select(:key, :value))
end

def build_sql(relation)
Expand All @@ -134,7 +130,7 @@ def select_all_no_query_cache(query, values)
if connection.prepared_statements?
result = connection.select_all(sanitize_sql(query), "#{name} Load", Array(values), preparable: true)
else
result = connection.select_all(sanitize_sql([ query, values ]), "#{name} Load", Array(values), preparable: false)
result = connection.select_all(sanitize_sql([ query, *values ]), "#{name} Load", Array(values), preparable: false)
end

result.cast_values(SolidCache::Entry.attribute_types)
Expand Down
8 changes: 8 additions & 0 deletions test/dummy/config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ development:
primary:
<<: *default
database: <%= database("database_cache_development") %>
primary_unprepared_statements:
<<: *default
database: <%= database("database_cache_development") %>
prepared_statements: false
primary_replica:
<<: *default
database: <%= database("database_cache_development") %>
Expand All @@ -67,6 +71,10 @@ test:
primary:
<<: *default
database: <%= database("database_cache_test") %>
primary_unprepared_statements:
<<: *default
database: <%= database("database_cache_test") %>
prepared_statements: false
primary_replica:
<<: *default
database: <%= database("database_cache_test") %>
Expand Down
12 changes: 12 additions & 0 deletions test/dummy/config/solid_cache_unprepared_statements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
default: &default
database: primary_unprepared_statements

store_options:
max_age: 3600
max_size:

development:
<<: *default

test:
<<: *default
25 changes: 25 additions & 0 deletions test/dummy/db/primary_unprepared_statements_schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_01_10_111702) do
create_table "solid_cache_entries", force: :cascade do |t|
t.binary "key", limit: 1024, null: false
t.binary "value", limit: 536870912, null: false
t.datetime "created_at", null: false
t.integer "key_hash", limit: 8, null: false
t.integer "byte_size", limit: 4, null: false
t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size"
t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size"
t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true
end

end
4 changes: 2 additions & 2 deletions test/models/solid_cache/record_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class RecordTest < ActiveSupport::TestCase
test "each_shard" do
shards = SolidCache::Record.each_shard.map { SolidCache::Record.current_shard }
case ENV["SOLID_CACHE_CONFIG"]
when "config/solid_cache_no_database.yml", "config/solid_cache_database.yml"
when "config/solid_cache_no_database.yml", "config/solid_cache_database.yml", "config/solid_cache_unprepared_statements.yml"
assert_equal [ :default ], shards
when "config/solid_cache_connects_to.yml", "config/solid_cache_shards.yml", nil
assert_equal [ :primary_shard_one, :primary_shard_two, :secondary_shard_one, :secondary_shard_two ], shards
Expand All @@ -19,7 +19,7 @@ class RecordTest < ActiveSupport::TestCase
test "each_shard uses the default role" do
role = ActiveRecord::Base.connected_to(role: :reading) { SolidCache::Record.each_shard.map { SolidCache::Record.current_role } }
case ENV["SOLID_CACHE_CONFIG"]
when "config/solid_cache_no_database.yml", "config/solid_cache_database.yml"
when "config/solid_cache_no_database.yml", "config/solid_cache_database.yml", "config/solid_cache_unprepared_statements.yml"
assert_equal [ :reading ], role
when "config/solid_cache_connects_to.yml", "config/solid_cache_shards.yml", nil
assert_equal [ :writing, :writing, :writing, :writing ], role
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,6 @@ def second_shard_key
end

def single_database?
[ "config/solid_cache_database.yml", "config/solid_cache_no_database.yml" ].include?(ENV["SOLID_CACHE_CONFIG"])
[ "config/solid_cache_database.yml", "config/solid_cache_no_database.yml", "config/solid_cache_unprepared_statements.yml" ].include?(ENV["SOLID_CACHE_CONFIG"])
end
end