dm-core 0.9.10 → 0.9.11

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.
data/History.txt CHANGED
@@ -1,3 +1,18 @@
1
+ === 0.9.11 / not released
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Added deprecation warning for inferred child_key naming convention change
6
+
7
+ * 6 bug fixes:
8
+
9
+ * Removed unecessary code from SEL
10
+ * 1.9.1 fix for Logger to use Array#join instead of Array#to_s
11
+ * 1.9.1 fix for specs to pass
12
+ * Fix for multiple join models to create correct SQL
13
+ * Fix for STI and lazy loading
14
+ * Fixed Resource#eql?
15
+
1
16
  === 0.9.10 / 2009-01-19
2
17
 
3
18
  * 1 major enhancement:
data/Rakefile CHANGED
@@ -9,18 +9,20 @@ require 'lib/dm-core/version'
9
9
 
10
10
  ROOT = Pathname(__FILE__).dirname.expand_path
11
11
 
12
- AUTHOR = "Dan Kubb"
13
- EMAIL = "dan.kubb@gmail.com"
14
- GEM_NAME = "dm-core"
15
- GEM_VERSION = DataMapper::VERSION
16
- GEM_DEPENDENCIES = ["data_objects", "~>0.9.11"],
17
- ["extlib", "~>0.9.10"],
18
- ["addressable", "~>2.0.1"]
12
+ AUTHOR = 'Dan Kubb'
13
+ EMAIL = 'dan.kubb@gmail.com'
14
+ GEM_NAME = 'dm-core'
15
+ GEM_VERSION = DataMapper::VERSION
16
+ GEM_DEPENDENCIES = [
17
+ %w[ data_objects ~>0.9.11 ],
18
+ %w[ extlib ~>0.9.11 ],
19
+ %w[ addressable ~>2.0.2 ],
20
+ ]
19
21
 
20
- PROJECT_NAME = "datamapper"
21
- PROJECT_DESCRIPTION = "Faster, Better, Simpler."
22
- PROJECT_SUMMARY = "An Object/Relational Mapper for Ruby"
23
- PROJECT_URL = "http://datamapper.org"
22
+ PROJECT_NAME = 'datamapper'
23
+ PROJECT_DESCRIPTION = 'Faster, Better, Simpler.'
24
+ PROJECT_SUMMARY = 'An Object/Relational Mapper for Ruby'
25
+ PROJECT_URL = 'http://datamapper.org'
24
26
 
25
27
  require ROOT + 'tasks/hoe'
26
28
  require ROOT + 'tasks/gemspec'
data/dm-core.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{dm-core}
5
- s.version = "0.9.10"
5
+ s.version = "0.9.11"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Dan Kubb"]
9
- s.date = %q{2009-01-19}
9
+ s.date = %q{2009-03-29}
10
10
  s.description = %q{Faster, Better, Simpler.}
11
11
  s.email = ["dan.kubb@gmail.com"]
12
12
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
@@ -25,16 +25,16 @@ Gem::Specification.new do |s|
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
27
  s.add_runtime_dependency(%q<data_objects>, ["~> 0.9.11"])
28
- s.add_runtime_dependency(%q<extlib>, ["~> 0.9.10"])
29
- s.add_runtime_dependency(%q<addressable>, ["~> 2.0.1"])
28
+ s.add_runtime_dependency(%q<extlib>, ["~> 0.9.11"])
29
+ s.add_runtime_dependency(%q<addressable>, ["~> 2.0.2"])
30
30
  else
31
31
  s.add_dependency(%q<data_objects>, ["~> 0.9.11"])
32
- s.add_dependency(%q<extlib>, ["~> 0.9.10"])
33
- s.add_dependency(%q<addressable>, ["~> 2.0.1"])
32
+ s.add_dependency(%q<extlib>, ["~> 0.9.11"])
33
+ s.add_dependency(%q<addressable>, ["~> 2.0.2"])
34
34
  end
35
35
  else
36
36
  s.add_dependency(%q<data_objects>, ["~> 0.9.11"])
