dm-core 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -5
- data/Manifest.txt +1 -0
- data/README.txt +67 -23
- data/Rakefile +0 -2
- data/deps.rip +1 -1
- data/dm-core.gemspec +6 -6
- data/lib/dm-core/adapters/abstract_adapter.rb +3 -76
- data/lib/dm-core/adapters/data_objects_adapter.rb +8 -39
- data/lib/dm-core/associations/many_to_many.rb +28 -16
- data/lib/dm-core/associations/many_to_one.rb +1 -45
- data/lib/dm-core/associations/one_to_many.rb +1 -38
- data/lib/dm-core/associations/relationship.rb +43 -20
- data/lib/dm-core/collection.rb +33 -32
- data/lib/dm-core/model/property.rb +8 -8
- data/lib/dm-core/model/relationship.rb +10 -12
- data/lib/dm-core/property.rb +20 -85
- data/lib/dm-core/property_set.rb +8 -8
- data/lib/dm-core/query/conditions/comparison.rb +13 -71
- data/lib/dm-core/query/conditions/operation.rb +73 -47
- data/lib/dm-core/query/operator.rb +3 -45
- data/lib/dm-core/query/path.rb +5 -41
- data/lib/dm-core/query.rb +37 -108
- data/lib/dm-core/repository.rb +3 -79
- data/lib/dm-core/resource.rb +54 -49
- data/lib/dm-core/support/chainable.rb +0 -2
- data/lib/dm-core/support/equalizer.rb +23 -0
- data/lib/dm-core/types/object.rb +4 -4
- data/lib/dm-core/version.rb +1 -1
- data/lib/dm-core.rb +3 -11
- data/spec/public/model/relationship_spec.rb +4 -4
- data/spec/public/property_spec.rb +5 -449
- data/spec/public/sel_spec.rb +52 -2
- data/spec/public/shared/collection_shared_spec.rb +79 -26
- data/spec/public/shared/finder_shared_spec.rb +6 -6
- data/spec/public/shared/resource_shared_spec.rb +2 -2
- data/spec/semipublic/property_spec.rb +524 -9
- data/spec/semipublic/query_spec.rb +6 -6
- data/tasks/hoe.rb +2 -2
- metadata +24 -4
data/lib/dm-core/resource.rb
CHANGED
@@ -21,7 +21,7 @@ module DataMapper
|
|
21
21
|
# @deprecated
|
22
22
|
def self.descendants
|
23
23
|
warn "DataMapper::Resource.descendants is deprecated, use DataMapper::Model.descendants instead (#{caller[0]})"
|
24
|
-
|
24
|
+
Model.descendants
|
25
25
|
end
|
26
26
|
|
27
27
|
# Deprecated API for updating attributes and saving Resource
|
@@ -118,6 +118,16 @@ module DataMapper
|
|
118
118
|
@saved == true
|
119
119
|
end
|
120
120
|
|
121
|
+
# Checks if this Resource instance is destroyed
|
122
|
+
#
|
123
|
+
# @return [Boolean]
|
124
|
+
# true if the resource has been destroyed
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
def destroyed?
|
128
|
+
@destroyed == true
|
129
|
+
end
|
130
|
+
|
121
131
|
# Checks if the resource has no changes to save
|
122
132
|
#
|
123
133
|
# @return [Boolean]
|
@@ -283,7 +293,7 @@ module DataMapper
|
|
283
293
|
# @api public
|
284
294
|
def reload
|
285
295
|
if saved?
|
286
|
-
|
296
|
+
eager_load(loaded_properties)
|
287
297
|
child_relationships.each { |relationship| relationship.get!(self).reload }
|
288
298
|
end
|
289
299
|
|
@@ -364,13 +374,13 @@ module DataMapper
|
|
364
374
|
# @api public
|
365
375
|
def destroy!
|
366
376
|
if saved? && repository.delete(Collection.new(query, [ self ])) == 1
|
377
|
+
@destroyed = true
|
367
378
|
@collection.delete(self) if @collection
|
368
379
|
reset
|
369
380
|
freeze
|
370
|
-
true
|
371
|
-
else
|
372
|
-
false
|
373
381
|
end
|
382
|
+
|
383
|
+
destroyed?
|
374
384
|
end
|
375
385
|
|
376
386
|
# Compares another Resource for equality
|
@@ -388,9 +398,7 @@ module DataMapper
|
|
388
398
|
# @api public
|
389
399
|
def eql?(other)
|
390
400
|
return true if equal?(other)
|
391
|
-
|
392
|
-
|
393
|
-
cmp?(other, :eql?)
|
401
|
+
instance_of?(other.class) && cmp?(other, :eql?)
|
394
402
|
end
|
395
403
|
|
396
404
|
# Compares another Resource for equivalency
|
@@ -408,8 +416,8 @@ module DataMapper
|
|
408
416
|
# @api public
|
409
417
|
def ==(other)
|
410
418
|
return true if equal?(other)
|
411
|
-
|
412
|
-
|
419
|
+
other.respond_to?(:model) &&
|
420
|
+
model.base_model.equal?(other.model.base_model) &&
|
413
421
|
cmp?(other, :==)
|
414
422
|
end
|
415
423
|
|
@@ -429,7 +437,7 @@ module DataMapper
|
|
429
437
|
raise ArgumentError, "Cannot compare a #{other.model} instance with a #{model} instance"
|
430
438
|
end
|
431
439
|
cmp = 0
|
432
|
-
model.default_order(repository_name).
|
440
|
+
model.default_order(repository_name).each do |direction|
|
433
441
|
cmp = direction.get(self) <=> direction.get(other)
|
434
442
|
break if cmp != 0
|
435
443
|
end
|
@@ -506,27 +514,6 @@ module DataMapper
|
|
506
514
|
properties[name].loaded?(self)
|
507
515
|
end
|
508
516
|
|
509
|
-
# Fetches all the names of the attributes that have been loaded,
|
510
|
-
# even if they are lazy but have been called
|
511
|
-
#
|
512
|
-
# @example
|
513
|
-
# class Foo
|
514
|
-
# include DataMapper::Resource
|
515
|
-
#
|
516
|
-
# property :name, String
|
517
|
-
# property :description, Text, :lazy => false
|
518
|
-
# end
|
519
|
-
#
|
520
|
-
# Foo.new.loaded_properties #=> [ #<Property @model=Foo @name=:name> ]
|
521
|
-
#
|
522
|
-
# @return [Array(Property)]
|
523
|
-
# names of attributes that have been loaded
|
524
|
-
#
|
525
|
-
# @api private
|
526
|
-
def loaded_properties
|
527
|
-
properties.select { |property| property.loaded?(self) }
|
528
|
-
end
|
529
|
-
|
530
517
|
# Checks if an attribute has unsaved changes
|
531
518
|
#
|
532
519
|
# @param [Symbol] name
|
@@ -690,10 +677,9 @@ module DataMapper
|
|
690
677
|
model.relationships(repository_name)
|
691
678
|
end
|
692
679
|
|
693
|
-
# Returns identity map
|
694
|
-
# was loaded from
|
680
|
+
# Returns the identity map for the model from the repository
|
695
681
|
#
|
696
|
-
# @return [
|
682
|
+
# @return [IdentityMap]
|
697
683
|
# identity map of repository this object was loaded from
|
698
684
|
#
|
699
685
|
# @api semipublic
|
@@ -701,26 +687,41 @@ module DataMapper
|
|
701
687
|
repository.identity_map(model)
|
702
688
|
end
|
703
689
|
|
704
|
-
#
|
705
|
-
#
|
690
|
+
# Fetches all the names of the attributes that have been loaded,
|
691
|
+
# even if they are lazy but have been called
|
692
|
+
#
|
693
|
+
# @return [Array<Property>]
|
694
|
+
# names of attributes that have been loaded
|
706
695
|
#
|
707
696
|
# @api private
|
708
|
-
def
|
709
|
-
|
697
|
+
def loaded_properties
|
698
|
+
properties.select { |property| property.loaded?(self) }
|
699
|
+
end
|
700
|
+
|
701
|
+
# Lazy loads attributes not yet loaded
|
702
|
+
#
|
703
|
+
# @param [Array<Property>] fields
|
704
|
+
# the properties to reload
|
705
|
+
#
|
706
|
+
# @return [self]
|
707
|
+
#
|
708
|
+
# @api private
|
709
|
+
def lazy_load(fields)
|
710
|
+
eager_load(fields - loaded_properties)
|
710
711
|
end
|
711
712
|
|
712
713
|
# Reloads specified attributes
|
713
714
|
#
|
714
|
-
# @param [
|
715
|
-
#
|
715
|
+
# @param [Array<Property>] fields
|
716
|
+
# the properties to reload
|
716
717
|
#
|
717
718
|
# @return [Resource]
|
718
719
|
# the receiver, the current Resource instance
|
719
720
|
#
|
720
721
|
# @api private
|
721
|
-
def
|
722
|
-
unless
|
723
|
-
collection.reload(:fields =>
|
722
|
+
def eager_load(fields)
|
723
|
+
unless fields.empty? || new?
|
724
|
+
collection.reload(:fields => fields)
|
724
725
|
end
|
725
726
|
|
726
727
|
self
|
@@ -751,9 +752,9 @@ module DataMapper
|
|
751
752
|
parent_relationships
|
752
753
|
end
|
753
754
|
|
754
|
-
# Returns
|
755
|
+
# Returns loaded child relationships
|
755
756
|
#
|
756
|
-
# @return [Array<
|
757
|
+
# @return [Array<Associations::OneToMany::Relationship>]
|
757
758
|
# array of child relationships for which this resource is parent and is loaded
|
758
759
|
#
|
759
760
|
# @api private
|
@@ -770,14 +771,13 @@ module DataMapper
|
|
770
771
|
end
|
771
772
|
|
772
773
|
many_to_many, other = child_relationships.partition do |relationship|
|
773
|
-
relationship.kind_of?(
|
774
|
+
relationship.kind_of?(Associations::ManyToMany::Relationship)
|
774
775
|
end
|
775
776
|
|
776
777
|
many_to_many + other
|
777
778
|
end
|
778
779
|
|
779
|
-
#
|
780
|
-
# setting default values for any unset properties
|
780
|
+
# Creates the resource with default values
|
781
781
|
#
|
782
782
|
# If resource is not dirty or a new (not yet saved),
|
783
783
|
# this method returns false
|
@@ -878,6 +878,11 @@ module DataMapper
|
|
878
878
|
|
879
879
|
# Raises an exception if #update is performed on a dirty resource
|
880
880
|
#
|
881
|
+
# @param [Symbol] method
|
882
|
+
# the name of the method to use in the exception
|
883
|
+
#
|
884
|
+
# @return [undefined]
|
885
|
+
#
|
881
886
|
# @raise [UpdateConflictError]
|
882
887
|
# raise if the resource is dirty
|
883
888
|
#
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Equalizer
|
3
|
+
def equalize(*methods)
|
4
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
5
|
+
def eql?(other)
|
6
|
+
return true if equal?(other)
|
7
|
+
instance_of?(other.class) &&
|
8
|
+
#{methods.map { |method| "#{method}.eql?(other.#{method})" }.join(' && ')}
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
return true if equal?(other)
|
13
|
+
#{methods.map { |method| "other.respond_to?(#{method.inspect})" }.join(' && ')} &&
|
14
|
+
#{methods.map { |method| "#{method} == other.#{method}" }.join(' && ')}
|
15
|
+
end
|
16
|
+
|
17
|
+
def hash
|
18
|
+
[ #{methods.join(', ')} ].hash
|
19
|
+
end
|
20
|
+
RUBY
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/dm-core/types/object.rb
CHANGED
@@ -2,8 +2,8 @@ module DataMapper
|
|
2
2
|
module Types
|
3
3
|
class Object < Type
|
4
4
|
primitive String
|
5
|
-
|
6
|
-
lazy
|
5
|
+
length 65535
|
6
|
+
lazy true
|
7
7
|
|
8
8
|
# TODO: document
|
9
9
|
# @api private
|
@@ -14,13 +14,13 @@ module DataMapper
|
|
14
14
|
# TODO: document
|
15
15
|
# @api private
|
16
16
|
def self.dump(value, property)
|
17
|
-
|
17
|
+
[ Marshal.dump(value) ].pack('m')
|
18
18
|
end
|
19
19
|
|
20
20
|
# TODO: document
|
21
21
|
# @api private
|
22
22
|
def self.load(value, property)
|
23
|
-
|
23
|
+
Marshal.load(value.unpack('m').first) unless value.nil?
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/dm-core/version.rb
CHANGED
data/lib/dm-core.rb
CHANGED
@@ -1,13 +1,4 @@
|
|
1
|
-
# This file begins the loading sequence.
|
2
|
-
#
|
3
|
-
# Quick Overview:
|
4
|
-
# * Requires fastthread, support libs, and base.
|
5
|
-
# * Sets the application root and environment for compatibility with frameworks
|
6
|
-
# such as Rails or Merb.
|
7
|
-
#
|
8
|
-
|
9
1
|
require 'addressable/uri'
|
10
|
-
require 'base64'
|
11
2
|
require 'bigdecimal'
|
12
3
|
require 'bigdecimal/util'
|
13
4
|
require 'date'
|
@@ -27,6 +18,7 @@ dir = Pathname(__FILE__).dirname.expand_path / 'dm-core'
|
|
27
18
|
|
28
19
|
require dir / 'support' / 'chainable'
|
29
20
|
require dir / 'support' / 'deprecate'
|
21
|
+
require dir / 'support' / 'equalizer'
|
30
22
|
|
31
23
|
require dir / 'model'
|
32
24
|
require dir / 'model' / 'descendant_set'
|
@@ -117,9 +109,9 @@ DataMapper::Logger.new(StringIO.new, :fatal)
|
|
117
109
|
# === Logging
|
118
110
|
# To turn on error logging to STDOUT, issue:
|
119
111
|
#
|
120
|
-
# DataMapper::Logger.new(
|
112
|
+
# DataMapper::Logger.new($stdout, :debug)
|
121
113
|
#
|
122
|
-
# You can pass a file location ("/path/to/log/file.log") in place of
|
114
|
+
# You can pass a file location ("/path/to/log/file.log") in place of $stdout.
|
123
115
|
# see DataMapper::Logger for more information.
|
124
116
|
#
|
125
117
|
module DataMapper
|
@@ -799,8 +799,8 @@ describe DataMapper::Associations do
|
|
799
799
|
@engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
|
800
800
|
end
|
801
801
|
|
802
|
-
it 'should have a source model equal to the
|
803
|
-
@engine_relationship.source_model.should equal(
|
802
|
+
it 'should have a source model equal to the ancestor' do
|
803
|
+
@engine_relationship.source_model.should equal(Car)
|
804
804
|
end
|
805
805
|
|
806
806
|
it 'should have a child key prefix the same as the inverse relationship' do
|
@@ -823,8 +823,8 @@ describe DataMapper::Associations do
|
|
823
823
|
@engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
|
824
824
|
end
|
825
825
|
|
826
|
-
it 'should have a source model equal to the
|
827
|
-
@engine_relationship.source_model.should equal(
|
826
|
+
it 'should have a source model equal to the ancestor' do
|
827
|
+
@engine_relationship.source_model.should equal(Car)
|
828
828
|
end
|
829
829
|
|
830
830
|
it 'should have a child key prefix inferred from the source model name' do
|