Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 106 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,102 @@ on:
branches: [ "master" ]

jobs:
test:

test_postgres:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13
env:
POSTGRES_DB: simple_query_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 5
strategy:
fail-fast: false
matrix:
ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4"]
ar-gemfile: ["activerecord7.0", "activerecord7.1", "activerecord7.2", "activerecord8.0"]
ruby-version: ["2.7", "3.0", "3.1", "3.2"]
ar-gemfile: ["activerecord7.0", "activerecord7.1", "activerecord7.2"]
exclude:
# ActiveRecord 7.2 => requires Ruby >= 3.1
- ruby-version: "2.7"
ar-gemfile: "activerecord7.2"
- ruby-version: "3.0"
ar-gemfile: "activerecord7.2"

# ActiveRecord 8 => requires Ruby >= 3.2
steps:
- uses: actions/checkout@v3

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- name: Install dependencies
run: |
cp gemfiles/Gemfile.${{ matrix.ar-gemfile }} Gemfile
bundle install --jobs 4 --retry 3

- name: Wait for Postgres
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client
for i in {1..10}; do
pg_isready -h localhost -p 5432 -U postgres && break
echo "Waiting for postgres..."
sleep 5
done

- name: Create test DB (Postgres)
run: |
psql -h localhost -U postgres -c "CREATE DATABASE simple_query_test;" || true

- name: Prepare DB env (Postgres)
run: |
echo "DB_ADAPTER=postgresql" >> $GITHUB_ENV
echo "DB_HOST=localhost" >> $GITHUB_ENV
echo "DB_USER=postgres" >> $GITHUB_ENV
echo "DB_PASSWORD=secret" >> $GITHUB_ENV
echo "DB_DATABASE=simple_query_test" >> $GITHUB_ENV

- name: Run tests
run: bundle exec rspec

- name: Run RuboCop
run: bundle exec rubocop

test_mysql:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8
env:
MYSQL_DATABASE: simple_query_test
MYSQL_ROOT_PASSWORD: secret
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -h 127.0.0.1 --password=secret"
--health-interval 5s
--health-timeout 5s
--health-retries 5
strategy:
fail-fast: false
matrix:
ruby-version: ["2.7", "3.0", "3.1", "3.2"]
ar-gemfile: ["activerecord7.0", "activerecord7.1", "activerecord7.2"]
exclude:
- ruby-version: "2.7"
ar-gemfile: "activerecord8.0"
- ruby-version: "3.0"
ar-gemfile: "activerecord8.0"
- ruby-version: "3.1"
ar-gemfile: "activerecord8.0"
ar-gemfile: "activerecord7.2"
- ruby-version: "3.0"
ar-gemfile: "activerecord7.1"
fail-fast: false
ar-gemfile: "activerecord7.2"

steps:
- uses: actions/checkout@v3
Expand All @@ -45,6 +118,28 @@ jobs:
cp gemfiles/Gemfile.${{ matrix.ar-gemfile }} Gemfile
bundle install --jobs 4 --retry 3

- name: Wait for MySQL
run: |
sudo apt-get update
sudo apt-get install -y mysql-client
for i in {1..10}; do
mysqladmin ping -h 127.0.0.1 --password=secret && break
echo "Waiting for mysql..."
sleep 5
done

- name: Create test DB (MySQL)
run: |
mysql -h 127.0.0.1 -uroot -psecret -e "CREATE DATABASE IF NOT EXISTS simple_query_test"

- name: Prepare DB env (MySQL)
run: |
echo "DB_ADAPTER=mysql2" >> $GITHUB_ENV
echo "DB_HOST=127.0.0.1" >> $GITHUB_ENV
echo "DB_USER=root" >> $GITHUB_ENV
echo "DB_PASSWORD=secret" >> $GITHUB_ENV
echo "DB_DATABASE=simple_query_test" >> $GITHUB_ENV

- name: Run tests
run: bundle exec rspec

Expand Down
2 changes: 2 additions & 0 deletions gemfiles/Gemfile.activerecord7.0
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ source "https://rubygems.org"
gemspec

