Commit b820d32
Changed files (9)
lib
spec
integration
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
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
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
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
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
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)
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
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
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