37
- s.add_dependency(%q<extlib>, ["~> 0.9.10"])
38
- s.add_dependency(%q<addressable>, ["~> 2.0.1"])
37
+ s.add_dependency(%q<extlib>, ["~> 0.9.11"])
38
+ s.add_dependency(%q<addressable>, ["~> 2.0.2"])
39
39
  end
40
40
  end
data/lib/dm-core.rb CHANGED
@@ -16,15 +16,15 @@ require 'set'
16
16
  require 'time'
17
17
  require 'yaml'
18
18
 
19
- gem 'addressable', '~>2.0.1'
19
+ gem 'addressable', '~>2.0.2'
20
20
  require 'addressable/uri'
21
21
 
22
- gem 'extlib', '~>0.9.10'
22
+ gem 'extlib', '~>0.9.11'
23
23
  require 'extlib'
24
24
  require 'extlib/inflection'
25
25
 
26
26
  begin
27
- gem 'fastthread', '~>1.0.1'
27
+ gem 'fastthread', '~>1.0.4'
28
28
  require 'fastthread'
29
29
  rescue LoadError
30
30
  # fastthread not installed
@@ -171,7 +171,7 @@ module DataMapper
171
171
  # @demo spec/integration/repository_spec.rb
172
172
  def self.repository(name = nil) # :yields: current_context
173
173
  current_repository = if name
174
- raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}" unless name.is_a?(Symbol)
174
+ raise ArgumentError, "First optional argument must be a Symbol, but was #{name.inspect}" unless name.is_a?(Symbol)
175
175
  Repository.context.detect { |r| r.name == name } || Repository.new(name)
176
176
  else
177
177
  Repository.context.last || Repository.new(Repository.default_name)
@@ -3,20 +3,14 @@ dir = Pathname(__FILE__).dirname.expand_path / 'adapters'
3
3
  require dir / 'abstract_adapter'
4
4
  require dir / 'in_memory_adapter'
5
5
 
6
- # TODO Factor these out into dm-more
7
- require dir / 'data_objects_adapter'
8
- begin
9
- require dir / 'sqlite3_adapter'
10
- rescue LoadError
11
- # ignore it
12
- end
13
- begin
14
- require dir / 'mysql_adapter'
15
- rescue LoadError
16
- # ignore it
17
- end
18
- begin
19
- require dir / 'postgres_adapter'
20
- rescue LoadError
21
- # ignore it
6
+ # NOTE: this is a temporary work-around to the load error problems,
7
+ # and is better fixed in dm-core/next. The main reason the fix is
8
+ # not applied in dm-core/master is because the change is non-trivial.
9
+
10
+ %w[ data_objects sqlite3 mysql postgres ].each do |gem|
11
+ begin
12
+ require dir / "#{gem}_adapter"
13
+ rescue LoadError, Gem::Exception
14
+ # ignore it
15
+ end
22
16
  end
@@ -266,14 +266,21 @@ module DataMapper
266
266
  end
267
267
 
268
268
  def links_statement(query)
269
- table_name = query.model.storage_name(query.repository.name)
269
+ table_list = [query.model.storage_name(query.repository.name)]
270
270
 
271
271
  statement = ''
272
272
  query.links.each do |relationship|
273
273
  parent_table_name = relationship.parent_model.storage_name(query.repository.name)
274
274
  child_table_name = relationship.child_model.storage_name(query.repository.name)
275
275
 
276
- join_table_name = table_name == parent_table_name ? child_table_name : parent_table_name
276
+ join_table_name = if table_list.include?(parent_table_name)
277
+ child_table_name
278
+ elsif table_list.include?(child_table_name)
279
+ parent_table_name
280
+ else
281
+ raise ArgumentError, 'you\'re trying to join a table with no connection to this query'
282
+ end
283
+ table_list << join_table_name
277
284
 
278
285
  # We only do INNER JOIN for now
279
286
  statement << " INNER JOIN #{quote_table_name(join_table_name)} ON "
@@ -18,28 +18,28 @@ module DataMapper
18
18
  module Migration
19
19
  # TODO: move to dm-more/dm-migrations (if possible)
20
20
  def storage_exists?(storage_name)
21
- statement = <<-EOS.compress_lines
21
+ statement = <<-SQL.compress_lines
22
22
  SELECT COUNT(*)