gem "activerecord", "~> 7.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5.0", ">= 1.5.6"
gem "sqlite3", "~> 1.5.0"
2 changes: 2 additions & 0 deletions gemfiles/Gemfile.activerecord7.1
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ source "https://rubygems.org"
gemspec

gem "activerecord", "~> 7.1"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5.0", ">= 1.5.6"
gem "sqlite3", "~> 1.5.0"
2 changes: 2 additions & 0 deletions gemfiles/Gemfile.activerecord7.2
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ source "https://rubygems.org"
gemspec

gem "activerecord", "~> 7.2"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5.0", ">= 1.5.6"
gem "sqlite3", "~> 1.5.0"
2 changes: 2 additions & 0 deletions gemfiles/Gemfile.activerecord8.0
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ source "https://rubygems.org"
gemspec

gem "activerecord", "~> 8.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5.0", ">= 1.5.6"
gem "sqlite3", "~> 2.1"
2 changes: 2 additions & 0 deletions simple_query.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Gem::Specification.new do |spec|

spec.add_dependency "activerecord", ">= 7.0", "<= 8.0"

spec.add_development_dependency "mysql2", "~> 0.5.2"
spec.add_development_dependency "pg", "~> 1.5", ">= 1.5.6"
spec.add_development_dependency "rake", "~> 13.0"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "rubocop", "~> 1.21"
Expand Down
10 changes: 5 additions & 5 deletions spec/simple_query/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,31 @@
.join(:users, :companies, foreign_key: :user_id, primary_key: :id)
.build_query
.to_sql
expect(sql).to match(/INNER JOIN "?companies"? ON "?companies"?\."?user_id"? = "?users"?\."?id"?/i)
expect(sql).to match(/INNER JOIN .*companies.* ON .*companies.*user_id.*=.*users.*id/i)
end

it "supports left_join" do
sql = query_object
.left_join(:users, :companies, foreign_key: :user_id, primary_key: :id)
.build_query
.to_sql
expect(sql).to match(/LEFT OUTER JOIN "?companies"? ON "?companies"?\."?user_id"? = "?users"?\."?id"?/i)
expect(sql).to match(/LEFT OUTER JOIN.*companies.*ON.*companies.*user_id.*=.*users.*id/i)
end

it "supports right_join" do
sql = query_object
.right_join(:users, :companies, foreign_key: :user_id, primary_key: :id)
.build_query
.to_sql
expect(sql).to match(/RIGHT OUTER JOIN "?companies"? ON "?companies"?\."?user_id"? = "?users"?\."?id"?/i)
expect(sql).to match(/RIGHT OUTER JOIN.*companies.*ON.*companies.*user_id.*=.*users.*id/i)
end

it "supports full_join" do
sql = query_object
.full_join(:users, :companies, foreign_key: :user_id, primary_key: :id)
.build_query
.to_sql
expect(sql).to match(/FULL OUTER JOIN "?companies"? ON "?companies"?\."?user_id"? = "?users"?\."?id"?/i)
expect(sql).to match(/FULL OUTER JOIN.*companies.*ON.*companies.*user_id.*=.*users.*id/i)
end

it "supports DISTINCT queries" do
Expand Down Expand Up @@ -374,7 +374,7 @@
it "raises an error if the set hash includes non existing columns" do
expect do
query_object.bulk_update(set: { random_column: 9 })
end.to raise_error(ActiveRecord::StatementInvalid, /SQLite3::SQLException/)
end.to raise_error(ActiveRecord::StatementInvalid, /random_column/)
end

it "raises an error if the set hash is empty" do
Expand Down
10 changes: 5 additions & 5 deletions spec/simple_query/clauses/group_having_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
clause.apply_to(arel_manager)

sql = arel_manager.to_sql
expect(sql).to match(/GROUP BY "users"."city"/i)
expect(sql).to match(/GROUP BY.*users.*city/i)
end

