sam-dm-core 0.9.6
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/.autotest +26 -0
- data/CONTRIBUTING +51 -0
- data/FAQ +92 -0
- data/History.txt +145 -0
- data/MIT-LICENSE +22 -0
- data/Manifest.txt +125 -0
- data/QUICKLINKS +12 -0
- data/README.txt +143 -0
- data/Rakefile +30 -0
- data/SPECS +63 -0
- data/TODO +1 -0
- data/lib/dm-core.rb +224 -0
- data/lib/dm-core/adapters.rb +4 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +202 -0
- data/lib/dm-core/adapters/data_objects_adapter.rb +707 -0
- data/lib/dm-core/adapters/mysql_adapter.rb +136 -0
- data/lib/dm-core/adapters/postgres_adapter.rb +188 -0
- data/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
- data/lib/dm-core/associations.rb +199 -0
- data/lib/dm-core/associations/many_to_many.rb +147 -0
- data/lib/dm-core/associations/many_to_one.rb +107 -0
- data/lib/dm-core/associations/one_to_many.rb +309 -0
- data/lib/dm-core/associations/one_to_one.rb +61 -0
- data/lib/dm-core/associations/relationship.rb +218 -0
- data/lib/dm-core/associations/relationship_chain.rb +81 -0
- data/lib/dm-core/auto_migrations.rb +113 -0
- data/lib/dm-core/collection.rb +638 -0
- data/lib/dm-core/dependency_queue.rb +31 -0
- data/lib/dm-core/hook.rb +11 -0
- data/lib/dm-core/identity_map.rb +45 -0
- data/lib/dm-core/is.rb +16 -0
- data/lib/dm-core/logger.rb +232 -0
- data/lib/dm-core/migrations/destructive_migrations.rb +17 -0
- data/lib/dm-core/migrator.rb +29 -0
- data/lib/dm-core/model.rb +471 -0
- data/lib/dm-core/naming_conventions.rb +84 -0
- data/lib/dm-core/property.rb +673 -0
- data/lib/dm-core/property_set.rb +162 -0
- data/lib/dm-core/query.rb +625 -0
- data/lib/dm-core/repository.rb +159 -0
- data/lib/dm-core/resource.rb +637 -0
- data/lib/dm-core/scope.rb +58 -0
- data/lib/dm-core/support.rb +7 -0
- data/lib/dm-core/support/array.rb +13 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/errors.rb +23 -0
- data/lib/dm-core/support/kernel.rb +7 -0
- data/lib/dm-core/support/symbol.rb +41 -0
- data/lib/dm-core/transaction.rb +267 -0
- data/lib/dm-core/type.rb +160 -0
- data/lib/dm-core/type_map.rb +80 -0
- data/lib/dm-core/types.rb +19 -0
- data/lib/dm-core/types/boolean.rb +7 -0
- data/lib/dm-core/types/discriminator.rb +34 -0
- data/lib/dm-core/types/object.rb +24 -0
- data/lib/dm-core/types/paranoid_boolean.rb +34 -0
- data/lib/dm-core/types/paranoid_datetime.rb +33 -0
- data/lib/dm-core/types/serial.rb +9 -0
- data/lib/dm-core/types/text.rb +10 -0
- data/lib/dm-core/version.rb +3 -0
- data/script/all +5 -0
- data/script/performance.rb +203 -0
- data/script/profile.rb +87 -0
- data/spec/integration/association_spec.rb +1371 -0
- data/spec/integration/association_through_spec.rb +203 -0
- data/spec/integration/associations/many_to_many_spec.rb +449 -0
- data/spec/integration/associations/many_to_one_spec.rb +163 -0
- data/spec/integration/associations/one_to_many_spec.rb +151 -0
- data/spec/integration/auto_migrations_spec.rb +398 -0
- data/spec/integration/collection_spec.rb +1069 -0
- data/spec/integration/data_objects_adapter_spec.rb +32 -0
- data/spec/integration/dependency_queue_spec.rb +58 -0
- data/spec/integration/model_spec.rb +127 -0
- data/spec/integration/mysql_adapter_spec.rb +85 -0
- data/spec/integration/postgres_adapter_spec.rb +731 -0
- data/spec/integration/property_spec.rb +233 -0
- data/spec/integration/query_spec.rb +506 -0
- data/spec/integration/repository_spec.rb +57 -0
- data/spec/integration/resource_spec.rb +475 -0
- data/spec/integration/sqlite3_adapter_spec.rb +352 -0
- data/spec/integration/sti_spec.rb +208 -0
- data/spec/integration/strategic_eager_loading_spec.rb +138 -0
- data/spec/integration/transaction_spec.rb +75 -0
- data/spec/integration/type_spec.rb +271 -0
- data/spec/lib/logging_helper.rb +18 -0
- data/spec/lib/mock_adapter.rb +27 -0
- data/spec/lib/model_loader.rb +91 -0
- data/spec/lib/publicize_methods.rb +28 -0
- data/spec/models/vehicles.rb +34 -0
- data/spec/models/zoo.rb +47 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/unit/adapters/abstract_adapter_spec.rb +133 -0
- data/spec/unit/adapters/adapter_shared_spec.rb +15 -0
- data/spec/unit/adapters/data_objects_adapter_spec.rb +628 -0
- data/spec/unit/adapters/postgres_adapter_spec.rb +133 -0
- data/spec/unit/associations/many_to_many_spec.rb +17 -0
- data/spec/unit/associations/many_to_one_spec.rb +152 -0
- data/spec/unit/associations/one_to_many_spec.rb +393 -0
- data/spec/unit/associations/one_to_one_spec.rb +7 -0
- data/spec/unit/associations/relationship_spec.rb +71 -0
- data/spec/unit/associations_spec.rb +242 -0
- data/spec/unit/auto_migrations_spec.rb +111 -0
- data/spec/unit/collection_spec.rb +182 -0
- data/spec/unit/data_mapper_spec.rb +35 -0
- data/spec/unit/identity_map_spec.rb +126 -0
- data/spec/unit/is_spec.rb +80 -0
- data/spec/unit/migrator_spec.rb +33 -0
- data/spec/unit/model_spec.rb +339 -0
- data/spec/unit/naming_conventions_spec.rb +36 -0
- data/spec/unit/property_set_spec.rb +83 -0
- data/spec/unit/property_spec.rb +753 -0
- data/spec/unit/query_spec.rb +530 -0
- data/spec/unit/repository_spec.rb +93 -0
- data/spec/unit/resource_spec.rb +626 -0
- data/spec/unit/scope_spec.rb +142 -0
- data/spec/unit/transaction_spec.rb +493 -0
- data/spec/unit/type_map_spec.rb +114 -0
- data/spec/unit/type_spec.rb +119 -0
- data/tasks/ci.rb +68 -0
- data/tasks/dm.rb +63 -0
- data/tasks/doc.rb +20 -0
- data/tasks/gemspec.rb +23 -0
- data/tasks/hoe.rb +46 -0
- data/tasks/install.rb +20 -0
- metadata +216 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe "Strategic Eager Loading" do
|
4
|
+
include LoggingHelper
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
class Zoo
|
8
|
+
include DataMapper::Resource
|
9
|
+
def self.default_repository_name; ADAPTER end
|
10
|
+
|
11
|
+
property :id, Serial
|
12
|
+
property :name, String
|
13
|
+
|
14
|
+
has n, :exhibits
|
15
|
+
end
|
16
|
+
|
17
|
+
class Exhibit
|
18
|
+
include DataMapper::Resource
|
19
|
+
def self.default_repository_name; ADAPTER end
|
20
|
+
|
21
|
+
property :id, Serial
|
22
|
+
property :name, String
|
23
|
+
property :zoo_id, Integer
|
24
|
+
|
25
|
+
belongs_to :zoo
|
26
|
+
has n, :animals
|
27
|
+
end
|
28
|
+
|
29
|
+
class Animal
|
30
|
+
include DataMapper::Resource
|
31
|
+
def self.default_repository_name; ADAPTER end
|
32
|
+
|
33
|
+
property :id, Serial
|
34
|
+
property :name, String
|
35
|
+
property :exhibit_id, Integer
|
36
|
+
|
37
|
+
belongs_to :exhibit
|
38
|
+
end
|
39
|
+
|
40
|
+
[Zoo, Exhibit, Animal].each { |k| k.auto_migrate!(ADAPTER) }
|
41
|
+
|
42
|
+
repository(ADAPTER) do
|
43
|
+
Zoo.create(:name => "Dallas Zoo")
|
44
|
+
Exhibit.create(:name => "Primates", :zoo_id => 1)
|
45
|
+
Animal.create(:name => "Chimpanzee", :exhibit_id => 1)
|
46
|
+
Animal.create(:name => "Orangutan", :exhibit_id => 1)
|
47
|
+
|
48
|
+
Zoo.create(:name => "San Diego")
|
49
|
+
Exhibit.create(:name => "Aviary", :zoo_id => 2)
|
50
|
+
Exhibit.create(:name => "Insectorium", :zoo_id => 2)
|
51
|
+
Exhibit.create(:name => "Bears", :zoo_id => 2)
|
52
|
+
Animal.create(:name => "Bald Eagle", :exhibit_id => 2)
|
53
|
+
Animal.create(:name => "Parakeet", :exhibit_id => 2)
|
54
|
+
Animal.create(:name => "Roach", :exhibit_id => 3)
|
55
|
+
Animal.create(:name => "Brown Bear", :exhibit_id => 4)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should eager load children" do
|
60
|
+
zoo_ids = Zoo.all.map { |z| z.key }
|
61
|
+
exhibit_ids = Exhibit.all.map { |e| e.key }
|
62
|
+
|
63
|
+
repository(ADAPTER) do
|
64
|
+
zoos = Zoo.all.entries # load all zoos
|
65
|
+
dallas = zoos.find { |z| z.name == 'Dallas Zoo' }
|
66
|
+
|
67
|
+
dallas.exhibits.entries # load all exhibits for zoos in identity_map
|
68
|
+
dallas.exhibits.size.should == 1
|
69
|
+
repository.identity_map(Zoo).keys.sort.should == zoo_ids
|
70
|
+
repository.identity_map(Exhibit).keys.sort.should == exhibit_ids
|
71
|
+
|
72
|
+
logger do |log|
|
73
|
+
zoos.each { |zoo| zoo.exhibits.entries } # issues no queries
|
74
|
+
log.readlines.should be_empty
|
75
|
+
end
|
76
|
+
|
77
|
+
dallas.exhibits << Exhibit.new(:name => "Reptiles")
|
78
|
+
dallas.exhibits.size.should == 2
|
79
|
+
dallas.save
|
80
|
+
end
|
81
|
+
repository(ADAPTER) do
|
82
|
+
Zoo.first.exhibits.size.should == 2
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not eager load children when a query is provided" do
|
87
|
+
repository(ADAPTER) do
|
88
|
+
dallas = Zoo.all.entries.find { |z| z.name == 'Dallas Zoo' }
|
89
|
+
exhibits = dallas.exhibits.entries # load all exhibits
|
90
|
+
|
91
|
+
logger do |log|
|
92
|
+
reptiles = dallas.exhibits(:name => 'Reptiles')
|
93
|
+
reptiles.size.should == 1
|
94
|
+
|
95
|
+
primates = dallas.exhibits(:name => 'Primates')
|
96
|
+
primates.size.should == 1
|
97
|
+
primates.should_not == reptiles
|
98
|
+
|
99
|
+
log.readlines.size.should == 2
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should eager load parents" do
|
105
|
+
animal_ids = Animal.all.map { |a| a.key }
|
106
|
+
exhibit_ids = Exhibit.all.map { |e| e.key }.sort
|
107
|
+
exhibit_ids.pop # remove Reptile exhibit, which has no Animals
|
108
|
+
|
109
|
+
repository(ADAPTER) do
|
110
|
+
animals = Animal.all.entries
|
111
|
+
bear = animals.find { |a| a.name == 'Brown Bear' }
|
112
|
+
bear.exhibit
|
113
|
+
repository.identity_map(Animal).keys.sort.should == animal_ids
|
114
|
+
repository.identity_map(Exhibit).keys.sort.should == exhibit_ids
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not eager load parents when parent is in IM" do
|
119
|
+
repository(ADAPTER) do
|
120
|
+
animal = Animal.first
|
121
|
+
exhibit = Exhibit.get(1) # load exhibit into IM
|
122
|
+
|
123
|
+
logger do |log|
|
124
|
+
animal.exhibit # load exhibit from IM
|
125
|
+
log.readlines.should be_empty
|
126
|
+
end
|
127
|
+
repository.identity_map(Exhibit).keys.should == [exhibit.key]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should return a Collection when no children" do
|
132
|
+
Zoo.create(:name => 'Portland')
|
133
|
+
|
134
|
+
Zoo.all.each do |zoo|
|
135
|
+
zoo.exhibits.should be_kind_of(DataMapper::Collection)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
# transaction capable adapters
|
4
|
+
ADAPTERS = []
|
5
|
+
ADAPTERS << :postgres if HAS_POSTGRES
|
6
|
+
ADAPTERS << :mysql if HAS_MYSQL
|
7
|
+
ADAPTERS << :sqlite3 if HAS_SQLITE3
|
8
|
+
|
9
|
+
if ADAPTERS.any?
|
10
|
+
class Sputnik
|
11
|
+
include DataMapper::Resource
|
12
|
+
|
13
|
+
property :id, Serial
|
14
|
+
property :name, DM::Text
|
15
|
+
end
|
16
|
+
|
17
|
+
describe DataMapper::Transaction do
|
18
|
+
before :all do
|
19
|
+
@repositories = []
|
20
|
+
|
21
|
+
ADAPTERS.each do |name|
|
22
|
+
@repositories << repository(name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
before :each do
|
27
|
+
ADAPTERS.each do |name|
|
28
|
+
Sputnik.auto_migrate!(name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should commit changes to all involved adapters on a two phase commit" do
|
33
|
+
DataMapper::Transaction.new(*@repositories) do
|
34
|
+
ADAPTERS.each do |name|
|
35
|
+
repository(name) { Sputnik.create(:name => 'hepp') }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
ADAPTERS.each do |name|
|
40
|
+
repository(name) { Sputnik.all.size.should == 1 }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not commit any changes if the block raises an exception" do
|
45
|
+
lambda do
|
46
|
+
DataMapper::Transaction.new(*@repositories) do
|
47
|
+
ADAPTERS.each do |name|
|
48
|
+
repository(name) { Sputnik.create(:name => 'hepp') }
|
49
|
+
end
|
50
|
+
raise "plur"
|
51
|
+
end
|
52
|
+
end.should raise_error(Exception, /plur/)
|
53
|
+
|
54
|
+
ADAPTERS.each do |name|
|
55
|
+
repository(name) { Sputnik.all.size.should == 0 }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not commit any changes if any of the adapters doesnt prepare properly" do
|
60
|
+
lambda do
|
61
|
+
DataMapper::Transaction.new(*@repositories) do |transaction|
|
62
|
+
ADAPTERS.each do |name|
|
63
|
+
repository(name) { Sputnik.create(:name => 'hepp') }
|
64
|
+
end
|
65
|
+
|
66
|
+
transaction.primitive_for(@repositories.last.adapter).should_receive(:prepare).and_throw(Exception.new("I am the famous test exception"))
|
67
|
+
end
|
68
|
+
end.should raise_error(Exception, /I am the famous test exception/)
|
69
|
+
|
70
|
+
ADAPTERS.each do |name|
|
71
|
+
repository(name) { Sputnik.all.size.should == 0 }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
gem 'fastercsv', '>=1.2.3'
|
4
|
+
require 'fastercsv'
|
5
|
+
|
6
|
+
if ADAPTER
|
7
|
+
module TypeTests
|
8
|
+
class Impostor < DataMapper::Type
|
9
|
+
primitive String
|
10
|
+
end
|
11
|
+
|
12
|
+
class Coconut
|
13
|
+
include DataMapper::Resource
|
14
|
+
|
15
|
+
storage_names[ADAPTER] = 'coconuts'
|
16
|
+
|
17
|
+
def self.default_repository_name
|
18
|
+
ADAPTER
|
19
|
+
end
|
20
|
+
|
21
|
+
property :id, Serial
|
22
|
+
property :faked, Impostor
|
23
|
+
property :active, Boolean
|
24
|
+
property :note, Text
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Lemon
|
29
|
+
include DataMapper::Resource
|
30
|
+
|
31
|
+
def self.default_repository_name
|
32
|
+
ADAPTER
|
33
|
+
end
|
34
|
+
|
35
|
+
property :id, Serial
|
36
|
+
property :color, String
|
37
|
+
property :deleted_at, DataMapper::Types::ParanoidDateTime
|
38
|
+
end
|
39
|
+
|
40
|
+
class Lime
|
41
|
+
include DataMapper::Resource
|
42
|
+
|
43
|
+
def self.default_repository_name
|
44
|
+
ADAPTER
|
45
|
+
end
|
46
|
+
|
47
|
+
property :id, Serial
|
48
|
+
property :color, String
|
49
|
+
property :deleted_at, DataMapper::Types::ParanoidBoolean
|
50
|
+
end
|
51
|
+
|
52
|
+
describe DataMapper::Type, "with #{ADAPTER}" do
|
53
|
+
before do
|
54
|
+
TypeTests::Coconut.auto_migrate!(ADAPTER)
|
55
|
+
|
56
|
+
@document = <<-EOS.margin
|
57
|
+
NAME, RATING, CONVENIENCE
|
58
|
+
Freebird's, 3, 3
|
59
|
+
Whataburger, 1, 5
|
60
|
+
Jimmy John's, 3, 4
|
61
|
+
Mignon, 5, 2
|
62
|
+
Fuzi Yao's, 5, 1
|
63
|
+
Blue Goose, 5, 1
|
64
|
+
EOS
|
65
|
+
|
66
|
+
@stuff = YAML::dump({ 'Happy Cow!' => true, 'Sad Cow!' => false })
|
67
|
+
|
68
|
+
@active = true
|
69
|
+
@note = "This is a note on our ol' guy bob"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should instantiate an object with custom types" do
|
73
|
+
coconut = TypeTests::Coconut.new(:faked => 'bob', :active => @active, :note => @note)
|
74
|
+
coconut.faked.should == 'bob'
|
75
|
+
coconut.active.should be_a_kind_of(TrueClass)
|
76
|
+
coconut.note.should be_a_kind_of(String)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should CRUD an object with custom types" do
|
80
|
+
repository(ADAPTER) do
|
81
|
+
coconut = TypeTests::Coconut.new(:faked => 'bob', :active => @active, :note => @note)
|
82
|
+
coconut.save.should be_true
|
83
|
+
coconut.id.should_not be_nil
|
84
|
+
|
85
|
+
fred = TypeTests::Coconut.get!(coconut.id)
|
86
|
+
fred.faked.should == 'bob'
|
87
|
+
fred.active.should be_a_kind_of(TrueClass)
|
88
|
+
fred.note.should be_a_kind_of(String)
|
89
|
+
|
90
|
+
note = "Seems like bob is just mockin' around"
|
91
|
+
fred.note = note
|
92
|
+
|
93
|
+
fred.save.should be_true
|
94
|
+
|
95
|
+
active = false
|
96
|
+
fred.active = active
|
97
|
+
|
98
|
+
fred.save.should be_true
|
99
|
+
|
100
|
+
# Can't call coconut.reload since coconut.collection isn't setup.
|
101
|
+
mac = TypeTests::Coconut.get!(fred.id)
|
102
|
+
mac.active.should == active
|
103
|
+
mac.note.should == note
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should respect paranoia with a datetime" do
|
108
|
+
Lemon.auto_migrate!(ADAPTER)
|
109
|
+
|
110
|
+
lemon = nil
|
111
|
+
|
112
|
+
repository(ADAPTER) do |repository|
|
113
|
+
lemon = Lemon.new
|
114
|
+
lemon.color = 'green'
|
115
|
+
|
116
|
+
lemon.save
|
117
|
+
lemon.destroy
|
118
|
+
|
119
|
+
lemon.deleted_at.should be_kind_of(DateTime)
|
120
|
+
end
|
121
|
+
|
122
|
+
repository(ADAPTER) do |repository|
|
123
|
+
Lemon.all.should be_empty
|
124
|
+
Lemon.get(lemon.id).should be_nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should provide access to paranoid items with DateTime" do
|
129
|
+
Lemon.auto_migrate!(ADAPTER)
|
130
|
+
|
131
|
+
lemon = nil
|
132
|
+
|
133
|
+
repository(ADAPTER) do |repository|
|
134
|
+
%w(red green yellow blue).each do |color|
|
135
|
+
Lemon.create(:color => color)
|
136
|
+
end
|
137
|
+
|
138
|
+
Lemon.all.size.should == 4
|
139
|
+
Lemon.first.destroy
|
140
|
+
Lemon.all.size.should == 3
|
141
|
+
Lemon.with_deleted{Lemon.all.size.should == 1}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should set paranoid datetime to a date time" do
|
146
|
+
tmp = (DateTime.now - 0.5)
|
147
|
+
dt = DateTime.now
|
148
|
+
DateTime.stub!(:now).and_return(tmp)
|
149
|
+
|
150
|
+
repository(ADAPTER) do |repository|
|
151
|
+
lemon = Lemon.new
|
152
|
+
lemon.color = 'green'
|
153
|
+
lemon.save
|
154
|
+
lemon.destroy
|
155
|
+
lemon.deleted_at.should == tmp
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should respect paranoia with a boolean" do
|
160
|
+
Lime.auto_migrate!(ADAPTER)
|
161
|
+
|
162
|
+
lime = nil
|
163
|
+
|
164
|
+
repository(ADAPTER) do |repository|
|
165
|
+
lime = Lime.new
|
166
|
+
lime.color = 'green'
|
167
|
+
|
168
|
+
lime.save
|
169
|
+
lime.destroy
|
170
|
+
|
171
|
+
lime.deleted_at.should be_kind_of(TrueClass)
|
172
|
+
end
|
173
|
+
|
174
|
+
repository(ADAPTER) do |repository|
|
175
|
+
Lime.all.should be_empty
|
176
|
+
Lime.get(lime.id).should be_nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should provide access to paranoid items with Boolean" do
|
181
|
+
Lime.auto_migrate!(ADAPTER)
|
182
|
+
|
183
|
+
lemon = nil
|
184
|
+
|
185
|
+
repository(ADAPTER) do |repository|
|
186
|
+
%w(red green yellow blue).each do |color|
|
187
|
+
Lime.create(:color => color)
|
188
|
+
end
|
189
|
+
|
190
|
+
Lime.all.size.should == 4
|
191
|
+
Lime.first.destroy
|
192
|
+
Lime.all.size.should == 3
|
193
|
+
Lime.with_deleted{Lime.all.size.should == 1}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "paranoid types across repositories" do
|
198
|
+
before(:all) do
|
199
|
+
DataMapper::Repository.adapters[:alternate_paranoid] = repository(ADAPTER).adapter.dup
|
200
|
+
|
201
|
+
Object.send(:remove_const, :Orange) if defined?(Orange)
|
202
|
+
class Orange
|
203
|
+
include DataMapper::Resource
|
204
|
+
|
205
|
+
def self.default_repository_name
|
206
|
+
ADAPTER
|
207
|
+
end
|
208
|
+
|
209
|
+
property :id, Serial
|
210
|
+
property :color, String
|
211
|
+
|
212
|
+
repository(:alternate_paranoid) do
|
213
|
+
property :deleted, DataMapper::Types::ParanoidBoolean
|
214
|
+
property :deleted_at, DataMapper::Types::ParanoidDateTime
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
repository(:alternate_paranoid){Orange.auto_migrate!}
|
219
|
+
end
|
220
|
+
|
221
|
+
before(:each) do
|
222
|
+
%w(red orange blue green).each{|color| o = Orange.create(:color => color)}
|
223
|
+
end
|
224
|
+
|
225
|
+
after(:each) do
|
226
|
+
Orange.repository.adapter.execute("DELETE FROM oranges")
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should setup the correct objects for the spec" do
|
230
|
+
repository(:alternate_paranoid){Orange.all.should have(4).items}
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should allow access the the default repository" do
|
234
|
+
Orange.all.should have(4).items
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should mark the objects as deleted in the alternate_paranoid repository" do
|
238
|
+
repository(:alternate_paranoid) do
|
239
|
+
Orange.first.destroy
|
240
|
+
Orange.all.should have(3).items
|
241
|
+
Orange.find_by_sql("SELECT * FROM oranges").should have(4).items
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should mark the objects as deleted in the alternate_paranoid repository but ignore it in the #{ADAPTER} repository" do
|
246
|
+
repository(:alternate_paranoid) do
|
247
|
+
Orange.first.destroy
|
248
|
+
end
|
249
|
+
Orange.all.should have(4).items
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should raise an error when trying to destroy from a repository that is not paranoid" do
|
253
|
+
lambda do
|
254
|
+
Orange.first.destroy
|
255
|
+
end.should raise_error(ArgumentError)
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should set all paranoid attributes on delete" do
|
259
|
+
repository(:alternate_paranoid) do
|
260
|
+
orange = Orange.first
|
261
|
+
orange.deleted.should be_false
|
262
|
+
orange.deleted_at.should be_nil
|
263
|
+
orange.destroy
|
264
|
+
|
265
|
+
orange.deleted.should be_true
|
266
|
+
orange.deleted_at.should be_a_kind_of(DateTime)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|