23
- FROM "information_schema"."columns"
24
- WHERE "table_name" = ?
23
+ FROM "information_schema"."tables"
24
+ WHERE "table_type" = 'BASE TABLE'
25
25
  AND "table_schema" = current_schema()
26
- EOS
26
+ AND "table_name" = ?
27
+ SQL
27
28
 
28
29
  query(statement, storage_name).first > 0
29
30
  end
30
31
 
31
32
  # TODO: move to dm-more/dm-migrations (if possible)
32
33
  def field_exists?(storage_name, column_name)
33
- statement = <<-EOS.compress_lines
34
+ statement = <<-SQL.compress_lines
34
35
  SELECT COUNT(*)
35
- FROM "pg_class"
36
- JOIN "pg_attribute" ON "pg_class"."oid" = "pg_attribute"."attrelid"
37
- WHERE "pg_attribute"."attname" = ?
38
- AND "pg_class"."relname" = ?
39
- AND "pg_attribute"."attnum" >= 0
40
- EOS
41
-
42
- query(statement, column_name, storage_name).first > 0
36
+ FROM "information_schema"."columns"
37
+ WHERE "table_schema" = current_schema()
38
+ AND "table_name" = ?
39
+ AND "column_name" = ?
40
+ SQL
41
+
42
+ query(statement, storage_name, column_name).first > 0
43
43
  end
44
44
 
45
45
  # TODO: move to dm-more/dm-migrations
@@ -112,8 +112,9 @@ module DataMapper
112
112
  def sequence_exists?(repository, property)
113
113
  statement = <<-EOS.compress_lines
114
114
  SELECT COUNT(*)
115
- FROM "pg_class"
116
- WHERE "relkind" = 'S' AND "relname" = ?
115
+ FROM "information_schema"."sequences"
116
+ WHERE "sequence_name" = ?
117
+ AND "sequence_schema" = current_schema()
117
118
  EOS
118
119
 
119
120
  query(statement, sequence_name(repository, property)).first > 0
@@ -146,6 +146,13 @@ module DataMapper
146
146
  # @api public
147
147
  def belongs_to(name, options={})
148
148
  @_valid_relations = false
149
+
150
+ if options.key?(:class_name) && !options.key?(:child_key)
151
+ warn "The inferred child_key will changing to be prefixed with the relationship name #{name}. " \
152
+ "When using :class_name in belongs_to specify the :child_key explicitly to avoid problems." \
153
+ "#{caller(0)[1]}"
154
+ end
155
+
149
156
  relationship = ManyToOne.setup(name, self, options)
150
157
  # Please leave this in - I will release contextual serialization soon
151
158
  # which requires this -- guyvdb
@@ -67,7 +67,7 @@ module DataMapper
67
67
  EOS
68
68
 
69
69
  names.each do |n|
70
- model.belongs_to(Extlib::Inflection.underscore(n).gsub("/", "_").to_sym, :class_name => n)
70
+ model.belongs_to(Extlib::Inflection.underscore(n).gsub('/', '_').to_sym)
71
71
  end
72
72
 
73
73
  Object.const_set(model_name, model)
@@ -99,7 +99,7 @@ module DataMapper
99
99
 
100
100
  def push(*resources)
101
101
  assert_mutable
102
- resources.reject { |resource| !resource.new_record? && self.include?(resource) }
102
+ resources.reject! { |resource| !resource.new_record? && self.include?(resource) }
103
103
  children.push(*resources)
104
104
  resources.each { |resource| relate_resource(resource) }
105
105
  self
@@ -107,7 +107,7 @@ module DataMapper
107
107
 
108
108
  def unshift(*resources)
109
109
  assert_mutable
110
- resources.reject { |resource| !resource.new_record? && self.include?(resource) }
110
+ resources.reject! { |resource| !resource.new_record? && self.include?(resource) }
111
111
  children.unshift(*resources)
112
112
  resources.each { |resource| relate_resource(resource) }
113
113
  self
@@ -81,10 +81,8 @@ module DataMapper
81
81
 
82
82
  with_repository(child_model) do |r|
83
83
  parent_identity_map = parent.repository.identity_map(parent_model)