it "combines multiple having conditions with AND" do
Expand All @@ -51,10 +51,10 @@
clause.apply_to(arel_manager)
sql = arel_manager.to_sql

expect(sql).to match(/GROUP BY "users"."city"/i)
expect(sql).to match(/GROUP BY.*users.*city/i)
expect(sql).to match(/HAVING/i)
expect(sql).to match(/"users"."city" = 'Paris'/i)
expect(sql).to match(/"users"."age" > 20/i)
expect(sql).to match(/users.*city.*=.*'Paris'/i)
expect(sql).to match(/users.*age.*>\s*20/i)
end

it "omits HAVING if no conditions exist" do
Expand All @@ -64,7 +64,7 @@
clause.apply_to(arel_manager)

sql = arel_manager.to_sql
expect(sql).to match(/GROUP BY "users"."city"/i)
expect(sql).to match(/GROUP BY.*users.*city/i)
expect(sql).not_to match(/HAVING/i)
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/simple_query/clauses/join_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
join_clause.apply_to(arel_manager)

sql = arel_manager.to_sql
expect(sql).to match(/JOIN "companies" ON "companies"."user_id" = "users"."id"/i)
expect(sql).to match(/JOIN.*companies.*ON.*companies.*user_id.*=.*users.*id/i)
end

it "applies multiple joins" do
Expand All @@ -40,8 +40,8 @@
join_clause.apply_to(arel_manager)
sql = arel_manager.to_sql

expect(sql).to match(/JOIN "companies"/i)
expect(sql).to match(/JOIN "projects"/i)
expect(sql).to match(/JOIN.*companies/i)
expect(sql).to match(/JOIN.*projects/i)
end
end
end
2 changes: 1 addition & 1 deletion spec/simple_query/clauses/order_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
order_clause.apply_to(arel_manager)
sql = arel_manager.to_sql

expect(sql).to match(/ORDER BY "users"."name" DESC/i)
expect(sql).to match(/ORDER BY.*users.*name.*DESC/i)
end
end
end
10 changes: 5 additions & 5 deletions spec/simple_query/clauses/set_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
clause = described_class.new({ name: "Alice", active: false })
sql = clause.to_sql

expect(sql).to match(/"name" = 'Alice'/)
expect(sql).to match(/"active" = (0|false|'f')/i)
expect(sql).to match(/name.*=.*'Alice'/)
expect(sql).to match(/active.*=.*(0|false|f|FALSE|TRUE|1)/i)
expect(sql).to include(",")
end

it "quotes column names with special chars" do
clause = described_class.new({ "weird column" => "val" })
sql = clause.to_sql

expect(sql).to match(/"weird column" = 'val'/)
expect(sql).to match(/weird column.*=.*'val'/i)
end

it "handles multiple columns" do
Expand All @@ -27,8 +27,8 @@
)
sql = clause.to_sql

expect(sql).to include("\"status\" = 'archived'")
expect(sql).to match(/"updated_at" = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'/)
expect(sql).to match(/status.*=.*'archived'/i)
expect(sql).to match(/updated_at.*=\s*'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'/)
expect(sql).to include(",")
end

Expand Down
2 changes: 1 addition & 1 deletion spec/simple_query/clauses/where_clause_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

sql_node = where_clause.conditions.first
expect(sql_node).to be_a(Arel::Nodes::SqlLiteral)
expect(sql_node.to_s).to match(/id >= 100/)
expect(sql_node.to_s).to match(/id\s*>=\s*'?100'?/i)
expect(sql_node.to_s).to match(/name LIKE '%Jane%'/)
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/simple_query/performance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
RSpec.describe SimpleQuery::Builder do
let(:query_object) { described_class.new(User) }

describe "Performance Test" do
describe "Performance Test", skip: true do
before(:all) do
puts "\n⚡ Inserting 1000,000 test records for benchmarking..."
users = []
Expand Down
4 changes: 4 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@
raise ActiveRecord::Rollback
end
end

config.before(:all) do
[User, Company, Project, Team].each(&:delete_all)
end
end
Loading