datamapper 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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