From 1e9d87573808a6e688c308cb0606436576342dec Mon Sep 17 00:00:00 2001 From: Krzysztof Wawer Date: Sun, 14 Jun 2015 11:57:05 +0200 Subject: [PATCH 1/4] Extract User class in tests to support dir --- spec/integration/commands/create_spec.rb | 10 ++-------- spec/integration/commands/update_spec.rb | 10 ++-------- spec/support/user.rb | 7 +++++++ 3 files changed, 11 insertions(+), 16 deletions(-) create mode 100644 spec/support/user.rb diff --git a/spec/integration/commands/create_spec.rb b/spec/integration/commands/create_spec.rb index 10a585d..ed3b023 100644 --- a/spec/integration/commands/create_spec.rb +++ b/spec/integration/commands/create_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' require 'virtus' +require_relative '../../support/user' + describe 'Commands / Create' do subject(:rom) { setup.finalize } @@ -17,14 +19,6 @@ setup.relation(:users) - class User - include Virtus.model - - attribute :id, Integer - attribute :name, String - attribute :email, String - end - setup.mappers do define(:users) do model User diff --git a/spec/integration/commands/update_spec.rb b/spec/integration/commands/update_spec.rb index 66e8264..dbf4f43 100644 --- a/spec/integration/commands/update_spec.rb +++ b/spec/integration/commands/update_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' require 'virtus' +require_relative '../../support/user' + describe 'Commands / Updates' do subject(:rom) { setup.finalize } @@ -28,14 +30,6 @@ def by_id(id) end end - class User - include Virtus.model - - attribute :id, Integer - attribute :name, String - attribute :email, String - end - setup.mappers do define(:users) do model User diff --git a/spec/support/user.rb b/spec/support/user.rb new file mode 100644 index 0000000..d5db616 --- /dev/null +++ b/spec/support/user.rb @@ -0,0 +1,7 @@ +class User + include Virtus.model + + attribute :id, Integer + attribute :name, String + attribute :email, String +end From dc1b402055922e61aadae5fbc3bbbeb5206a32cf Mon Sep 17 00:00:00 2001 From: Krzysztof Wawer Date: Sun, 14 Jun 2015 11:58:20 +0200 Subject: [PATCH 2/4] Remove old FIXME from tests --- spec/integration/commands/delete_spec.rb | 3 --- spec/integration/commands/update_spec.rb | 3 --- 2 files changed, 6 deletions(-) diff --git a/spec/integration/commands/delete_spec.rb b/spec/integration/commands/delete_spec.rb index 0aa53f5..4cac0a4 100644 --- a/spec/integration/commands/delete_spec.rb +++ b/spec/integration/commands/delete_spec.rb @@ -40,9 +40,6 @@ def by_id(id) expect(result.value) .to eql(user_id: 1, name: "Julie", email: "julie.andrews@example.com") - # FIXME: reload! should not be necessary - rom.relation(:users).relation.dataset.reload! - result = rom.relation(:users).to_a expect(result.count).to eql(2) end diff --git a/spec/integration/commands/update_spec.rb b/spec/integration/commands/update_spec.rb index dbf4f43..97adf95 100644 --- a/spec/integration/commands/update_spec.rb +++ b/spec/integration/commands/update_spec.rb @@ -49,9 +49,6 @@ def by_id(id) expect(result.value.to_a).to match_array(output_data) - # FIXME: reload! should not be necessary - rom.relation(:users).relation.dataset.reload! - result = rom.relation(:users).as(:entity).by_id(1).to_a.first expect(result.email).to eql('tester@example.com') end From b550fc08e7178dd1f11daf9e964fba1a9076d3b0 Mon Sep 17 00:00:00 2001 From: Krzysztof Wawer Date: Sun, 14 Jun 2015 12:04:49 +0200 Subject: [PATCH 3/4] Add possibility to generate fresh csv file --- lib/rom/csv/commands/create.rb | 23 ++++-- spec/integration/commands/create_spec.rb | 98 ++++++++++++++++-------- 2 files changed, 83 insertions(+), 38 deletions(-) diff --git a/lib/rom/csv/commands/create.rb b/lib/rom/csv/commands/create.rb index 743670d..308061e 100644 --- a/lib/rom/csv/commands/create.rb +++ b/lib/rom/csv/commands/create.rb @@ -17,20 +17,29 @@ def execute(tuples) end def insert(tuples) - tuples.each { |tuple| dataset << new_row(tuple) } + headers = headers_from_csv || headers_from_tuple(tuples.first) + tuples.each { |tuple| dataset << new_row(headers, tuple) } dataset.sync! end - def new_row(tuple) - ::CSV::Row.new(dataset.data.headers, ordered_data(tuple)) + def new_row(headers, tuple) + ::CSV::Row.new(headers, ordered_data(headers, tuple)) end - def ordered_data(tuple) - dataset.data.headers.map { |header| tuple[header] } + def ordered_data(headers, tuple) + headers.map { |header| tuple[header] } end - def dataset - relation.dataset + def dataset + relation.dataset + end + + def headers_from_csv + dataset.data.headers unless dataset.data.headers.empty? + end + + def headers_from_tuple(tuple) + tuple.keys end end end diff --git a/spec/integration/commands/create_spec.rb b/spec/integration/commands/create_spec.rb index ed3b023..e08d7a6 100644 --- a/spec/integration/commands/create_spec.rb +++ b/spec/integration/commands/create_spec.rb @@ -14,53 +14,89 @@ subject(:users) { rom.commands.users } - before do - FileUtils.copy(original_path, path) + context 'when csv file exists' do + before do + FileUtils.copy(original_path, path) - setup.relation(:users) + setup.relation(:users) - setup.mappers do - define(:users) do - model User - register_as :entity + setup.mappers do + define(:users) do + model User + register_as :entity + end end - end - setup.commands(:users) do - define(:create) do - result :one - end + setup.commands(:users) do + define(:create) do + result :one + end - define(:create_many, type: :create) do - result :many + define(:create_many, type: :create) do + result :many + end end end - end - it 'returns a single tuple when result is set to :one' do - result = users.try do - users.create.call(user_id: 4, name: 'John', email: 'john@doe.org') + it 'returns a single tuple when result is set to :one' do + result = users.try do + users.create.call(user_id: 4, name: 'John', email: 'john@doe.org') + end + expect(result.value).to eql(user_id: 4, name: 'John', email: 'john@doe.org') + + result = rom.relation(:users).as(:entity).to_a + expect(result.count).to eql(4) end - expect(result.value).to eql(user_id: 4, name: 'John', email: 'john@doe.org') - result = rom.relation(:users).as(:entity).to_a - expect(result.count).to eql(4) - end + it 'returns tuples when result is set to :many' do + result = users.try do + users.create_many.call([ + { user_id: 4, name: 'Jane', email: 'jane@doe.org' }, + { user_id: 5, name: 'Jack', email: 'jack@doe.org' } + ]) + end - it 'returns tuples when result is set to :many' do - result = users.try do - users.create_many.call([ + expect(result.value.to_a).to match_array([ { user_id: 4, name: 'Jane', email: 'jane@doe.org' }, { user_id: 5, name: 'Jack', email: 'jack@doe.org' } ]) + + result = rom.relation(:users).as(:entity).to_a + expect(result.count).to eql(5) end + end + + context "when csv file doesn't exists" do + before do + FileUtils.rm(path) if File.exists?(path) + FileUtils.touch(path) - expect(result.value.to_a).to match_array([ - { user_id: 4, name: 'Jane', email: 'jane@doe.org' }, - { user_id: 5, name: 'Jack', email: 'jack@doe.org' } - ]) + setup.relation(:users) - result = rom.relation(:users).as(:entity).to_a - expect(result.count).to eql(5) + setup.mappers do + define(:users) do + model User + register_as :entity + end + end + + setup.commands(:users) do + define(:create) do + result :one + end + end + end + + it 'returns tuples from new generated csv file' do + result = rom.relation(:users).as(:entity).to_a + expect(result.count).to eql(0) + + users.try do + users.create.call(user_id: 4, name: 'John', email: 'john@doe.org') + end + + result = rom.relation(:users).as(:entity).to_a + expect(result.count).to eql(1) + end end end From 5d4b2f96cf1a145a943c8219e3a8cc519f29e024 Mon Sep 17 00:00:00 2001 From: Krzysztof Wawer Date: Sun, 14 Jun 2015 12:24:03 +0200 Subject: [PATCH 4/4] Add more examples --- .gitignore | 1 + README.md | 2 - examples/addresses.csv | 5 +++ examples/create_csv_report.rb | 39 +++++++++++++++++++ examples/find_user.rb | 2 +- examples/join_datasets.rb | 72 +++++++++++++++++++++++++++++++++++ examples/users.csv | 2 +- 7 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 examples/addresses.csv create mode 100644 examples/create_csv_report.rb create mode 100644 examples/join_datasets.rb diff --git a/.gitignore b/.gitignore index 5dde784..33d8f31 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ *.a mkmf.log spec/fixtures/testing.csv +examples/report.csv diff --git a/README.md b/README.md index bf7867d..536fd86 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,6 @@ CSV support for [Ruby Object Mapper](https://github.com/rom-rb/rom) -**Note: rom-csv is read only at the moment.** - ## Installation Add this line to your application's Gemfile: diff --git a/examples/addresses.csv b/examples/addresses.csv new file mode 100644 index 0000000..de1a63c --- /dev/null +++ b/examples/addresses.csv @@ -0,0 +1,5 @@ +address_id,user_id,street +1,1,Cleveland Street +2,2,East Avenue +3,2,Lantern Lane +4,3,Lantern Street diff --git a/examples/create_csv_report.rb b/examples/create_csv_report.rb new file mode 100644 index 0000000..f562f00 --- /dev/null +++ b/examples/create_csv_report.rb @@ -0,0 +1,39 @@ +require 'bundler' +Bundler.setup + +require 'rom/csv' +require 'ostruct' + +csv_file = File.expand_path("./report.csv", File.dirname(__FILE__)) + +FileUtils.touch(csv_file) +setup = ROM.setup(:csv, csv_file) + +setup.relation(:users) + +class User < OpenStruct +end + +setup.mappers do + define(:users) do + register_as :entity + model User + end +end + +setup.commands(:users) do + define(:create) do + result :one + end +end + +rom = setup.finalize + +rom.commands.users.try do + rom.commands.users.create.call(id: 1, name: 'John', email: 'john@doe.org') +end + +data = rom.relation(:users).as(:entity).to_a +# => [#] + +data diff --git a/examples/find_user.rb b/examples/find_user.rb index ebb8f79..773f974 100644 --- a/examples/find_user.rb +++ b/examples/find_user.rb @@ -25,6 +25,6 @@ class User < OpenStruct rom = setup.finalize user = rom.relation(:users).as(:entity).by_name('Jane').one -# => # +# => # user or abort "user not found" diff --git a/examples/join_datasets.rb b/examples/join_datasets.rb new file mode 100644 index 0000000..c0a72aa --- /dev/null +++ b/examples/join_datasets.rb @@ -0,0 +1,72 @@ +require 'bundler' +Bundler.setup + +require 'rom/csv' +require 'ostruct' + +users_csv_file = File.expand_path("./users.csv", File.dirname(__FILE__)) +addresses_csv_file = File.expand_path("./addresses.csv", File.dirname(__FILE__)) + +setup = ROM.setup( + users: [:csv, users_csv_file], + addresses: [:csv, addresses_csv_file] +) + +setup.relation(:users) do + gateway :users + + def by_name(name) + restrict(name: name) + end + + def only_name + project(:name) + end + + def ordered + order(:name, :email) + end + + def with_addresses + join(addresses) + end +end + +setup.relation(:addresses) do + gateway :addresses +end + +class User < OpenStruct +end + +class UserWithAddress < OpenStruct +end + +class Address < OpenStruct +end + +setup.mappers do + define(:users) do + model User + register_as :entity + end + + define(:users_with_address, parent: :users) do + model UserWithAddress + register_as :entity_with_address + + group :addresses do + model Address + + attribute :address_id + attribute :street + end + end +end + +rom = setup.finalize +user = rom.relation(:users).as(:entity_with_address).with_addresses.first +# => #]> + +user or abort "user not found" diff --git a/examples/users.csv b/examples/users.csv index fe0895c..2fc2d2a 100644 --- a/examples/users.csv +++ b/examples/users.csv @@ -1,3 +1,3 @@ -id,name,email +user_id,name,email 1,Julie,julie.andrews@example.com 2,Jane,jane@doe.org