diff options
| author | mo khan <mo@mokhan.ca> | 2014-07-13 09:31:41 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2014-07-13 09:31:41 -0600 |
| commit | b820d323588765ed6b7f5022d1a7551cf304f51b (patch) | |
| tree | 6aac3213d4c3ecba10b783d82a0f5ff685776c06 | |
| parent | 9d11dbbb3053811be6fd54407e08b5119c9756b3 (diff) | |
move classes to separate files and startto build identity map.
| -rw-r--r-- | humble.gemspec | 1 | ||||
| -rw-r--r-- | lib/humble.rb | 2 | ||||
| -rw-r--r-- | lib/humble/column.rb | 3 | ||||
| -rw-r--r-- | lib/humble/default_mapper.rb | 16 | ||||
| -rw-r--r-- | lib/humble/identity_map.rb | 14 | ||||
| -rw-r--r-- | lib/humble/mapping_configuration.rb | 27 | ||||
| -rw-r--r-- | lib/humble/result_set.rb | 16 | ||||
| -rw-r--r-- | lib/humble/session.rb | 10 | ||||
| -rw-r--r-- | spec/integration/select_spec.rb | 10 |
9 files changed, 62 insertions, 37 deletions
diff --git a/humble.gemspec b/humble.gemspec index e01addb..402efe6 100644 --- a/humble.gemspec +++ b/humble.gemspec @@ -23,4 +23,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake" spec.add_development_dependency 'rspec' spec.add_development_dependency 'sqlite3' + spec.add_development_dependency 'byebug' end diff --git a/lib/humble.rb b/lib/humble.rb index eac8f9f..f4816d5 100644 --- a/lib/humble.rb +++ b/lib/humble.rb @@ -9,6 +9,8 @@ require "humble/mapping_configuration" require "humble/mapping_configuration_builder" require "humble/database_table" require "humble/column" +require "humble/default_mapper" +require "humble/identity_map" module Humble diff --git a/lib/humble/column.rb b/lib/humble/column.rb index 66ab233..243b17a 100644 --- a/lib/humble/column.rb +++ b/lib/humble/column.rb @@ -75,7 +75,8 @@ module Humble end def apply(row, entity, session) - items = session.find_all(@type) + puts "#{@attribute} #{@type} #{row} #{entity}" + items = session.find_all(@type).to_a entity.public_send("#{@attribute}=", items) end diff --git a/lib/humble/default_mapper.rb b/lib/humble/default_mapper.rb new file mode 100644 index 0000000..d92f68a --- /dev/null +++ b/lib/humble/default_mapper.rb @@ -0,0 +1,16 @@ +class DefaultMapper + attr_reader :session, :table + + def initialize(table, session) + @table = table + @session = session + end + + def map_from(row) + table.type.new.tap do |entity| + table.each do |column| + column.apply(row, entity, session) + end + end + end +end diff --git a/lib/humble/identity_map.rb b/lib/humble/identity_map.rb new file mode 100644 index 0000000..b19db43 --- /dev/null +++ b/lib/humble/identity_map.rb @@ -0,0 +1,14 @@ +class IdentityMap + def initialize(items = {}) + @items = items + end + + def fetch(key, &block) + if @items.key?(key) + @items[key] + else + @items[key] = block.call + @items[key] + end + end +end diff --git a/lib/humble/mapping_configuration.rb b/lib/humble/mapping_configuration.rb index f70c97b..ce5c15d 100644 --- a/lib/humble/mapping_configuration.rb +++ b/lib/humble/mapping_configuration.rb @@ -1,14 +1,12 @@ module Humble class MappingConfiguration + attr_reader :table + def initialize(table, configuration) @table = table @configuration = configuration end - def find_all_using(session) - ResultSet.new(session.create_connection[@table.name], mapper_for(session)) - end - def save_using(session, entity) connection = session.create_connection[@table.name] if primary_key.has_default_value?(entity) @@ -29,31 +27,10 @@ module Humble private - def mapper_for(session) - DefaultMapper.new(@table, session) - end - def primary_key @primary_key ||= @table.find do |column| column.primary_key? end end - - class DefaultMapper - attr_reader :session, :table - - def initialize(table, session) - @table = table - @session = session - end - - def map_from(row) - entity = table.type.new - table.each do |column| - column.apply(row, entity, session) - end - entity - end - end end end diff --git a/lib/humble/result_set.rb b/lib/humble/result_set.rb index 0a0d4ee..61e41fb 100644 --- a/lib/humble/result_set.rb +++ b/lib/humble/result_set.rb @@ -8,19 +8,27 @@ module Humble end def each(&block) - @rows.each do |row| - block.call(@mapper.map_from(row)) + items.each do |item| + block.call(item) end end def include?(item) - self.find do |x| + find do |x| x == item end end def inspect - "[#{self.map { |x| x.inspect }.join(", ")}]" + "[#{map { |x| x.inspect }.join(", ")}]" + end + + private + + def items + @items ||= @rows.map do |row| + @mapper.map_from(row) + end.to_a end end end diff --git a/lib/humble/session.rb b/lib/humble/session.rb index 936aa39..6be422a 100644 --- a/lib/humble/session.rb +++ b/lib/humble/session.rb @@ -3,6 +3,7 @@ module Humble def initialize(session_factory, configuration) @session_factory = session_factory @configuration = configuration + @identity_map = IdentityMap.new end def begin_transaction(&block) @@ -16,13 +17,16 @@ module Humble end def find(clazz, id) - find_all(clazz).find do |x| - x.id == id + @identity_map.fetch("#{clazz.name}-#{id}") do + find_all(clazz).find do |x| + x.id == id + end end end def find_all(clazz) - mapping_for(clazz).find_all_using(self) + table = mapping_for(clazz).table + ResultSet.new(create_connection[table.name], DefaultMapper.new(table, self)) end def delete(entity) diff --git a/spec/integration/select_spec.rb b/spec/integration/select_spec.rb index 058fb84..b06ad27 100644 --- a/spec/integration/select_spec.rb +++ b/spec/integration/select_spec.rb @@ -31,13 +31,11 @@ describe "select items" do context "when fetching a single item" do let!(:studio_id) { connection[:studios].insert(name: 'universal') } let!(:movie_id) { connection[:movies].insert(name: 'blood in, blood out', studio_id: studio_id) } + let!(:review_id) { connection[:reviews].insert(movie_id: movie_id, description: description) } + let!(:other_review_id) { connection[:reviews].insert(movie_id: movie_id + 1, description: 'blah blah') } let(:result) { session.find(Movie, movie_id) } let(:description) { 'wow... that snail is fast.' } - before :each do - connection[:reviews].insert(movie_id: movie_id, description: description) - end - it "loads the proper type" do expect(result).to be_instance_of(Movie) end @@ -60,5 +58,9 @@ describe "select items" do expect(result.reviews.first.description).to eql(description) expect(result.reviews.first.description).to eql(description) end + + it "does not load items associated with another parent record" do + expect(result.reviews.find { |x| x.id == other_review_id }).to be_nil + end end end |
