From 8f4ab5e331e43a4512408eaaa7b3ef03469d65e4 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Tue, 29 Sep 2020 12:39:41 -0400 Subject: [PATCH 01/10] Update Ruby to 2.7.1 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 24ba9a3..860487c 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.0 +2.7.1 From 612cd9e1dc400a4b5ff86d214eb64d5552d19b97 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Tue, 29 Sep 2020 12:40:33 -0400 Subject: [PATCH 02/10] Ignore .tool-versions file for asdf users --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8be9e24..fe94da1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ *.a mkmf.log /projectFilesBackup +.tool-versions From 47cfdc8a11913decfa777a784ff61f1955f25c7c Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Tue, 29 Sep 2020 12:46:15 -0400 Subject: [PATCH 03/10] Update Ruby gems --- gemfiles/rails_5_1.gemfile.lock | 51 +++++++++++++------------- gemfiles/rails_5_2.gemfile.lock | 63 ++++++++++++++++----------------- gemfiles/rails_6_0.gemfile.lock | 53 +++++++++++++-------------- 3 files changed, 79 insertions(+), 88 deletions(-) diff --git a/gemfiles/rails_5_1.gemfile.lock b/gemfiles/rails_5_1.gemfile.lock index 2c579dd..ae264fd 100644 --- a/gemfiles/rails_5_1.gemfile.lock +++ b/gemfiles/rails_5_1.gemfile.lock @@ -22,7 +22,7 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - appraisal (2.2.0) + appraisal (2.3.0) bundler rake thor (>= 0.14.0) @@ -31,49 +31,46 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - codecov (0.1.16) + codecov (0.2.11) json simplecov - url coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.7) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - diff-lcs (1.3) + diff-lcs (1.4.4) docile (1.3.2) equalizer (0.0.11) - i18n (1.8.2) + i18n (1.8.5) concurrent-ruby (~> 1.0) ice_nine (0.11.2) - json (2.3.0) - minitest (5.14.0) + json (2.3.1) + minitest (5.14.2) pg (0.18.4) rake (13.0.1) - rspec (3.8.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-core (3.8.0) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.1) + rspec (3.9.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.3) simple_serializer (1.0.2) - simplecov (0.17.1) + simplecov (0.19.0) docile (~> 1.1) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) - thor (0.20.0) + simplecov-html (~> 0.11) + simplecov-html (0.12.3) + thor (1.0.1) thread_safe (0.3.6) - tzinfo (1.2.6) + tzinfo (1.2.7) thread_safe (~> 0.1) - url (0.3.2) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) @@ -98,4 +95,4 @@ RUBY VERSION ruby 2.6.3p62 BUNDLED WITH - 1.17.2 + 2.1.4 diff --git a/gemfiles/rails_5_2.gemfile.lock b/gemfiles/rails_5_2.gemfile.lock index 8a16f76..6bb3af2 100644 --- a/gemfiles/rails_5_2.gemfile.lock +++ b/gemfiles/rails_5_2.gemfile.lock @@ -9,20 +9,20 @@ PATH GEM remote: https://rubygems.org/ specs: - activemodel (5.2.4.1) - activesupport (= 5.2.4.1) - activerecord (5.2.4.1) - activemodel (= 5.2.4.1) - activesupport (= 5.2.4.1) + activemodel (5.2.4.4) + activesupport (= 5.2.4.4) + activerecord (5.2.4.4) + activemodel (= 5.2.4.4) + activesupport (= 5.2.4.4) arel (>= 9.0) activerecord-import (0.13.0) activerecord (>= 3.0) - activesupport (5.2.4.1) + activesupport (5.2.4.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - appraisal (2.2.0) + appraisal (2.3.0) bundler rake thor (>= 0.14.0) @@ -31,49 +31,46 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - codecov (0.1.16) + codecov (0.2.11) json simplecov - url coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.7) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - diff-lcs (1.3) + diff-lcs (1.4.4) docile (1.3.2) equalizer (0.0.11) - i18n (1.8.2) + i18n (1.8.5) concurrent-ruby (~> 1.0) ice_nine (0.11.2) - json (2.3.0) - minitest (5.14.0) + json (2.3.1) + minitest (5.14.2) pg (0.18.4) rake (13.0.1) - rspec (3.8.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-core (3.8.0) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.1) + rspec (3.9.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.3) simple_serializer (1.0.2) - simplecov (0.17.1) + simplecov (0.19.0) docile (~> 1.1) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) - thor (0.20.0) + simplecov-html (~> 0.11) + simplecov-html (0.12.3) + thor (1.0.1) thread_safe (0.3.6) - tzinfo (1.2.6) + tzinfo (1.2.7) thread_safe (~> 0.1) - url (0.3.2) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) @@ -98,4 +95,4 @@ RUBY VERSION ruby 2.6.3p62 BUNDLED WITH - 1.17.2 + 2.1.4 diff --git a/gemfiles/rails_6_0.gemfile.lock b/gemfiles/rails_6_0.gemfile.lock index edb8120..925e489 100644 --- a/gemfiles/rails_6_0.gemfile.lock +++ b/gemfiles/rails_6_0.gemfile.lock @@ -9,20 +9,20 @@ PATH GEM remote: https://rubygems.org/ specs: - activemodel (6.0.2.1) - activesupport (= 6.0.2.1) - activerecord (6.0.2.1) - activemodel (= 6.0.2.1) - activesupport (= 6.0.2.1) - activerecord-import (1.0.4) + activemodel (6.0.3.3) + activesupport (= 6.0.3.3) + activerecord (6.0.3.3) + activemodel (= 6.0.3.3) + activesupport (= 6.0.3.3) + activerecord-import (1.0.6) activerecord (>= 3.2) - activesupport (6.0.2.1) + activesupport (6.0.3.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - zeitwerk (~> 2.2) - appraisal (2.2.0) + zeitwerk (~> 2.2, >= 2.2.2) + appraisal (2.3.0) bundler rake thor (>= 0.14.0) @@ -30,55 +30,52 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - codecov (0.1.16) + codecov (0.2.11) json simplecov - url coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.7) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - diff-lcs (1.3) + diff-lcs (1.4.4) docile (1.3.2) equalizer (0.0.11) - i18n (1.8.2) + i18n (1.8.5) concurrent-ruby (~> 1.0) ice_nine (0.11.2) - json (2.3.0) - minitest (5.14.0) - pg (1.2.2) + json (2.3.1) + minitest (5.14.2) + pg (1.2.3) rake (13.0.1) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.0) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-support (3.9.2) + rspec-support (3.9.3) simple_serializer (1.0.2) - simplecov (0.17.1) + simplecov (0.19.0) docile (~> 1.1) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) + simplecov-html (~> 0.11) + simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) - tzinfo (1.2.6) + tzinfo (1.2.7) thread_safe (~> 0.1) - url (0.3.2) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) equalizer (~> 0.0, >= 0.0.9) - zeitwerk (2.2.2) + zeitwerk (2.4.0) PLATFORMS ruby From 78c7c1ac8061401762ef5861c8ca6feddee21452 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 11:25:57 -0400 Subject: [PATCH 04/10] Revert bundler to v1 for Ruby < 2.7 --- gemfiles/rails_5_1.gemfile.lock | 2 +- gemfiles/rails_5_2.gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gemfiles/rails_5_1.gemfile.lock b/gemfiles/rails_5_1.gemfile.lock index ae264fd..1c77a35 100644 --- a/gemfiles/rails_5_1.gemfile.lock +++ b/gemfiles/rails_5_1.gemfile.lock @@ -95,4 +95,4 @@ RUBY VERSION ruby 2.6.3p62 BUNDLED WITH - 2.1.4 + 1.17.3 diff --git a/gemfiles/rails_5_2.gemfile.lock b/gemfiles/rails_5_2.gemfile.lock index 6bb3af2..e3939f3 100644 --- a/gemfiles/rails_5_2.gemfile.lock +++ b/gemfiles/rails_5_2.gemfile.lock @@ -95,4 +95,4 @@ RUBY VERSION ruby 2.6.3p62 BUNDLED WITH - 2.1.4 + 1.17.3 From 16d9666089d28a04e0a9c70fd17d466261e9844e Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 11:39:15 -0400 Subject: [PATCH 05/10] Have Travis CI use the most recent version of Ruby 2.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a8d520c..ebe5f13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ services: - postgresql matrix: include: - - rvm: 2.5.7 + - rvm: 2.5 gemfile: gemfiles/rails_5_1.gemfile - rvm: 2.6 gemfile: gemfiles/rails_5_1.gemfile From b53f35e94c69e276dd199cfefe87cc148bc9ce13 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 20:48:18 -0400 Subject: [PATCH 06/10] Use Rails 6 insert_all and upsert_all methods --- lib/vorpal/driver/postgresql.rb | 42 ++++++++- lib/vorpal/version.rb | 2 +- spec/helpers/db_helpers.rb | 10 +++ .../vorpal/driver/postgresql_spec.rb | 88 ++++++++++++++++++- spec/integration_spec_helper.rb | 2 + spec/performance/vorpal/performance_spec.rb | 6 ++ vorpal.gemspec | 1 + 7 files changed, 145 insertions(+), 6 deletions(-) diff --git a/lib/vorpal/driver/postgresql.rb b/lib/vorpal/driver/postgresql.rb index 7d6543e..aff0b4f 100644 --- a/lib/vorpal/driver/postgresql.rb +++ b/lib/vorpal/driver/postgresql.rb @@ -9,7 +9,12 @@ def initialize end def insert(db_class, db_objects) - if defined? ActiveRecord::Import + if ActiveRecord::VERSION::MAJOR >= 6 + return if db_objects.empty? + + update_timestamps_on_create(db_class, db_objects) + db_class.insert_all!(db_objects.map(&:attributes)) + elsif defined? ActiveRecord::Import db_class.import(db_objects, validate: false) else db_objects.each do |db_object| @@ -19,8 +24,15 @@ def insert(db_class, db_objects) end def update(db_class, db_objects) - db_objects.each do |db_object| - db_object.save!(validate: false) + if ActiveRecord::VERSION::MAJOR >= 6 + return if db_objects.empty? + + update_timestamps_on_update(db_class, db_objects) + db_class.upsert_all(db_objects.map(&:attributes)) + else + db_objects.each do |db_object| + db_object.save!(validate: false) + end end end @@ -100,6 +112,30 @@ def query(db_class, aggregate_mapper) private + # Adapted from https://github.com/rails/rails/blob/614580270d7789e5275defc3da020ce27b3b2302/activerecord/lib/active_record/timestamp.rb#L99 + def update_timestamps_on_create(db_class, db_objects) + return unless db_class.record_timestamps + + current_time = db_class.current_time_from_proper_timezone + db_objects.each do |db_object| + db_class.all_timestamp_attributes_in_model.each do |column| + db_object.write_attribute(column, current_time) unless db_object.read_attribute(column) + end + end + end + + #Adapted from https://github.com/rails/rails/blob/614580270d7789e5275defc3da020ce27b3b2302/activerecord/lib/active_record/timestamp.rb#L111 + def update_timestamps_on_update(db_class, db_objects) + return unless db_class.record_timestamps + + current_time = db_class.current_time_from_proper_timezone + db_objects.each do |db_object| + db_class.timestamp_attributes_for_update_in_model.each do |column| + db_object.write_attribute(column, current_time) + end + end + end + def sequence_name(db_class) @sequence_names[db_class] ||= execute( "SELECT substring(column_default from '''(.*)''') FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1 AND column_name = 'id' LIMIT 1", diff --git a/lib/vorpal/version.rb b/lib/vorpal/version.rb index 8eaa1ff..ced5e96 100644 --- a/lib/vorpal/version.rb +++ b/lib/vorpal/version.rb @@ -1,3 +1,3 @@ module Vorpal - VERSION = "1.0.3" + VERSION = "1.0.4" end diff --git a/spec/helpers/db_helpers.rb b/spec/helpers/db_helpers.rb index 5fadc63..15580e4 100644 --- a/spec/helpers/db_helpers.rb +++ b/spec/helpers/db_helpers.rb @@ -49,6 +49,16 @@ def define_table(table_name, columns, force) end end + # Has the same API as the Rails create_table, except doesn't die when the + # table already exists + def create_table(table_name, force: nil, **options) + return unless table_name_is_free?(table_name) || force + + db_connection.create_table(table_name, **{ force: force, **options }) do |t| + yield t + end + end + def defineAr(table_name) Class.new(ActiveRecord::Base) do self.table_name = table_name diff --git a/spec/integration/vorpal/driver/postgresql_spec.rb b/spec/integration/vorpal/driver/postgresql_spec.rb index 6132d87..8b16ea0 100644 --- a/spec/integration/vorpal/driver/postgresql_spec.rb +++ b/spec/integration/vorpal/driver/postgresql_spec.rb @@ -1,7 +1,19 @@ +# frozen_string_literal: true + require 'integration_spec_helper' require 'vorpal' describe Vorpal::Driver::Postgresql do + before(:all) do + create_table('actors') do |t| + t.string :name + t.timestamps + t.index :name, unique: true + end + end + + let(:db_driver) { Vorpal::Driver::Postgresql.new } + describe '#build_db_class' do let(:db_class) { subject.build_db_class(PostgresDriverSpec::Foo, 'example') } @@ -24,7 +36,69 @@ it 'uses the model class name to make the generated AR::Base class name unique' do db_class = build_db_class(PostgresDriverSpec::Foo) - expect(db_class.name).to match("PostgresDriverSpec__Foo") + expect(db_class.name).to match('PostgresDriverSpec__Foo') + end + end + + describe '#insert' do + it 'sets the created_at column' do + nick_cage = build_actor(created_at: nil) + + db_driver.insert(PostgresDriverSpec::Actor, [nick_cage]) + + nick_cage.reload + expect(nick_cage.created_at).to_not be_nil + end + + it 'blows up if a duplicate PK is used' do + nick_cage = build_actor(id: 1, name: 'Nicholas Cage') + will_farrell = build_actor(id: 1, name: 'William Farrell') + + expect do + db_driver.insert(PostgresDriverSpec::Actor, [nick_cage, will_farrell]) + end.to raise_exception(ActiveRecord::RecordNotUnique) + end + + it 'blows up if a non-PK uniqueness constraint is violated' do + nick_cage = build_actor(id: 1, name: 'Nicholas Cage') + nick_cage2 = build_actor(id: 2, name: 'Nicholas Cage') + + expect do + db_driver.insert(PostgresDriverSpec::Actor, [nick_cage, nick_cage2]) + end.to raise_exception(ActiveRecord::RecordNotUnique) + end + end + + describe '#update' do + it 'sets the updated_at column' do + actor = create_actor + + Timecop.freeze(Time.local(2000, 1, 1)) do + db_driver.update(PostgresDriverSpec::Actor, [actor]) + end + + actor.reload + expect(actor.updated_at).to eq(Time.local(2000, 1, 1)) + end + + it 'leaves the created_at column alone' do + actor = create_actor + old_created_at = actor.created_at + + db_driver.update(PostgresDriverSpec::Actor, [actor]) + + actor.reload + expect(actor.created_at).to eq(old_created_at) + end + + it 'blows up if a non-PK uniqueness constraint is violated' do + nick_cage = create_actor(id: 1, name: 'Nicholas Cage') + nick_cage2 = create_actor(id: 2) + nick_cage2.name = nick_cage.name + + expect do + db_driver.update(PostgresDriverSpec::Actor, [nick_cage, nick_cage2]) + end.to raise_exception(ActiveRecord::RecordNotUnique) end end @@ -33,10 +107,20 @@ module PostgresDriverSpec class Foo; end class Bar; end + class Actor < ActiveRecord::Base; end + end + + def create_actor(id: 1, name: 'actor 1', **options) + actor = build_actor(**{ id: id, name: name, **options }) + actor.save! + actor + end + + def build_actor(id: 1, name: 'actor 1', **options) + PostgresDriverSpec::Actor.new(**{ id: id, name: name, **options }) end def build_db_class(clazz) - db_driver = Vorpal::Driver::Postgresql.new db_driver.build_db_class(clazz, 'example') end end diff --git a/spec/integration_spec_helper.rb b/spec/integration_spec_helper.rb index 8a4ab26..2f6f1f5 100644 --- a/spec/integration_spec_helper.rb +++ b/spec/integration_spec_helper.rb @@ -2,12 +2,14 @@ require 'pg' require 'helpers/db_helpers' require 'helpers/codecov_helper' +require 'timecop' begin require 'activerecord-import/base' rescue LoadError puts "Not using activerecord-import!" end +Timecop.safe_mode = true DbHelpers.ensure_database_exists DbHelpers.establish_connection diff --git a/spec/performance/vorpal/performance_spec.rb b/spec/performance/vorpal/performance_spec.rb index 7bc1525..bdfc019 100644 --- a/spec/performance/vorpal/performance_spec.rb +++ b/spec/performance/vorpal/performance_spec.rb @@ -200,6 +200,12 @@ def add_branch(branch_options) # load 1.042127 0.006379 1.048506 ( 1.156116) # destroy 0.693851 0.003333 0.697184 ( 0.829565) # + # Vorpal 1.0.4, Ruby 2.7.1, ActiveRecord 6.0.3, Dockerized Test DB, OSX + # user system total real + # create 0.530917 0.007090 0.538007 ( 0.657076) + # update 0.928303 0.007056 0.935359 ( 1.145808) + # load 0.938172 0.008781 0.946953 ( 1.063257) + # destroy 0.597991 0.002711 0.600702 ( 0.748637) it 'benchmarks all operations' do trees = build_trees(1000) Benchmark.bm(7) do |x| diff --git a/vorpal.gemspec b/vorpal.gemspec index 06a78f3..3bf2ddd 100644 --- a/vorpal.gemspec +++ b/vorpal.gemspec @@ -26,6 +26,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rspec", "~> 3.0" spec.add_development_dependency "virtus", "~> 1.0" spec.add_development_dependency "appraisal", "~> 2.2" + spec.add_development_dependency "timecop" spec.required_ruby_version = ">= 2.5.7" spec.add_development_dependency "activerecord" From d898ea89b3ee6f8f382102af2f08b69bce2ae78d Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 21:05:22 -0400 Subject: [PATCH 07/10] Update README --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c6a6dca..5b895e3 100644 --- a/README.md +++ b/README.md @@ -181,13 +181,11 @@ It also does not do some things that you might expect from other ORMs: 1. Only supports PostgreSQL. ## Future Enhancements -* Aggregate updated_at. -* Support for other DBMSs (no MySQL support until ids can be generated without inserting into a table!) -* Support for other ORMs. -* Value objects. -* Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions? TimeZone support?) -* More efficient updates (use fewer queries.) +* Support for UUID primary keys. * Nicer DSL for specifying attributes that have different names in the domain model than in the DB. +* Show how to implement POROs without using Virtus (it is unsupported and can be crazy slow) +* Aggregate updated_at. +* Better support for value objects. ## FAQ @@ -230,6 +228,10 @@ For example, use the [#query](https://rubydoc.info/github/nulogy/vorpal/master/V **A.** You can use [ActiveModel::Serialization](http://api.rubyonrails.org/classes/ActiveModel/Serialization.html) or [ActiveModel::Serializers](https://github.com/rails-api/active_model_serializers) but they are not heartily recommended. The former is too coupled to the model and the latter is too coupled to Rails controllers. Vorpal uses [SimpleSerializer](https://github.com/nulogy/simple_serializer) for this purpose. +**Q.** Are `updated_at` and `created_at` supported? + +**A.** Yes. If they exist on your database tables, they will behave exactly as if you were using vanilla ActiveRecord. + ## Contributing 1. Fork it ( https://github.com/nulogy/vorpal/fork ) From 244f595a3e961a59b16d700df8df3307c6c904b3 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 21:09:59 -0400 Subject: [PATCH 08/10] Add timecop to appraisals --- gemfiles/rails_5_1.gemfile.lock | 4 +++- gemfiles/rails_5_2.gemfile.lock | 4 +++- gemfiles/rails_6_0.gemfile.lock | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gemfiles/rails_5_1.gemfile.lock b/gemfiles/rails_5_1.gemfile.lock index 1c77a35..5129cc6 100644 --- a/gemfiles/rails_5_1.gemfile.lock +++ b/gemfiles/rails_5_1.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.3) + vorpal (1.0.4) activesupport equalizer simple_serializer (~> 1.0) @@ -69,6 +69,7 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) + timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -88,6 +89,7 @@ DEPENDENCIES pg (~> 0.18.0) rake (~> 13) rspec (~> 3.0) + timecop virtus (~> 1.0) vorpal! diff --git a/gemfiles/rails_5_2.gemfile.lock b/gemfiles/rails_5_2.gemfile.lock index e3939f3..e4b89a2 100644 --- a/gemfiles/rails_5_2.gemfile.lock +++ b/gemfiles/rails_5_2.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.3) + vorpal (1.0.4) activesupport equalizer simple_serializer (~> 1.0) @@ -69,6 +69,7 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) + timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -88,6 +89,7 @@ DEPENDENCIES pg (~> 0.18.0) rake (~> 13) rspec (~> 3.0) + timecop virtus (~> 1.0) vorpal! diff --git a/gemfiles/rails_6_0.gemfile.lock b/gemfiles/rails_6_0.gemfile.lock index 925e489..afde596 100644 --- a/gemfiles/rails_6_0.gemfile.lock +++ b/gemfiles/rails_6_0.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.3) + vorpal (1.0.4) activesupport equalizer simple_serializer (~> 1.0) @@ -68,6 +68,7 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) + timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -88,6 +89,7 @@ DEPENDENCIES pg rake (~> 13) rspec (~> 3.0) + timecop virtus (~> 1.0) vorpal! From c97968b4720c74178890415de373490093e372b2 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 21:46:23 -0400 Subject: [PATCH 09/10] Fix tests in Travis --- gemfiles/rails_5_1.gemfile.lock | 4 +--- gemfiles/rails_5_2.gemfile.lock | 2 +- gemfiles/rails_6_0.gemfile.lock | 4 +--- lib/vorpal/version.rb | 2 +- spec/integration/vorpal/driver/postgresql_spec.rb | 5 +++-- spec/integration_spec_helper.rb | 5 ++--- vorpal.gemspec | 1 - 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/gemfiles/rails_5_1.gemfile.lock b/gemfiles/rails_5_1.gemfile.lock index 5129cc6..ea8aef7 100644 --- a/gemfiles/rails_5_1.gemfile.lock +++ b/gemfiles/rails_5_1.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.4) + vorpal (1.1.0) activesupport equalizer simple_serializer (~> 1.0) @@ -69,7 +69,6 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) - timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -89,7 +88,6 @@ DEPENDENCIES pg (~> 0.18.0) rake (~> 13) rspec (~> 3.0) - timecop virtus (~> 1.0) vorpal! diff --git a/gemfiles/rails_5_2.gemfile.lock b/gemfiles/rails_5_2.gemfile.lock index e4b89a2..cdadaa8 100644 --- a/gemfiles/rails_5_2.gemfile.lock +++ b/gemfiles/rails_5_2.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.4) + vorpal (1.1.0) activesupport equalizer simple_serializer (~> 1.0) diff --git a/gemfiles/rails_6_0.gemfile.lock b/gemfiles/rails_6_0.gemfile.lock index afde596..2b580cc 100644 --- a/gemfiles/rails_6_0.gemfile.lock +++ b/gemfiles/rails_6_0.gemfile.lock @@ -1,7 +1,7 @@ PATH remote: .. specs: - vorpal (1.0.4) + vorpal (1.1.0) activesupport equalizer simple_serializer (~> 1.0) @@ -68,7 +68,6 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) - timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -89,7 +88,6 @@ DEPENDENCIES pg rake (~> 13) rspec (~> 3.0) - timecop virtus (~> 1.0) vorpal! diff --git a/lib/vorpal/version.rb b/lib/vorpal/version.rb index ced5e96..0964cce 100644 --- a/lib/vorpal/version.rb +++ b/lib/vorpal/version.rb @@ -1,3 +1,3 @@ module Vorpal - VERSION = "1.0.4" + VERSION = "1.1.0" end diff --git a/spec/integration/vorpal/driver/postgresql_spec.rb b/spec/integration/vorpal/driver/postgresql_spec.rb index 8b16ea0..28da0f2 100644 --- a/spec/integration/vorpal/driver/postgresql_spec.rb +++ b/spec/integration/vorpal/driver/postgresql_spec.rb @@ -73,7 +73,8 @@ it 'sets the updated_at column' do actor = create_actor - Timecop.freeze(Time.local(2000, 1, 1)) do + travel_to(Time.local(2000, 1, 1)) do + actor.touch db_driver.update(PostgresDriverSpec::Actor, [actor]) end @@ -83,7 +84,7 @@ it 'leaves the created_at column alone' do actor = create_actor - old_created_at = actor.created_at + old_created_at = actor.reload.created_at # reload because older versions of PG will truncate timestamps db_driver.update(PostgresDriverSpec::Actor, [actor]) diff --git a/spec/integration_spec_helper.rb b/spec/integration_spec_helper.rb index 2f6f1f5..ea61335 100644 --- a/spec/integration_spec_helper.rb +++ b/spec/integration_spec_helper.rb @@ -2,20 +2,19 @@ require 'pg' require 'helpers/db_helpers' require 'helpers/codecov_helper' -require 'timecop' +require 'active_support/testing/time_helpers' begin require 'activerecord-import/base' rescue LoadError puts "Not using activerecord-import!" end -Timecop.safe_mode = true - DbHelpers.ensure_database_exists DbHelpers.establish_connection RSpec.configure do |config| config.include DbHelpers + config.include ActiveSupport::Testing::TimeHelpers # implements `use_transactional_fixtures = true` config.before(:each) do diff --git a/vorpal.gemspec b/vorpal.gemspec index 3bf2ddd..06a78f3 100644 --- a/vorpal.gemspec +++ b/vorpal.gemspec @@ -26,7 +26,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rspec", "~> 3.0" spec.add_development_dependency "virtus", "~> 1.0" spec.add_development_dependency "appraisal", "~> 2.2" - spec.add_development_dependency "timecop" spec.required_ruby_version = ">= 2.5.7" spec.add_development_dependency "activerecord" From 9ae6a6db1b2450ec0e4410a34028dad02602e752 Mon Sep 17 00:00:00 2001 From: Sean Kirby Date: Fri, 2 Oct 2020 21:53:27 -0400 Subject: [PATCH 10/10] Removes timecop for real --- gemfiles/rails_5_2.gemfile.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/gemfiles/rails_5_2.gemfile.lock b/gemfiles/rails_5_2.gemfile.lock index cdadaa8..c67c32d 100644 --- a/gemfiles/rails_5_2.gemfile.lock +++ b/gemfiles/rails_5_2.gemfile.lock @@ -69,7 +69,6 @@ GEM simplecov-html (0.12.3) thor (1.0.1) thread_safe (0.3.6) - timecop (0.9.1) tzinfo (1.2.7) thread_safe (~> 0.1) virtus (1.0.5) @@ -89,7 +88,6 @@ DEPENDENCIES pg (~> 0.18.0) rake (~> 13) rspec (~> 3.0) - timecop virtus (~> 1.0) vorpal!