84
- child_identity_map = r.identity_map(child_model)
85
84
 
86
85
  query_values = parent_identity_map.keys
87
- query_values.reject! { |k| child_identity_map[k] }
88
86
 
89
87
  bind_values = query_values unless query_values.empty?
90
88
  query = child_key.zip(bind_values.transpose).to_hash
@@ -35,7 +35,9 @@ module DataMapper
35
35
  # @api public
36
36
  def reload(query = {})
37
37
  @query = scoped_query(query)
38
- @query.update(:fields => @query.fields | @key_properties)
38
+ inheritance_property = model.base_model.inheritance_property
39
+ fields = (@key_properties | [inheritance_property]).compact
40
+ @query.update(:fields => @query.fields | fields)
39
41
  replace(all(:reload => true))
40
42
  end
41
43
 
@@ -178,7 +178,7 @@ module DataMapper
178
178
  #
179
179
  def flush
180
180
  return unless @buffer.size > 0
181
- @log.write_method(@buffer.slice!(0..-1).to_s)
181
+ @log.write_method(@buffer.slice!(0..-1).join)
182
182
  end
183
183
 
184
184
  # Close and remove the current log object.
data/lib/dm-core/model.rb CHANGED
@@ -234,6 +234,10 @@ module DataMapper
234
234
  properties(repository_name).key
235
235
  end
236
236
 
237
+ def inheritance_property(repository_name = default_repository_name)
238
+ @properties[repository_name].detect { |property| property.type == DataMapper::Types::Discriminator }
239
+ end
240
+
237
241
  def default_order(repository_name = default_repository_name)
238
242
  @default_order ||= {}
239
243
  @default_order[repository_name] ||= key(repository_name).map { |property| Query::Direction.new(property) }
@@ -344,6 +348,9 @@ module DataMapper
344
348
  model = values.at(inheritance_property_index) || model
345
349
  end
346
350
 
351
+ key_values = nil
352
+ identity_map = nil
353
+
347
354
  if key_property_indexes = query.key_property_indexes(repository)
348
355
  key_values = values.values_at(*key_property_indexes)
349
356
  identity_map = repository.identity_map(model)
@@ -353,7 +360,6 @@ module DataMapper
353
360
  else
354
361
  resource = model.allocate
355
362
  resource.instance_variable_set(:@repository, repository)
356
- identity_map.set(key_values, resource)
357
363
  end
358
364
  else
359
365
  resource = model.allocate
@@ -376,6 +382,10 @@ module DataMapper
376
382
  end
377
383
  end
378
384
 
385
+ if key_values && identity_map
386
+ identity_map.set(key_values, resource)
387
+ end
388
+
379
389
  resource
380
390
  end
381
391
 
@@ -476,8 +486,9 @@ module DataMapper
476
486
  return DataMapper::Query::Path.new(repository, [ relationship ], klass)
477
487
  end
478
488
 
479
- if property = properties(repository_name)[method]
480
- return property
489
+ property_set = properties(repository_name)
490
+ if property_set.has_property?(method)
491
+ return property_set[method]
481
492
  end
482
493
 
483
494
  super
@@ -149,6 +149,11 @@ module DataMapper
149
149
 
150
150
  # Compares if its the same object or if attributes are equal
151
151
  #
152
+ # The comparaison is
153
+ # * false if object not from same repository
154
+ # * false if object has no all same properties
155
+ #
156
+ #
152
157
  # ==== Parameters
153
158
  # other<Object>:: Object to compare to
154
159
  #
@@ -158,15 +163,25 @@ module DataMapper
158
163
  # -
159
164
  # @api public
160
165
  def eql?(other)
161
- return true if object_id == other.object_id
166
+ return true if equal?(other)
167
+
168
+ # two instances for different models cannot be equivalent
162
169
  return false unless other.kind_of?(model)
163
- return true if repository == other.repository && key == other.key
164
170
 
165
- properties.each do |property|
166
- return false if property.get!(self) != property.get!(other)
171
+ # two instances with different keys cannot be equivalent
172
+ return false if key != other.key
173
+
174
+ # neither object has changed since loaded, so they are equivalent
175
+ return true if repository == other.repository && !dirty? && !other.dirty?
176
+
177
+ # get all the loaded and non-loaded properties that are not keys,
178
+ # since the key comparison was performed earlier
179
+ loaded, not_loaded = properties.select { |p| !p.key? }.partition do |property|
180
+ attribute_loaded?(property.name) && other.attribute_loaded?(property.name)
167
181
  end
168
182
 
169
- true
183
+ # check all loaded properties, and then all unloaded properties
184
+ (loaded + not_loaded).all? { |p| p.get(self) == p.get(other) }
170
185
  end
171
186
 
172
187
  alias == eql?
@@ -264,4 +264,4 @@ module DataMapper
264
264
  end
265
265
 
266
266
  end # class Transaction
267
- end # module DataMapper
267
+ end # module DataMapper
@@ -77,4 +77,4 @@ module DataMapper
77
77
  end
78
78
  end
79
79
  end # class TypeMap
80
- end # module DataMapper
80
+ end # module DataMapper
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '0.9.10' unless defined?(DataMapper::VERSION)
2
+ VERSION = '0.9.11'.freeze
3
3
  end
@@ -12,7 +12,7 @@ require 'rbench'
12
12
  gem 'faker', '~>0.3.1'
13
13
  require 'faker'
14
14
 
15
- gem 'activerecord', '~>2.2.2'
15
+ gem 'activerecord', '~>2.3.2'
16
16
  require 'active_record'
17
17
 
18
18
  socket_file = Pathname.glob(%w[
data/script/profile.rb CHANGED
@@ -4,7 +4,7 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
4
4
 
5
5
  require 'rubygems'
6
6
 
7
- gem 'ruby-prof', '~>0.7.1'
7
+ gem 'ruby-prof', '~>0.7.3'
8
8
  require 'ruby-prof'
9
9
 
10
10
  gem 'faker', '~>0.3.1'
@@ -1100,7 +1100,6 @@ if ADAPTER
1100
1100
  customer.name == 'John Johnsen'
1101
1101
  end
1102
1102
  customers.size.should == 1
1103
- # another example can be found here: http://pastie.textmate.org/private/tt1hf1syfsytyxdgo4qxawfl
1104
1103
  end
1105
1104
 
1106
1105
  it 'should return the right children for has n => has 1 relationships' do
@@ -116,7 +116,7 @@ if HAS_SQLITE3
116
116
  }
117
117
 
118
118
  types.each do |name,(klass,type,nullable,default,key)|
119
- describe "a #{klass} property" do
119
+ describe "a #{klass} property (#{name})" do
120
120
  it "should be created as a #{type}" do
121
121
  @table_set[name.to_s].type.should == type
122
122
  end
@@ -228,7 +228,7 @@ if HAS_MYSQL
228
228
  }
229
229
 
230
230
  types.each do |name,(klass,type,nullable,default,key)|
231
- describe "a #{klass} property" do
231
+ describe "a #{klass} property (#{name})" do
232
232
  it "should be created as a #{type}" do
233
233
  @table_set[name.to_s].type.should == type
234
234
  end
@@ -372,7 +372,7 @@ if HAS_POSTGRES
372
372
  }
373
373
 
374
374
  types.each do |name,(klass,type,nullable,default,key)|
375
- describe "a #{Extlib::Inflection.classify(name.to_s)} property" do
375
+ describe "a #{klass} property (#{name})" do
376
376
  it "should be created as a #{type}" do
377
377
  @table_set[name.to_s].type.should == type
378
378
  end
@@ -1,11 +1,11 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
- if RUBY_VERSION >= '1.9.0'
4
- require 'csv'
5
- else
6
- gem 'fastercsv', '~>1.4.0'
7
- require 'fastercsv'
8
- end
3
+ # if RUBY_VERSION >= '1.9.0'
4
+ # require 'csv'
5
+ # else
6
+ # gem 'fastercsv', '~>1.4.0'
7
+ # require 'fastercsv'
8
+ # end
9
9
 
10
10
  describe DataMapper::Property do
11
11
  before do
@@ -9,6 +9,7 @@ if ADAPTER
9
9
  describe "DataMapper::Resource with #{ADAPTER}" do
10
10
 
11
11
  load_models_for_metaphor :zoo
12
+ load_models_for_metaphor :content
12
13
 
13
14
  before(:each) do
14
15
  DataMapper.auto_migrate!(ADAPTER)
@@ -59,12 +60,39 @@ if ADAPTER
59
60
  end
60
61
 
61
62
  describe '#eql?' do
62
- it "should return true if the objects are the same instances"
63
- it "should return false if the other object is not an instance of the same model"
64
- it "should return false if the other object is a different class"
63
+
64
+ it "should return true if the objects are the same instances" do
65
+ z = Zoo.first
66
+ z2 = z
67
+ z.should be_eql(z2)
68
+ end
69
+
70
+ it "should return false if the other object is not an instance of the same model" do
71
+ z = Zoo.first
72
+ z2 = Zoo.create(:name => 'New York')
73
+ z.should_not be_eql(z2)
74
+ end
75
+
76
+ it "should return false if the other object is a different class" do
77
+ z = Zoo.first
78
+ o = Content::Dialect.first
79
+ z.should_not be_eql(o)
80
+ end
81
+
65
82
  it "should return true if the repositories are the same and the primary key is the same"
66
- it "should return true if all the properties are the same"
67
- it "should return false if any of the properties are different"
83
+ it "should return false if the repository is not the same and the primary key is the same"
84
+
85
+ it "should return true if all the properties are the same" do
86
+ z = Zoo.first
87
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission})
88
+ z.should be_eql(z2)
89
+ end
90
+
91
+ it "should return false if any of the properties are different" do
92
+ z = Zoo.first
93
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission}.merge(:description => 'impressive'))
94
+ z.should_not be_eql(z2)
95
+ end
68
96
  end
69
97
 
70
98
  describe '#hash' do
@@ -162,127 +190,127 @@ end
162
190
 
163
191
  # ---------- Old specs... BOOOOOOOOOO ---------------
164
192
  if ADAPTER
165
- class Orange
166
- include DataMapper::Resource
193
+ describe "DataMapper::Resource with #{ADAPTER}" do
194
+ before :all do
195
+ class ::Orange
196
+ include DataMapper::Resource
167
197
 
168
- def self.default_repository_name
169
- ADAPTER
170
- end
198
+ def self.default_repository_name
199
+ ADAPTER
200
+ end
171
201
 
172
- property :name, String, :key => true
173
- property :color, String
174
- end
202
+ property :name, String, :key => true
203
+ property :color, String
204
+ end
175
205
 
176
- class Apple
177
- include DataMapper::Resource
206
+ class ::Apple
207
+ include DataMapper::Resource
178
208
 
179
- def self.default_repository_name
180
- ADAPTER
181
- end
209
+ def self.default_repository_name
210
+ ADAPTER
211
+ end
182
212
 
183
- property :id, Serial
184
- property :color, String, :default => 'green', :nullable => true
185
- end
213
+ property :id, Serial
214
+ property :color, String, :default => 'green', :nullable => true
215
+ end
186
216
 
187
- class FortunePig
188
- include DataMapper::Resource
217
+ class ::FortunePig
218
+ include DataMapper::Resource
189
219
 
190
- def self.default_repository_name
191
- ADAPTER
192
- end
220
+ def self.default_repository_name
221
+ ADAPTER
222
+ end
193
223
 
194
- property :id, Serial
195
- property :name, String
224
+ property :id, Serial
225
+ property :name, String
196
226
 
197
- def to_s
198
- name
199
- end
227
+ def to_s
228
+ name
229
+ end
200
230
 
201
- after :create do
202
- @created_id = self.id
203
- end
231
+ after :create do
232
+ @created_id = self.id
233
+ end
204
234
 
205
- after :save do
206
- @save_id = self.id
207
- end
208
- end
235
+ after :save do
236
+ @save_id = self.id
237
+ end
238
+ end
209
239
 
210
- class Car
211
- include DataMapper::Resource
240
+ class ::Car
241
+ include DataMapper::Resource
212
242
 
213
- def self.default_repository_name
214
- ADAPTER
215
- end
243
+ def self.default_repository_name
244
+ ADAPTER
245
+ end
216
246
 
217
- property :brand, String, :key => true
218
- property :color, String
219
- property :created_on, Date
220
- property :touched_on, Date
221
- property :updated_on, Date
247
+ property :brand, String, :key => true
248
+ property :color, String
249
+ property :created_on, Date
250
+ property :touched_on, Date
251
+ property :updated_on, Date
222
252
 
223
- before :save do
224
- self.touched_on = Date.today
225
- end
253
+ before :save do
254
+ self.touched_on = Date.today
255
+ end
226
256
 
227
- before :create do
228
- self.created_on = Date.today
229
- end
257
+ before :create do
258
+ self.created_on = Date.today
259
+ end
230
260
 
231
- before :update do
232
- self.updated_on = Date.today
233
- end
234
- end
261
+ before :update do
262
+ self.updated_on = Date.today
263
+ end
264
+ end
235
265
 
236
- class Male
237
- include DataMapper::Resource
266
+ class ::Male
267
+ include DataMapper::Resource
238
268
 
239
- def self.default_repository_name
240
- ADAPTER
241
- end
269
+ def self.default_repository_name
270
+ ADAPTER
271
+ end
242
272
 
243
- property :id, Serial
244
- property :name, String
245
- property :iq, Integer, :default => 100
246
- property :type, Discriminator
247
- property :data, Object
273
+ property :id, Serial
274
+ property :name, String
275
+ property :iq, Integer, :default => 100
276
+ property :type, Discriminator
277
+ property :data, Object
248
278
 
249
- def iq=(i)
250
- attribute_set(:iq, i - 1)
251
- end
252
- end
279
+ def iq=(i)
280
+ attribute_set(:iq, i - 1)
281
+ end
282
+ end
253
283
 
254
- class Bully < Male; end
284
+ class ::Bully < Male; end
255
285
 
256
- class Mugger < Bully; end
286
+ class ::Mugger < Bully; end
257
287
 
258
- class Maniac < Bully; end
288
+ class ::Maniac < Bully; end
259
289
 
260
- class Psycho < Maniac; end
290
+ class ::Psycho < Maniac; end
261
291
 
262
- class Geek < Male
263
- property :awkward, Boolean, :default => true
292
+ class ::Geek < Male
293
+ property :awkward, Boolean, :default => true
264
294
 
265
- def iq=(i)
266
- attribute_set(:iq, i + 30)
267
- end
268
- end
295
+ def iq=(i)
296
+ attribute_set(:iq, i + 30)
297
+ end
298
+ end
269
299
 
270
- class Flanimal
271
- include DataMapper::Resource
300
+ class ::Flanimal
301
+ include DataMapper::Resource
272
302
 
273
- def self.default_repository_name
274
- ADAPTER
275
- end
303
+ def self.default_repository_name
304
+ ADAPTER
305
+ end
276
306
 
277
- property :id, Serial
278
- property :type, Discriminator
279
- property :name, String
280
- end
307
+ property :id, Serial
308
+ property :type, Discriminator
309
+ property :name, String
310
+ end
281
311
 
282
- class Sprog < Flanimal; end
312
+ class ::Sprog < Flanimal; end
283
313
 
284
- describe "DataMapper::Resource with #{ADAPTER}" do
285
- before :all do
286
314
  Orange.auto_migrate!(ADAPTER)
287
315
  Apple.auto_migrate!(ADAPTER)
288
316
  FortunePig.auto_migrate!(ADAPTER)
@@ -14,6 +14,7 @@ if HAS_SQLITE3
14
14
  property :id, Serial
15
15
  property :title, String, :nullable => false
16
16
  property :isbn, Integer, :nullable => false
17
+ property :content, Text
17
18
  property :class_type, Discriminator
18
19
  end
19
20
 
@@ -226,5 +227,47 @@ if HAS_SQLITE3
226
227
  end
227
228
  end
228
229
  end
