From efd52cd43f59850602459f085f5b1171d0312019 Mon Sep 17 00:00:00 2001 From: Yuri Artemev Date: Sun, 4 Oct 2015 14:24:27 +0300 Subject: [PATCH 1/5] enhance specs --- spec/integration/commands/create_spec.rb | 4 ++-- spec/integration/commands/delete_spec.rb | 4 ++-- spec/integration/commands/update_spec.rb | 4 ++-- spec/integration/repository_spec.rb | 7 ++----- spec/spec_helper.rb | 7 ++++--- spec/support/prepare_db.rb | 26 ++++++++---------------- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/spec/integration/commands/create_spec.rb b/spec/integration/commands/create_spec.rb index d5a13f0..8f0169a 100644 --- a/spec/integration/commands/create_spec.rb +++ b/spec/integration/commands/create_spec.rb @@ -10,7 +10,7 @@ subject(:users) { rom.commands.users } before do - create_table('test_db', 'users') + clean_table('test_db', 'users') setup.relation(:users) @@ -41,7 +41,7 @@ class User end after do - drop_table('test_db', 'users') + clean_table('test_db', 'users') end it 'returns a single tuple when result is set to :one' do diff --git a/spec/integration/commands/delete_spec.rb b/spec/integration/commands/delete_spec.rb index 4004652..800de7c 100644 --- a/spec/integration/commands/delete_spec.rb +++ b/spec/integration/commands/delete_spec.rb @@ -10,7 +10,7 @@ let(:gateway) { rom.gateways[:default] } before do - create_table('test_db', 'users') + clean_table('test_db', 'users') setup.relation(:users) do def by_id(id) @@ -34,7 +34,7 @@ def by_id(id) end after do - drop_table('test_db', 'users') + clean_table('test_db', 'users') end it 'deletes all tuples in a restricted relation' do diff --git a/spec/integration/commands/update_spec.rb b/spec/integration/commands/update_spec.rb index 55ac40c..7e8efd1 100644 --- a/spec/integration/commands/update_spec.rb +++ b/spec/integration/commands/update_spec.rb @@ -11,7 +11,7 @@ let(:gateway) { rom.gateways[:default] } before do - create_table('test_db', 'users') + clean_table('test_db', 'users') setup.relation(:users) do def by_id(id) @@ -48,7 +48,7 @@ class User end after do - drop_table('test_db', 'users') + clean_table('test_db', 'users') end it 'updates everything when there is no original tuple' do diff --git a/spec/integration/repository_spec.rb b/spec/integration/repository_spec.rb index 8d19766..2c9da73 100644 --- a/spec/integration/repository_spec.rb +++ b/spec/integration/repository_spec.rb @@ -1,16 +1,13 @@ require 'spec_helper' - require 'virtus' describe 'RethinkDB gateway' do - include PrepareDB - let(:gateway) { rom.gateways[:default] } let(:setup) { ROM.setup(:rethinkdb, db_options.merge(db: 'test_db')) } subject(:rom) { setup.finalize } before do - create_table('test_db', 'users') + clean_table('test_db', 'users') setup.relation(:users) do def with_name(name) @@ -63,7 +60,7 @@ class User end after do - drop_table('test_db', 'users') + clean_table('test_db', 'users') end describe 'env#relation' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 500cdcb..c26fc8e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,13 +13,14 @@ require_relative 'support/prepare_db' RSpec.configure do |config| - config.include PrepareDB + include PrepareDB - config.before(:all) do + config.before(:suite) do create_database('test_db') + create_table('test_db', 'users') end - config.after(:all) do + config.after(:suite) do drop_database('test_db') end end diff --git a/spec/support/prepare_db.rb b/spec/support/prepare_db.rb index 4df5e41..debd339 100644 --- a/spec/support/prepare_db.rb +++ b/spec/support/prepare_db.rb @@ -1,33 +1,25 @@ module PrepareDB def create_database(database) - drop_database(database) - rql.db_create(database).run(connection) end def drop_database(database) - database_exist?(database) && rql.db_drop(database).run(connection) - end - - def database_exist?(database) - database_list.include?(database.to_s) - end - - def database_list - rql.db_list.run(connection) + rql.db_drop(database).run(connection) end def create_table(database, table) - drop_table(database, table) - rql.db(database).table_create(table).run(connection) - end - - def drop_table(database, table) if table_exist?(database, table) - rql.db(database).table_drop(table).run(connection) + clean_table(database, table) + else + rql.db(database).table_create(table).run(connection) end end + def clean_table(database, table) + rql.db(database).table(table).delete.run(connection) + rescue RethinkDB::RqlOpFailedError + end + def table_exist?(database, table) table_list(database).include?(table.to_s) end From a0bc6b15d740eaf9befa0666e465422c7bbb8ff2 Mon Sep 17 00:00:00 2001 From: Yuri Artemev Date: Sun, 4 Oct 2015 14:29:43 +0300 Subject: [PATCH 2/5] enhance adapter --- lib/rom/rethinkdb/commands/create.rb | 4 ++-- lib/rom/rethinkdb/dataset.rb | 19 +++++++++++-------- lib/rom/rethinkdb/gateway.rb | 6 +----- lib/rom/rethinkdb/relation.rb | 14 +++----------- spec/integration/repository_spec.rb | 23 +++++++++++++++++++++++ 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/lib/rom/rethinkdb/commands/create.rb b/lib/rom/rethinkdb/commands/create.rb index 3cbedf1..8edd12c 100644 --- a/lib/rom/rethinkdb/commands/create.rb +++ b/lib/rom/rethinkdb/commands/create.rb @@ -8,7 +8,7 @@ class Create < ROM::Commands::Create adapter :rethinkdb def execute(tuples) - insert_tuples = [tuples].flatten.map do |tuple| + insert_tuples = [tuples].flatten.map do |tuple| attributes = input[tuple] validator.call(attributes) attributes.to_h @@ -19,7 +19,7 @@ def execute(tuples) def insert(tuples) pks = dataset.scope.insert(tuples) - .run(dataset.connection)["generated_keys"] + .run(dataset.connection)["generated_keys"] dataset.filter { |user| relation.rql.expr(pks).contains(user["id"]) } .to_a diff --git a/lib/rom/rethinkdb/dataset.rb b/lib/rom/rethinkdb/dataset.rb index ecb91ea..647316f 100644 --- a/lib/rom/rethinkdb/dataset.rb +++ b/lib/rom/rethinkdb/dataset.rb @@ -13,22 +13,25 @@ def initialize(scope, rql, connection) end def to_a - scope.run(connection) + wrap_array(scope.run(connection)) end def each(&block) to_a.each(&block) end - def count - scope.count.run(connection) + def method_missing(command, *args, &block) + self.class.new(scope.public_send(command, *args, &block), rql, connection) end - [:filter, :pluck, :order_by].each do |method_name| - define_method(method_name) do |*args, &block| - self.class.new(scope.send(method_name, *args, &block), rql, - connection) - end + private + + def wrap_array(object) + return [object] if object.is_a?(Hash) + return object if object.is_a?(Array) + return [] if object.nil? + + object.to_a end end end diff --git a/lib/rom/rethinkdb/gateway.rb b/lib/rom/rethinkdb/gateway.rb index 87d756e..79d1983 100644 --- a/lib/rom/rethinkdb/gateway.rb +++ b/lib/rom/rethinkdb/gateway.rb @@ -31,7 +31,6 @@ def initialize(options) # # @api public def dataset(name) - rql.db(options[:db]).table(name.to_s).run(connection) datasets[name] = Dataset.new(rql.table(name.to_s), rql, connection) end @@ -52,10 +51,7 @@ def [](name) # # @api public def dataset?(name) - rql.db(options[:db]).table(name.to_s).run(connection) - true - rescue ::RethinkDB::RqlRuntimeError - false + rql.db(options[:db]).table_list.run(connection).include?(name.to_s) end # Disconnect from database diff --git a/lib/rom/rethinkdb/relation.rb b/lib/rom/rethinkdb/relation.rb index 293559e..82e3149 100644 --- a/lib/rom/rethinkdb/relation.rb +++ b/lib/rom/rethinkdb/relation.rb @@ -15,19 +15,11 @@ def rql end def count - dataset.count + dataset.to_a.count end - def filter(*args, &block) - __new__(dataset.__send__(__method__, *args, &block)) - end - - def pluck(*args, &block) - __new__(dataset.__send__(__method__, *args, &block)) - end - - def order_by(*args, &block) - __new__(dataset.__send__(__method__, *args, &block)) + def method_missing(command, *args, &block) + __new__(dataset.public_send(command, *args, &block)) end end end diff --git a/spec/integration/repository_spec.rb b/spec/integration/repository_spec.rb index 2c9da73..2fe2688 100644 --- a/spec/integration/repository_spec.rb +++ b/spec/integration/repository_spec.rb @@ -10,6 +10,10 @@ clean_table('test_db', 'users') setup.relation(:users) do + def by_id(id) + get(id) + end + def with_name(name) filter(name: name) end @@ -29,6 +33,10 @@ def by_name def names_on_street(street) filter(street: street).order_by('name').pluck(:name) end + + def undef + undef_method(with: 'args') + end end class User @@ -64,6 +72,21 @@ class User end describe 'env#relation' do + it 'raise error on undefined method' do + message = %|undefined method `undef_method' for r.table("users"):RethinkDB::RQL| + + expect { + rom.relation(:users).undef.to_a + }.to raise_error(NoMethodError, message) + end + + it 'return data by primary key' do + pk = rom.relation(:users).to_a.map {|o| o.fetch('id') }.first + user = rom.relation(:users).as(:entity).by_id(pk).one + + expect(user.id).to eq(pk) + end + it 'returns mapped object' do jane = rom.relation(:users).as(:entity).with_name('Jane').to_a.first From b5ef46d63e7213bcfc294424dcb327e46ea4a805 Mon Sep 17 00:00:00 2001 From: Yuri Artemev Date: Sun, 4 Oct 2015 14:36:22 +0300 Subject: [PATCH 3/5] fix rubocop warnings --- .rubocop.yml | 6 +++--- lib/rom/rethinkdb/commands/create.rb | 14 ++++++++++---- lib/rom/rethinkdb/dataset.rb | 5 +++-- spec/integration/repository_spec.rb | 10 +++++----- spec/support/prepare_db.rb | 1 + 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 396e150..37aaa1d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,7 @@ # Generated by `rubocop --auto-gen-config` inherit_from: .rubocop_todo.yml -# It’s quite readable when we know what we are doing +# It's quite readable when we know what we are doing Lint/AssignmentInCondition: Enabled: false @@ -10,7 +10,7 @@ Lint/HandleExceptions: Exclude: - Rakefile -# The enforced style doesn’t match Vim’s defaults +# The enforced style doesn't match Vim's defaults Style/AlignParameters: Enabled: false @@ -42,7 +42,7 @@ Style/MultilineBlockChain: Style/RegexpLiteral: MaxSlashes: 0 -# Don’t introduce semantic fail/raise distinction +# Don't introduce semantic fail/raise distinction Style/SignalException: EnforcedStyle: only_raise diff --git a/lib/rom/rethinkdb/commands/create.rb b/lib/rom/rethinkdb/commands/create.rb index 8edd12c..5c2ff2a 100644 --- a/lib/rom/rethinkdb/commands/create.rb +++ b/lib/rom/rethinkdb/commands/create.rb @@ -18,11 +18,17 @@ def execute(tuples) end def insert(tuples) - pks = dataset.scope.insert(tuples) - .run(dataset.connection)["generated_keys"] + pks = get_pks(tuples) - dataset.filter { |user| relation.rql.expr(pks).contains(user["id"]) } - .to_a + dataset.filter do |user| + relation.rql.expr(pks).contains(user['id']) + end.to_a + end + + def get_pks(tuples) + dataset.scope.insert(tuples) + .run(dataset.connection) + .fetch('generated_keys') end def dataset diff --git a/lib/rom/rethinkdb/dataset.rb b/lib/rom/rethinkdb/dataset.rb index 647316f..4727459 100644 --- a/lib/rom/rethinkdb/dataset.rb +++ b/lib/rom/rethinkdb/dataset.rb @@ -21,10 +21,11 @@ def each(&block) end def method_missing(command, *args, &block) - self.class.new(scope.public_send(command, *args, &block), rql, connection) + self.class.new(scope.public_send(command, *args, &block), + rql, connection) end - private + private def wrap_array(object) return [object] if object.is_a?(Hash) diff --git a/spec/integration/repository_spec.rb b/spec/integration/repository_spec.rb index 2fe2688..b38a0da 100644 --- a/spec/integration/repository_spec.rb +++ b/spec/integration/repository_spec.rb @@ -34,8 +34,8 @@ def names_on_street(street) filter(street: street).order_by('name').pluck(:name) end - def undef - undef_method(with: 'args') + def undefined + undfn(with: 'args') end end @@ -73,15 +73,15 @@ class User describe 'env#relation' do it 'raise error on undefined method' do - message = %|undefined method `undef_method' for r.table("users"):RethinkDB::RQL| + message = %|undefined method `undfn' for r.table("users"):RethinkDB::RQL| expect { - rom.relation(:users).undef.to_a + rom.relation(:users).undefined.to_a }.to raise_error(NoMethodError, message) end it 'return data by primary key' do - pk = rom.relation(:users).to_a.map {|o| o.fetch('id') }.first + pk = rom.relation(:users).to_a.map { |o| o.fetch('id') }.first user = rom.relation(:users).as(:entity).by_id(pk).one expect(user.id).to eq(pk) diff --git a/spec/support/prepare_db.rb b/spec/support/prepare_db.rb index debd339..5b9ce95 100644 --- a/spec/support/prepare_db.rb +++ b/spec/support/prepare_db.rb @@ -18,6 +18,7 @@ def create_table(database, table) def clean_table(database, table) rql.db(database).table(table).delete.run(connection) rescue RethinkDB::RqlOpFailedError + nil end def table_exist?(database, table) From 394e7f633c48fd18c8ae017ff968d07c84f14cd5 Mon Sep 17 00:00:00 2001 From: Yuri Artemev Date: Sun, 4 Oct 2015 14:47:19 +0300 Subject: [PATCH 4/5] refactor create command --- lib/rom/rethinkdb/commands/create.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/rom/rethinkdb/commands/create.rb b/lib/rom/rethinkdb/commands/create.rb index 5c2ff2a..6d52d07 100644 --- a/lib/rom/rethinkdb/commands/create.rb +++ b/lib/rom/rethinkdb/commands/create.rb @@ -14,23 +14,22 @@ def execute(tuples) attributes.to_h end - insert(insert_tuples) + pks = insert(insert_tuples) + get_by_pks(pks) end def insert(tuples) - pks = get_pks(tuples) + dataset.scope.insert(tuples) + .run(dataset.connection) + .fetch('generated_keys') + end + def get_by_pks(pks) dataset.filter do |user| relation.rql.expr(pks).contains(user['id']) end.to_a end - def get_pks(tuples) - dataset.scope.insert(tuples) - .run(dataset.connection) - .fetch('generated_keys') - end - def dataset relation.dataset end From 4364def791ba59c0f4a8fb56b8f3c84f4475420d Mon Sep 17 00:00:00 2001 From: Yuri Artemev Date: Mon, 5 Oct 2015 03:56:33 +0300 Subject: [PATCH 5/5] don't check exception message of undefined method in relation --- spec/integration/repository_spec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/integration/repository_spec.rb b/spec/integration/repository_spec.rb index b38a0da..3c5e109 100644 --- a/spec/integration/repository_spec.rb +++ b/spec/integration/repository_spec.rb @@ -73,11 +73,9 @@ class User describe 'env#relation' do it 'raise error on undefined method' do - message = %|undefined method `undfn' for r.table("users"):RethinkDB::RQL| - expect { rom.relation(:users).undefined.to_a - }.to raise_error(NoMethodError, message) + }.to raise_error(NoMethodError) end it 'return data by primary key' do