diff --git a/acceptance/cases/models/insert_all_test.rb b/acceptance/cases/models/insert_all_test.rb index f13e3c38..b149f17e 100644 --- a/acceptance/cases/models/insert_all_test.rb +++ b/acceptance/cases/models/insert_all_test.rb @@ -33,6 +33,12 @@ def test_insert_all assert_raise(NotImplementedError) { Author.insert_all(values) } end + def test_insert + value = { id: Author.next_sequence_value, name: "Alice" } + + assert_raise(NotImplementedError) { Author.insert(value) } + end + def test_insert_all! values = [ { id: Author.next_sequence_value, name: "Alice" }, @@ -85,6 +91,22 @@ def test_insert_all_with_buffered_mutation_transaction assert_equal "Carol", authors[2].name end + def test_upsert + Author.create id: 1, name: "David" + authors = Author.all.order(:name) + assert_equal 1, authors.length + assert_equal "David", authors[0].name + + value = { id: 1, name: "Alice" } + + Author.upsert(value) + + authors = Author.all.order(:name) + + assert_equal 1, authors.length + assert_equal "Alice", authors[0].name + end + def test_upsert_all Author.create id: 1, name: "David" authors = Author.all.order(:name) diff --git a/lib/activerecord_spanner_adapter/base.rb b/lib/activerecord_spanner_adapter/base.rb index 0062f6ac..c397f684 100644 --- a/lib/activerecord_spanner_adapter/base.rb +++ b/lib/activerecord_spanner_adapter/base.rb @@ -67,11 +67,11 @@ def self._upsert_record values _buffer_record values, :insert_or_update end - def self.insert_all _attributes, _returning: nil, _unique_by: nil - raise NotImplementedError, "Cloud Spanner does not support skip_duplicates." + def self.insert_all _attributes, **_kwargs + raise NotImplementedError, "Cloud Spanner does not support skip_duplicates. Use insert! or upsert instead." end - def self.insert_all! attributes, returning: nil + def self.insert_all! attributes, **_kwargs return super unless spanner_adapter? return super if active_transaction? && !buffered_mutations? @@ -90,7 +90,7 @@ def self.insert_all! attributes, returning: nil end end - def self.upsert_all attributes, returning: nil, unique_by: nil + def self.upsert_all attributes, **_kwargs return super unless spanner_adapter? if active_transaction? && !buffered_mutations? raise NotImplementedError, "Cloud Spanner does not support upsert using DML. " \ diff --git a/test/activerecord_spanner_mock_server/spanner_active_record_with_mock_server_test.rb b/test/activerecord_spanner_mock_server/spanner_active_record_with_mock_server_test.rb index b1fd33ed..d27d6512 100644 --- a/test/activerecord_spanner_mock_server/spanner_active_record_with_mock_server_test.rb +++ b/test/activerecord_spanner_mock_server/spanner_active_record_with_mock_server_test.rb @@ -9,8 +9,64 @@ require_relative "./base_spanner_mock_server_test" module MockServerTests + CommitRequest = Google::Cloud::Spanner::V1::CommitRequest + class SpannerActiveRecordMockServerTest < BaseSpannerMockServerTest + def test_insert + singer = { first_name: "Alice", last_name: "Ecila" } + + assert_raises(NotImplementedError) { Singer.insert(singer) } + end + + def test_insert! + singer = { first_name: "Alice", last_name: "Ecila" } + singer = Singer.insert! singer + + commit_requests = @mock.requests.select { |req| req.is_a?(CommitRequest) } + assert_equal 1, commit_requests.length + mutations = commit_requests[0].mutations + assert_equal 1, mutations.length + mutation = mutations[0] + assert_equal :insert, mutation.operation + assert_equal "singers", mutation.insert.table + + assert_equal 1, mutation.insert.values.length + assert_equal 3, mutation.insert.values[0].length + assert_equal "Alice", mutation.insert.values[0][0] + assert_equal "Ecila", mutation.insert.values[0][1] + assert_equal singer[0]["id"], mutation.insert.values[0][2].to_i + + assert_equal 3, mutation.insert.columns.length + assert_equal "first_name", mutation.insert.columns[0] + assert_equal "last_name", mutation.insert.columns[1] + assert_equal "id", mutation.insert.columns[2] + end + + def test_upsert + singer = { first_name: "Alice", last_name: "Ecila" } + singer = Singer.upsert singer + + commit_requests = @mock.requests.select { |req| req.is_a?(CommitRequest) } + assert_equal 1, commit_requests.length + mutations = commit_requests[0].mutations + assert_equal 1, mutations.length + mutation = mutations[0] + assert_equal :insert_or_update, mutation.operation + assert_equal "singers", mutation.insert_or_update.table + + assert_equal 1, mutation.insert_or_update.values.length + assert_equal 3, mutation.insert_or_update.values[0].length + assert_equal "Alice", mutation.insert_or_update.values[0][0] + assert_equal "Ecila", mutation.insert_or_update.values[0][1] + assert_equal singer[0]["id"], mutation.insert_or_update.values[0][2].to_i + + assert_equal 3, mutation.insert_or_update.columns.length + assert_equal "first_name", mutation.insert_or_update.columns[0] + assert_equal "last_name", mutation.insert_or_update.columns[1] + assert_equal "id", mutation.insert_or_update.columns[2] + end + def test_selects_all_singers_without_transaction sql = "SELECT `singers`.* FROM `singers`" @mock.put_statement_result sql, MockServerTests::create_random_singers_result(4)