230
+
231
+ describe "with lazy property" do
232
+ before :all do
233
+ Book.auto_migrate!(:sqlite3)
234
+ repository(:sqlite3) do
235
+ ShortStory.create(
236
+ :title => "The Science of Happiness",
237
+ :isbn => "129038",
238
+ :content => 'This doesn\'t feel like a normal academic conference. True, the three-day Positive Psychology Summit i',
239
+ :moral => "Bullshit might get you to the top, but it won't keep you there."
240
+ )
241
+
242
+ ShortStory.create(
243
+ :title => "Blank as white paper",
244
+ :isbn => "129039",
245
+ :content => '',
246
+ :moral => "none."
247
+ )
248
+ end
249
+ end
250
+
251
+ it "should be able to access the properties from the parent collection" do
252
+ repository(:sqlite3) do
253
+ books = Book.all
254
+
255
+ books.each do |book|
256
+ book.title.should_not be_nil
257
+ book.isbn.should_not be_nil
258
+ book.moral.should_not be_nil
259
+ end
260
+
261
+ books[0].content
262
+
263
+ books.each do |book|
264
+ book.title.should_not be_nil
265
+ book.isbn.should_not be_nil
266
+ book.moral.should_not be_nil
267
+ end
268
+
269
+ end
270
+ end
271
+ end
229
272
  end
230
273
  end
@@ -1,11 +1,11 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
- if RUBY_VERSION >= '1.9.0'
4
- require 'csv'
5
- else
6
- gem 'fastercsv', '~>1.4.0'
7
- require 'fastercsv'
8
- end
3
+ # if RUBY_VERSION >= '1.9.0'
4
+ # require 'csv'
5
+ # else
6
+ # gem 'fastercsv', '~>1.4.0'
7
+ # require 'fastercsv'
8
+ # end
9
9
 
10
10
  if ADAPTER
11
11
  module ::TypeTests
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'pathname'
2
2
  require 'rubygems'
3
3
 
4
- gem 'rspec', '~>1.1.11'
4
+ gem 'rspec', '~>1.2'
5
5
  require 'spec'
6
6
 
7
7
  SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
@@ -339,7 +339,7 @@ describe DataMapper::Adapters::DataObjectsAdapter do
339
339
 
340
340
  if method == :read_one
341
341
  it 'should return a DataMapper::Resource' do
342
- do_read.should == be_kind_of(DataMapper::Resource)
342
+ do_read.should be_kind_of(DataMapper::Resource)
343
343
  end
344
344
  else
345
345
  it 'should return a DataMapper::Collection' do
@@ -36,7 +36,7 @@ if HAS_POSTGRES
36
36
  end
37
37
 
38
38
  it 'should check to make sure the sequences exist' do
39
- statement = %q[SELECT COUNT(*) FROM "pg_class" WHERE "relkind" = 'S' AND "relname" = ?]
39
+ statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
40
40
  @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
41
41
  @adapter.upgrade_model_storage(@repository, @model)
42
42
  end
@@ -78,7 +78,7 @@ if HAS_POSTGRES
78
78
  end
79
79
 
80
80
  it 'should check to make sure the sequences exist' do
81
- statement = %q[SELECT COUNT(*) FROM "pg_class" WHERE "relkind" = 'S' AND "relname" = ?]
81
+ statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
82
82
  @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
83
83
  @adapter.create_model_storage(@repository, @model)
84
84
  end
@@ -231,11 +231,11 @@ describe "DataMapper::Associations" do
231
231
 
232
232
  it "should create a many-to-one association with options" do
233
233
  DataMapper::Associations::ManyToOne.should_receive(:setup).
234
- with(:vehicle, Manufacturer, { :class_name => 'Car' }).
234
+ with(:vehicle, Manufacturer, :class_name => 'Car', :child_key => [ :car_id ]).
235
235
  and_return(@relationship)
236
236
 
237
237
  class ::Manufacturer
238
- belongs_to(:vehicle, :class_name => 'Car').should == mock_relationship
238
+ belongs_to(:vehicle, :class_name => 'Car', :child_key => [ :car_id ]).should == mock_relationship
239
239
  end
240
240
  end
241
241
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.10
4
+ version: 0.9.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Kubb
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-19 00:00:00 -08:00
12
+ date: 2009-03-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.10
33
+ version: 0.9.11
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: addressable
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: 2.0.1
43
+ version: 2.0.2
44
44
  version:
45
45
  description: Faster, Better, Simpler.
46
46
  email: