-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
84 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,36 @@ | ||
require "active_record" | ||
require "debug" | ||
module RandomRails | ||
module Adapters | ||
module ActiveRecord | ||
module Base | ||
def random(precision: 10) | ||
# TODO: use different ways to sample data depending on the database adapter | ||
from("#{table_name} TABLESAMPLE BERNOULLI(#{precision})").limit(1) | ||
if connection.adapter_name == "postgresql" | ||
from("#{table_name} TABLESAMPLE BERNOULLI(#{precision})").limit(1) | ||
else | ||
# from("\"#{table_name}\" LIMIT 1 OFFSET (SELECT CAST(ROUND(RANDOM() * (SELECT COUNT(*) FROM \"#{table_name}\"))) AS INTEGER)") | ||
# ================= | ||
# offset_value = connection.select_value("SELECT RANDOM() % MAX(id) FROM \"people\"").abs | ||
|
||
# offset(offset_value).limit(1) | ||
# ================= | ||
# binding.irb | ||
from("\"#{table_name}\" LIMIT 1 OFFSET abs(random() % (SELECT count(*) FROM \"#{table_name}\"))") | ||
|
||
# SELECT "people".* FROM "people" LIMIT 1 OFFSET abs(random()%(SELECT count(*) FROM "people")); | ||
|
||
# from("\"#{table_name}\" OFFSET (SELECT CAST(ROUND(RANDOM() * (SELECT COUNT(*) FROM \"#{table_name}\")) AS INTEGER))") | ||
# people limit 1 offset (SELECT CAST(ROUND(RANDOM() * (SELECT COUNT(*) FROM "people")) AS INTEGER)) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
# select * from people limit 1 offset (SELECT CAST(ROUND(RANDOM() * (SELECT COUNT(*) FROM "people")) AS INTEGER)) | ||
|
||
|
||
|
||
# SELECT ROUND(RANDOM() * (SELECT COUNT(*) FROM users)) FROM users LIMIT 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require "pry" | ||
RSpec.describe RandomRails::Adapters::ActiveRecord::Base do | ||
describe "#random" do | ||
it { expect(Person).to respond_to(:random) } | ||
it { expect(Person.random).to be_a(ActiveRecord::Relation) } | ||
it { expect(Person.random.to_sql).to include("TABLESAMPLE BERNOULLI") } | ||
|
||
case ActiveRecord::Base.connection.adapter_name | ||
when "PostgreSQL" | ||
it { expect(Person.random.to_sql).to include("TABLESAMPLE BERNOULLI") } | ||
when "SQLite" | ||
it { expect(Person.random.to_sql).to include("OFFSET") } | ||
end | ||
|
||
context "when precision is specified" do | ||
it { expect(Person.random(precision: 5).to_sql).to include("TABLESAMPLE BERNOULLI(5)") } | ||
case ActiveRecord::Base.connection.adapter_name | ||
when "PostgreSQL" | ||
it { expect(Person.random(precision: 5).to_sql).to include("TABLESAMPLE BERNOULLI(5)") } | ||
when "SQLite" | ||
it { expect(Person.random(precision: 5).to_sql).to include("OFFSET") } | ||
end | ||
|
||
# the main poblem is that calling `Person.random.inspect` will execute the query with "LIMIT ?" at the end that raises a syntax error | ||
it { binding.irb; expect(Person.random.inspect).to include(ActiveRecord::Relation.to_s) } | ||
end | ||
|
||
context "when limit is specified" do | ||
it { expect(Person.random.limit(5).to_sql).to include("LIMIT 5") } | ||
end | ||
end | ||
end | ||
|
||
|
||
# Person.from(" | ||
# users | ||
# OFFSET ROUND( | ||
# RAND() * ( | ||
# SELECT COUNT(*) FROM users | ||
# ) | ||
# ) | ||
# ").limit(1).inspect | ||
|
||
|
||
# offset = "SELECT ROUND(RAND() * (SELECT COUNT(*) FROM users))" | ||
|
||
# "SELECT * FROM users OFFSET #{offset}" | ||
|
||
|
||
# # * Correct offset | ||
# # ROUND(RANDOM() * (SELECT COUNT(*) FROM people)) | ||
|
||
# offset = "ROUND(RANDOM() * (SELECT COUNT(*) FROM people))" | ||
|
||
# sql = "SELECT * FROM people OFFSET #{offset}" | ||
|
||
# Person.from("people OFFSET #{offset}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters