datamapper 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. data/CHANGELOG +65 -0
  2. data/README +193 -1
  3. data/do_performance.rb +153 -0
  4. data/environment.rb +45 -0
  5. data/example.rb +119 -22
  6. data/lib/data_mapper.rb +36 -16
  7. data/lib/data_mapper/adapters/abstract_adapter.rb +8 -0
  8. data/lib/data_mapper/adapters/data_object_adapter.rb +360 -0
  9. data/lib/data_mapper/adapters/mysql_adapter.rb +30 -179
  10. data/lib/data_mapper/adapters/postgresql_adapter.rb +90 -199
  11. data/lib/data_mapper/adapters/sql/coersion.rb +32 -3
  12. data/lib/data_mapper/adapters/sql/commands/conditions.rb +97 -128
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +234 -231
  14. data/lib/data_mapper/adapters/sql/commands/loader.rb +99 -0
  15. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +30 -0
  16. data/lib/data_mapper/adapters/sql/mappings/column.rb +68 -6
  17. data/lib/data_mapper/adapters/sql/mappings/schema.rb +6 -3
  18. data/lib/data_mapper/adapters/sql/mappings/table.rb +71 -42
  19. data/lib/data_mapper/adapters/sql/quoting.rb +8 -2
  20. data/lib/data_mapper/adapters/sqlite3_adapter.rb +32 -201
  21. data/lib/data_mapper/associations.rb +21 -7
  22. data/lib/data_mapper/associations/belongs_to_association.rb +96 -80
  23. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +158 -67
  24. data/lib/data_mapper/associations/has_many_association.rb +96 -78
  25. data/lib/data_mapper/associations/has_n_association.rb +64 -0
  26. data/lib/data_mapper/associations/has_one_association.rb +49 -79
  27. data/lib/data_mapper/associations/reference.rb +47 -0
  28. data/lib/data_mapper/base.rb +216 -50
  29. data/lib/data_mapper/callbacks.rb +71 -24
  30. data/lib/data_mapper/{session.rb → context.rb} +20 -8
  31. data/lib/data_mapper/database.rb +176 -45
  32. data/lib/data_mapper/embedded_value.rb +65 -0
  33. data/lib/data_mapper/identity_map.rb +12 -4
  34. data/lib/data_mapper/support/active_record_impersonation.rb +12 -8
  35. data/lib/data_mapper/support/enumerable.rb +8 -0
  36. data/lib/data_mapper/support/serialization.rb +13 -0
  37. data/lib/data_mapper/support/string.rb +1 -12
  38. data/lib/data_mapper/support/symbol.rb +3 -0
  39. data/lib/data_mapper/validations/unique_validator.rb +1 -2
  40. data/lib/data_mapper/validations/validation_helper.rb +18 -1
  41. data/performance.rb +109 -34
  42. data/plugins/can_has_sphinx/LICENSE +23 -0
  43. data/plugins/can_has_sphinx/README +4 -0
  44. data/plugins/can_has_sphinx/REVISION +1 -0
  45. data/plugins/can_has_sphinx/Rakefile +22 -0
  46. data/plugins/can_has_sphinx/init.rb +1 -0
  47. data/plugins/can_has_sphinx/install.rb +1 -0
  48. data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +123 -0
  49. data/plugins/can_has_sphinx/lib/sphinx.rb +460 -0
  50. data/plugins/can_has_sphinx/scripts/sphinx.sh +47 -0
  51. data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +41 -0
  52. data/plugins/dataobjects/REVISION +1 -0
  53. data/plugins/dataobjects/Rakefile +7 -0
  54. data/plugins/dataobjects/do.rb +246 -0
  55. data/plugins/dataobjects/do_mysql.rb +179 -0
  56. data/plugins/dataobjects/do_postgres.rb +181 -0
  57. data/plugins/dataobjects/do_sqlite3.rb +153 -0
  58. data/plugins/dataobjects/spec/do_spec.rb +150 -0
  59. data/plugins/dataobjects/spec/spec_helper.rb +81 -0
  60. data/plugins/dataobjects/swig_mysql/do_mysql.bundle +0 -0
  61. data/plugins/dataobjects/swig_mysql/extconf.rb +33 -0
  62. data/plugins/dataobjects/swig_mysql/mysql_c.c +18800 -0
  63. data/plugins/dataobjects/swig_mysql/mysql_c.i +8 -0
  64. data/plugins/dataobjects/swig_mysql/mysql_supp.i +46 -0
  65. data/plugins/dataobjects/swig_postgres/Makefile +146 -0
  66. data/plugins/dataobjects/swig_postgres/extconf.rb +29 -0
  67. data/plugins/dataobjects/swig_postgres/postgres_c.bundle +0 -0
  68. data/plugins/dataobjects/swig_postgres/postgres_c.c +8185 -0
  69. data/plugins/dataobjects/swig_postgres/postgres_c.i +73 -0
  70. data/plugins/dataobjects/swig_sqlite/db +0 -0
  71. data/plugins/dataobjects/swig_sqlite/extconf.rb +9 -0
  72. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +4725 -0
  73. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +168 -0
  74. data/rakefile.rb +45 -23
  75. data/spec/acts_as_tree_spec.rb +39 -0
  76. data/spec/associations_spec.rb +220 -0
  77. data/spec/attributes_spec.rb +15 -0
  78. data/spec/base_spec.rb +44 -0
  79. data/spec/callbacks_spec.rb +45 -0
  80. data/spec/can_has_sphinx.rb +6 -0
  81. data/spec/coersion_spec.rb +34 -0
  82. data/spec/conditions_spec.rb +49 -0
  83. data/spec/conversions_to_yaml_spec.rb +17 -0
  84. data/spec/count_command_spec.rb +11 -0
  85. data/spec/delete_command_spec.rb +1 -1
  86. data/spec/embedded_value_spec.rb +23 -0
  87. data/spec/fixtures/animals_exhibits.yaml +2 -0
  88. data/spec/fixtures/people.yaml +18 -1
  89. data/spec/{legacy.rb → legacy_spec.rb} +3 -3
  90. data/spec/load_command_spec.rb +157 -20
  91. data/spec/magic_columns_spec.rb +9 -0
  92. data/spec/mock_adapter.rb +20 -0
  93. data/spec/models/animal.rb +1 -1
  94. data/spec/models/animals_exhibit.rb +6 -0
  95. data/spec/models/exhibit.rb +2 -0
  96. data/spec/models/person.rb +26 -1
  97. data/spec/models/project.rb +19 -0
  98. data/spec/models/sales_person.rb +1 -0
  99. data/spec/models/section.rb +6 -0
  100. data/spec/models/zoo.rb +3 -1
  101. data/spec/query_spec.rb +9 -0
  102. data/spec/save_command_spec.rb +65 -1
  103. data/spec/schema_spec.rb +89 -0
  104. data/spec/single_table_inheritance_spec.rb +27 -0
  105. data/spec/spec_helper.rb +9 -55
  106. data/spec/{symbolic_operators.rb → symbolic_operators_spec.rb} +9 -5
  107. data/spec/{validates_confirmation_of.rb → validates_confirmation_of_spec.rb} +4 -3
  108. data/spec/{validates_format_of.rb → validates_format_of_spec.rb} +5 -4
  109. data/spec/{validates_length_of.rb → validates_length_of_spec.rb} +8 -7
  110. data/spec/{validates_uniqueness_of.rb → validates_uniqueness_of_spec.rb} +7 -10
  111. data/spec/{validations.rb → validations_spec.rb} +24 -6
  112. data/tasks/drivers.rb +20 -0
  113. data/tasks/fixtures.rb +42 -0
  114. metadata +181 -42
  115. data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +0 -140
  116. data/lib/data_mapper/adapters/sql/commands/delete_command.rb +0 -113
  117. data/lib/data_mapper/adapters/sql/commands/save_command.rb +0 -141
  118. data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +0 -33
  119. data/lib/data_mapper/adapters/sql_adapter.rb +0 -163
  120. data/lib/data_mapper/associations/advanced_has_many_association.rb +0 -55
  121. data/lib/data_mapper/support/blank_slate.rb +0 -3
  122. data/lib/data_mapper/support/proc.rb +0 -69
  123. data/lib/data_mapper/support/struct.rb +0 -26
  124. data/lib/data_mapper/unit_of_work.rb +0 -38
  125. data/spec/basic_finder.rb +0 -67
  126. data/spec/belongs_to.rb +0 -47
  127. data/spec/has_and_belongs_to_many.rb +0 -25
  128. data/spec/has_many.rb +0 -34
  129. data/spec/new_record.rb +0 -24
  130. data/spec/sub_select.rb +0 -16
  131. data/spec/support/string_spec.rb +0 -7
@@ -0,0 +1,65 @@
1
+ module DataMapper
2
+
3
+ class EmbeddedValue
4
+
5
+ def initialize(instance)
6
+ @instance = instance
7
+ end
8
+
9
+ def self.property(name, type, options = {})
10
+ mapping = database.schema[containing_class].add_column(name, type, options)
11
+ define_property_getter(name, mapping)
12
+ define_property_setter(name, mapping)
13
+ end
14
+
15
+ def self.define_property_getter(name, mapping)
16
+ class_eval <<-EOS
17
+ def #{name}
18
+ @instance.instance_variable_get(#{mapping.instance_variable_name.inspect})
19
+ end
20
+ EOS
21
+ end
22
+
23
+ def self.define_property_setter(name, mapping)
24
+ class_eval <<-EOS
25
+ def #{name.to_s.sub(/\?$/, '')}=(value)
26
+ @instance.instance_variable_set(#{mapping.instance_variable_name.inspect}, value)
27
+ end
28
+ EOS
29
+ end
30
+
31
+ def self.containing_class
32
+ @containing_class || @containing_class = begin
33
+ tree = name.split('::')
34
+ tree.pop
35
+ tree.inject(Object) { |klass, current| klass.const_get(current) }
36
+ end
37
+ end
38
+
39
+ def self.define(container, class_or_name, &block)
40
+ embedded_class, embedded_class_name, accessor_name = nil
41
+
42
+ if class_or_name.kind_of?(Class)
43
+ embedded_class = class_or_name
44
+ embedded_class_name = class_or_name.name.split('::').last
45
+ accessor_name = Inflector.underscore(embedded_class_name)
46
+ else
47
+ accessor_name = class_or_name.to_s
48
+ embedded_class_name = Inflector.camelize(accessor_name)
49
+ embedded_class = Class.new(EmbeddedValue)
50
+ container.const_set(embedded_class_name, embedded_class) unless container.const_defined?(embedded_class_name)
51
+ end
52
+
53
+ embedded_class.instance_variable_set('@containing_class', container)
54
+ embedded_class.class_eval(&block) if block_given?
55
+
56
+ container.class_eval <<-EOS
57
+ def #{accessor_name}
58
+ #{embedded_class_name}.new(self)
59
+ end
60
+ EOS
61
+ end
62
+
63
+ end
64
+
65
+ end # module DataMapper
@@ -15,7 +15,7 @@ module DataMapper
15
15
  # Pass a Class and a key, and to retrieve an instance.
16
16
  # If the instance isn't found, nil is returned.
17
17
  def get(klass, key)
18
- @cache[klass][key]
18
+ @cache[mapped_class(klass)][key]
19
19
  end
20
20
 
21
21
  # Pass an instance to add it to the IdentityMap.
@@ -23,13 +23,13 @@ module DataMapper
23
23
  def set(instance)
24
24
  instance_key = instance.key
25
25
  raise "Can't store an instance with a nil key in the IdentityMap" if instance_key.nil?
26
-
27
- @cache[instance.class][instance_key] = instance
26
+
27
+ @cache[mapped_class(instance.class)][instance_key] = instance
28
28
  end
29
29
 
30
30
  # Remove an instance from the IdentityMap.
31
31
  def delete(instance)
32
- @cache[instance.class].delete(instance.key)
32
+ @cache[mapped_class(instance.class)].delete(instance.key)
33
33
  end
34
34
 
35
35
  # Clears a particular set of classes from the IdentityMap.
@@ -37,5 +37,13 @@ module DataMapper
37
37
  @cache.delete(klass)
38
38
  end
39
39
 
40
+ private
41
+ def mapped_class(klass)
42
+ if klass.superclass == DataMapper::Base
43
+ klass
44
+ else
45
+ mapped_class(klass.superclass)
46
+ end
47
+ end
40
48
  end
41
49
  end
@@ -29,12 +29,16 @@ module DataMapper
29
29
  first(search_attributes) || create(search_attributes.merge(create_attributes))
30
30
  end
31
31
 
32
- def all(options = {}, &b)
33
- database.all(self, options, &b)
32
+ def all(options = {})
33
+ database.all(self, options)
34
34
  end
35
35
 
36
- def first(*args, &b)
37
- database.first(self, *args, &b)
36
+ def first(*args)
37
+ database.first(self, *args)
38
+ end
39
+
40
+ def count(*args)
41
+ database.count(self, *args)
38
42
  end
39
43
 
40
44
  def delete_all
@@ -45,11 +49,11 @@ module DataMapper
45
49
  database.truncate(self)
46
50
  end
47
51
 
48
- def find(type_or_id, options = {}, &b)
52
+ def find(type_or_id, options = {})
49
53
  case type_or_id
50
- when :first then first(options, &b)
51
- when :all then all(options, &b)
52
- else first(type_or_id, options, &b)
54
+ when :first then first(options)
55
+ when :all then all(options)
56
+ else first(type_or_id, options)
53
57
  end
54
58
  end
55
59
 
@@ -1,5 +1,13 @@
1
1
  module DataMapper
2
+ # The Support module adds functionality to Make Things Easier(tm):
3
+ # * grouping by attributes of objects in an array (returns a hash, see #DataMapper::Support::Enumerable)
4
+ # * adds symbols for operators like <= (lte), like, in, select, etc (see #DataMapper::Support::Symbol)
5
+ # * adds methods for strings, allowing us to ensure strings are wrapped with content (see #DataMapper::Support::String)
6
+ # * pulls in ActiveSupport's Inflector module
7
+ # * loads #DataMapper::Database and #DataMapper::Base
2
8
  module Support
9
+
10
+ # Extends Array to include an instance method for grouping objects
3
11
  module Enumerable
4
12
 
5
13
  # Group a collection of elements into groups within a
@@ -0,0 +1,13 @@
1
+ module DataMapper
2
+ module Support
3
+ module Serialization
4
+
5
+ def to_yaml
6
+ document = {}
7
+ attributes.each_pair { |k,v| document[k.to_s] = v }
8
+ document.to_yaml
9
+ end
10
+
11
+ end
12
+ end # module Support
13
+ end # module DataMapper
@@ -35,16 +35,5 @@ module DataMapper
35
35
  end # module DataMapper
36
36
 
37
37
  class String #:nodoc:
38
- include DataMapper::Support::String
39
-
40
- def self.fragile_underscore(camel_cased_word)
41
- camel_cased_word.gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
42
- end
43
-
44
- @underscore_cache = Hash.new { |h,k| h[k.freeze] = fragile_underscore(k) }
45
-
46
- def self.memoized_underscore(camel_cased_word)
47
- @underscore_cache[camel_cased_word]
48
- end
49
-
38
+ include DataMapper::Support::String
50
39
  end
@@ -1,5 +1,7 @@
1
1
  module DataMapper
2
2
  module Support
3
+
4
+ # Extends
3
5
  module Symbol
4
6
 
5
7
  class Operator
@@ -76,6 +78,7 @@ module DataMapper
76
78
  def avg
77
79
  Operator.new(self, :avg)
78
80
  end
81
+
79
82
  alias average avg
80
83
 
81
84
  def min
@@ -35,8 +35,7 @@ module DataMapper
35
35
  finder_options.merge! @options[:scope] => scope_value
36
36
  end
37
37
 
38
- finder_options.merge!({ target.session.mappings[target.class].key.name.not => target.key }) unless target.new_record?
39
-
38
+ finder_options.merge!({ target.session.table(target.class).key.name.not => target.key }) unless target.new_record?
40
39
  target.session.first(target.class, finder_options).nil?
41
40
  end
42
41
 
@@ -31,7 +31,24 @@ module DataMapper
31
31
  end
32
32
 
33
33
  def valid?(context = :general)
34
- self.class.validations.execute(context, self)
34
+ validate_excluding_association(nil, context)
35
+ end
36
+
37
+ def validate_excluding_association(associated, context = :general)
38
+ return false unless self.class.callbacks.execute(:before_validation, self)
39
+ return false unless self.class.validations.execute(context, self)
40
+ if self.respond_to?(:loaded_associations)
41
+ return false unless self.loaded_associations.all? do |association|
42
+ if association != associated && association.respond_to?(:validate_excluding_association)
43
+ association.validate_excluding_association(self, context)
44
+ else
45
+ true
46
+ end
47
+ end
48
+ end
49
+
50
+ return false unless self.class.callbacks.execute(:after_validation, self)
51
+ return true
35
52
  end
36
53
 
37
54
  module ClassMethods
data/performance.rb CHANGED
@@ -1,11 +1,13 @@
1
+ require 'benchmark'
1
2
  require 'active_record'
2
3
 
3
4
  ActiveRecord::Base.establish_connection :adapter => 'mysql',
4
- :host => 'localhost',
5
5
  :username => 'root',
6
6
  :password => '',
7
7
  :database => 'data_mapper_1'
8
-
8
+
9
+ ActiveRecord::Base.find_by_sql('SELECT 1')
10
+
9
11
  class ARAnimal < ActiveRecord::Base
10
12
  set_table_name 'animals'
11
13
  end
@@ -16,21 +18,16 @@ end
16
18
 
17
19
  require 'lib/data_mapper'
18
20
 
19
- log_path = File.dirname(__FILE__) + '/development.log'
20
-
21
- require 'fileutils'
22
- FileUtils::rm log_path if File.exists?(log_path)
23
-
24
- DataMapper::Database.setup do
25
- adapter 'mysql'
26
- database 'data_mapper_1'
27
- username 'root'
28
- end
21
+ DataMapper::Database.setup({
22
+ :adapter => 'mysql',
23
+ :database => 'data_mapper_1',
24
+ :username => 'root'
25
+ })
29
26
 
30
27
  class DMAnimal < DataMapper::Base
31
28
  set_table_name 'animals'
32
29
  property :name, :string
33
- property :notes, :string, :lazy => true
30
+ property :notes, :string
34
31
  end
35
32
 
36
33
  class DMPerson < DataMapper::Base
@@ -38,7 +35,11 @@ class DMPerson < DataMapper::Base
38
35
  property :name, :string
39
36
  property :age, :integer
40
37
  property :occupation, :string
41
- property :notes, :text, :lazy => true
38
+ property :notes, :text
39
+ property :street, :string
40
+ property :city, :string
41
+ property :state, :string, :size => 2
42
+ property :zip_code, :string, :size => 10
42
43
  end
43
44
 
44
45
  class Exhibit < DataMapper::Base
@@ -63,42 +64,74 @@ end
63
64
 
64
65
  N = (ENV['N'] || 1000).to_i
65
66
 
67
+ # 4.times do
68
+ # [DMAnimal, Zoo, Exhibit].each do |klass|
69
+ # klass.all.each do |instance|
70
+ # klass.create(instance.attributes.reject { |k,v| k == :id })
71
+ # end
72
+ # end
73
+ # end
74
+
66
75
  Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
67
76
 
68
77
  x.report('ActiveRecord:id') do
69
- N.times { ARAnimal.find(1) }
78
+ N.times { ARAnimal.find(1).name }
70
79
  end
71
80
 
72
81
  x.report('DataMapper:id') do
73
- N.times { DMAnimal[1] }
82
+ N.times { DMAnimal[1].name }
83
+ end
84
+
85
+ x.report('DataMapper:id:in-session') do
86
+ database do
87
+ N.times { DMAnimal[1].name }
88
+ end
74
89
  end
75
90
 
76
91
  x.report('ActiveRecord:all') do
77
- N.times { ARAnimal.find(:all) }
92
+ N.times { ARAnimal.find(:all).each { |a| a.name } }
78
93
  end
79
94
 
80
95
  x.report('DataMapper:all') do
81
- N.times { DMAnimal.all }
96
+ N.times { DMAnimal.all.each { |a| a.name } }
97
+ end
98
+
99
+ x.report('DataMapper:all:in-session') do
100
+ database do
101
+ N.times { DMAnimal.all.each { |a| a.name } }
102
+ end
82
103
  end
83
104
 
84
105
  x.report('ActiveRecord:conditions') do
85
- N.times { ARZoo.find(:first, :conditions => ['name = ?', 'Galveston']) }
106
+ N.times { ARZoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
86
107
  end
87
108
 
88
109
  x.report('DataMapper:conditions:short') do
89
- N.times { Zoo[:name => 'Galveston'] }
110
+ N.times { Zoo[:name => 'Galveston'].name }
111
+ end
112
+
113
+ x.report('DataMapper:conditions:short:in-session') do
114
+ database do
115
+ N.times { Zoo[:name => 'Galveston'].name }
116
+ end
90
117
  end
91
118
 
92
119
  x.report('DataMapper:conditions:long') do
93
- N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']) }
120
+ N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
121
+ end
122
+
123
+ x.report('DataMapper:conditions:long:in-session') do
124
+ database do
125
+ N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
126
+ end
94
127
  end
95
128
 
96
129
  people = [
97
- ['Sam', 29, 'Programmer'],
98
- ['Amy', 28, 'Business Analyst Manager'],
99
- ['Scott', 25, 'Programmer'],
100
- ['Josh', 23, 'Supervisor'],
101
- ['Bob', 40, 'Peon']
130
+ ['Sam', 29, 'Programmer', 'A slow text field'],
131
+ ['Amy', 28, 'Business Analyst Manager', 'A slow text field'],
132
+ ['Scott', 25, 'Programmer', 'A slow text field'],
133
+ ['Josh', 23, 'Supervisor', 'A slow text field'],
134
+ ['Bob', 40, 'Peon', 'A slow text field']
102
135
  ]
103
136
 
104
137
  DMPerson.truncate!
@@ -106,7 +139,7 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
106
139
  x.report('ActiveRecord:insert') do
107
140
  N.times do
108
141
  people.each do |a|
109
- ARPerson::create(:name => a[0], :age => a[1], :occupation => a[2])
142
+ ARPerson::create(:name => a[0], :age => a[1], :occupation => a[2], :notes => a[3])
110
143
  end
111
144
  end
112
145
  end
@@ -116,7 +149,7 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
116
149
  x.report('DataMapper:insert') do
117
150
  N.times do
118
151
  people.each do |a|
119
- DMPerson::create(:name => a[0], :age => a[1], :occupation => a[2])
152
+ DMPerson::create(:name => a[0], :age => a[1], :occupation => a[2], :notes => a[3])
120
153
  end
121
154
  end
122
155
  end
@@ -124,6 +157,7 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
124
157
  x.report('ActiveRecord:update') do
125
158
  N.times do
126
159
  bob = ARAnimal.find(:first, :conditions => ["name = ?", 'Elephant'])
160
+ bob.name
127
161
  bob.notes = 'Updated by ActiveRecord'
128
162
  bob.save
129
163
  end
@@ -132,6 +166,7 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
132
166
  x.report('DataMapper:update') do
133
167
  N.times do
134
168
  bob = DMAnimal.first(:name => 'Elephant')
169
+ bob.name
135
170
  bob.notes = 'Updated by DataMapper'
136
171
  bob.save
137
172
  end
@@ -140,34 +175,74 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
140
175
  x.report('ActiveRecord:associations:lazy') do
141
176
  N.times do
142
177
  zoos = ARZoo.find(:all)
143
- zoos.each { |zoo| zoo.exhibits.entries }
178
+ zoos.each { |zoo| zoo.name; zoo.exhibits.entries }
144
179
  end
145
180
  end
146
181
 
147
182
  x.report('ActiveRecord:associations:included') do
148
183
  N.times do
149
184
  zoos = ARZoo.find(:all, :include => [:exhibits])
150
- zoos.each { |zoo| zoo.exhibits.entries }
185
+ zoos.each { |zoo| zoo.name; zoo.exhibits.entries }
151
186
  end
152
187
  end
153
188
 
154
189
  x.report('DataMapper:associations') do
155
190
  N.times do
156
- database do
157
- Zoo.all.each { |zoo| zoo.exhibits.entries }
191
+ Zoo.all.each { |zoo| zoo.name; zoo.exhibits.entries }
192
+ end
193
+ end
194
+
195
+ x.report('DataMapper:associations:in-session') do
196
+ database do
197
+ N.times do
198
+ Zoo.all.each { |zoo| zoo.name; zoo.exhibits.entries }
158
199
  end
159
200
  end
160
201
  end
161
202
 
162
203
  x.report('ActiveRecord:find_by_sql') do
163
204
  N.times do
164
- ARZoo.find_by_sql("SELECT * FROM zoos")
205
+ ARZoo.find_by_sql("SELECT * FROM zoos").each { |z| z.name }
165
206
  end
166
207
  end
167
208
 
168
209
  x.report('DataMapper:find_by_sql') do
169
210
  N.times do
170
- database.query("SELECT * FROM zoos")
211
+ database.query("SELECT * FROM zoos").each { |z| z.name }
212
+ end
213
+ end
214
+
215
+ x.report('ActiveRecord:accessors') do
216
+ person = ARPerson.find(:first)
217
+
218
+ N.times do
219
+ <<-VCARD
220
+ #{person.name} (#{person.age})
221
+ #{person.occupation}
222
+
223
+ #{person.street}
224
+ #{person.city}, #{person.state} #{person.zip_code}
225
+
226
+ #{person.notes}
227
+ VCARD
228
+ end
229
+ end
230
+
231
+ x.report('DataMapper:accessors') do
232
+ person = DMPerson.first
233
+
234
+ N.times do
235
+ <<-VCARD
236
+ #{person.name} (#{person.age})
237
+ #{person.occupation}
238
+
239
+ #{person.street}
240
+ #{person.city}, #{person.state} #{person.zip_code}
241
+
242
+ #{person.notes}
243
+ VCARD
171
244
  end
172
245
  end
246
+
247
+
173
248
  end