datamapper 0.2.4 → 0.2.5
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/CHANGELOG +16 -1
- data/README +10 -8
- data/environment.rb +1 -1
- data/example.rb +13 -5
- data/lib/data_mapper.rb +2 -0
- data/lib/data_mapper/adapters/abstract_adapter.rb +61 -0
- data/lib/data_mapper/adapters/data_object_adapter.rb +33 -6
- data/lib/data_mapper/adapters/mysql_adapter.rb +5 -0
- data/lib/data_mapper/adapters/postgresql_adapter.rb +12 -0
- data/lib/data_mapper/adapters/sql/commands/load_command.rb +6 -14
- data/lib/data_mapper/adapters/sql/mappings/column.rb +37 -26
- data/lib/data_mapper/adapters/sql/mappings/table.rb +50 -8
- data/lib/data_mapper/associations.rb +4 -5
- data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +2 -2
- data/lib/data_mapper/associations/has_many_association.rb +40 -13
- data/lib/data_mapper/associations/has_n_association.rb +1 -1
- data/lib/data_mapper/base.rb +5 -448
- data/lib/data_mapper/callbacks.rb +12 -2
- data/lib/data_mapper/context.rb +4 -0
- data/lib/data_mapper/database.rb +1 -1
- data/lib/data_mapper/identity_map.rb +2 -2
- data/lib/data_mapper/persistence.rb +538 -0
- data/lib/data_mapper/support/active_record_impersonation.rb +21 -3
- data/lib/data_mapper/support/errors.rb +2 -0
- data/lib/data_mapper/support/serialization.rb +7 -10
- data/lib/data_mapper/support/struct.rb +7 -0
- data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +11 -4
- data/performance.rb +23 -10
- data/rakefile.rb +1 -1
- data/spec/active_record_impersonation_spec.rb +2 -6
- data/spec/acts_as_tree_spec.rb +3 -1
- data/spec/associations_spec.rb +40 -160
- data/spec/attributes_spec.rb +1 -1
- data/spec/base_spec.rb +41 -13
- data/spec/callbacks_spec.rb +32 -0
- data/spec/coersion_spec.rb +1 -1
- data/spec/column_spec.rb +22 -12
- data/spec/dependency_spec.rb +5 -3
- data/spec/embedded_value_spec.rb +33 -17
- data/spec/has_many_association_spec.rb +173 -0
- data/spec/legacy_spec.rb +2 -2
- data/spec/load_command_spec.rb +59 -7
- data/spec/models/animal.rb +6 -2
- data/spec/models/animals_exhibit.rb +3 -1
- data/spec/models/career.rb +2 -1
- data/spec/models/comment.rb +3 -1
- data/spec/models/exhibit.rb +3 -1
- data/spec/models/fruit.rb +3 -1
- data/spec/models/person.rb +10 -1
- data/spec/models/post.rb +3 -1
- data/spec/models/project.rb +3 -1
- data/spec/models/section.rb +3 -1
- data/spec/models/serializer.rb +3 -1
- data/spec/models/user.rb +3 -1
- data/spec/models/zoo.rb +3 -1
- data/spec/paranoia_spec.rb +3 -1
- data/spec/postgres_spec.rb +54 -0
- data/spec/save_command_spec.rb +9 -5
- data/spec/schema_spec.rb +0 -91
- data/spec/single_table_inheritance_spec.rb +8 -0
- data/spec/table_spec.rb +46 -0
- data/spec/validates_uniqueness_of_spec.rb +19 -1
- metadata +8 -10
- data/lib/data_mapper/associations/has_one_association.rb +0 -77
- data/plugins/dataobjects/do_rb +0 -0
data/spec/legacy_spec.rb
CHANGED
@@ -8,8 +8,8 @@ describe 'Legacy mappings' do
|
|
8
8
|
|
9
9
|
it('should allow custom foreign-key mappings') do
|
10
10
|
database do
|
11
|
-
Fruit
|
12
|
-
Animal
|
11
|
+
Fruit.first(:name => 'Watermelon').devourer_of_souls.should == Animal.first(:name => 'Cup')
|
12
|
+
Animal.first(:name => 'Cup').favourite_fruit.should == Fruit.first(:name => 'Watermelon')
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
data/spec/load_command_spec.rb
CHANGED
@@ -5,6 +5,11 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
5
5
|
before(:all) do
|
6
6
|
fixtures(:zoos)
|
7
7
|
fixtures(:animals)
|
8
|
+
fixtures(:people)
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
fixtures(:people)
|
8
13
|
end
|
9
14
|
|
10
15
|
def loader_for(klass, options = {})
|
@@ -109,7 +114,7 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
109
114
|
zebra = Animal.first(:name => 'Zebra')
|
110
115
|
zebra.name.should == 'Zebra'
|
111
116
|
|
112
|
-
elephant = Animal
|
117
|
+
elephant = Animal.first(:name => 'Elephant')
|
113
118
|
elephant.name.should == 'Elephant'
|
114
119
|
|
115
120
|
aged = Person.all(:age => 29)
|
@@ -122,18 +127,18 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
122
127
|
|
123
128
|
it 'should not find deleted objects' do
|
124
129
|
database do
|
125
|
-
wally = Animal
|
130
|
+
wally = Animal.first(:name => 'Whale')
|
126
131
|
wally.new_record?.should == false
|
127
132
|
wally.destroy!.should == true
|
128
133
|
|
129
|
-
wallys_evil_twin = Animal
|
134
|
+
wallys_evil_twin = Animal.first(:name => 'Whale')
|
130
135
|
wallys_evil_twin.should == nil
|
131
136
|
|
132
137
|
wally.new_record?.should == true
|
133
138
|
wally.save
|
134
139
|
wally.new_record?.should == false
|
135
140
|
|
136
|
-
Animal
|
141
|
+
Animal.first(:name => 'Whale').should == wally
|
137
142
|
end
|
138
143
|
end
|
139
144
|
|
@@ -160,6 +165,22 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
160
165
|
Zoo.find(1).should be_a_kind_of(Zoo)
|
161
166
|
end
|
162
167
|
|
168
|
+
# TICKET: http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/90
|
169
|
+
it "should return a CLEAN object" do
|
170
|
+
Animal[2].should_not be_dirty
|
171
|
+
Animal.first(:name => 'Cup').should_not be_dirty
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should retrieve altered integer columns correctly" do
|
175
|
+
pending "see http://wm.lighthouseapp.com/projects/4819-datamapper/tickets/95"
|
176
|
+
sam = Person.first
|
177
|
+
sam.age = 6471561394
|
178
|
+
sam.save
|
179
|
+
sam.reload
|
180
|
+
sam.original_values[:age].should == 6471561394
|
181
|
+
sam.age.should == 6471561394
|
182
|
+
end
|
183
|
+
|
163
184
|
it "should be able to search on UTF-8 strings" do
|
164
185
|
Zoo.create(:name => 'Danish Vowels: Smoot!') # øø
|
165
186
|
Zoo.first(:name.like => '%Smoot%').should be_a_kind_of(Zoo)
|
@@ -175,9 +196,11 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
175
196
|
end
|
176
197
|
|
177
198
|
# See the comment in dataobjects_spec for why this is failing
|
178
|
-
|
179
|
-
|
180
|
-
|
199
|
+
unless ENV["ADAPTER"] == "mysql"
|
200
|
+
it "should return nil when finding by id, and the id is not present and/or invalid" do
|
201
|
+
Zoo.find(nil).should be_nil
|
202
|
+
end
|
203
|
+
end
|
181
204
|
|
182
205
|
it "should return in order" do
|
183
206
|
fixtures(:posts)
|
@@ -188,6 +211,35 @@ describe DataMapper::Adapters::Sql::Commands::LoadCommand do
|
|
188
211
|
two.title.should eql('Two')
|
189
212
|
one.next.next.previous.previous.next.previous.next.next.title.should eql('Three')
|
190
213
|
end
|
214
|
+
|
215
|
+
it "should iterate in batches" do
|
216
|
+
|
217
|
+
total = Animal.count
|
218
|
+
count = 0
|
219
|
+
|
220
|
+
Animal.each(:name.not => nil) do |animal|
|
221
|
+
count += 1
|
222
|
+
end
|
223
|
+
|
224
|
+
count.should == total
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should get the right object back" do
|
228
|
+
a = Animal.first(:name => 'Cup')
|
229
|
+
Animal.get(a.id).should == a
|
230
|
+
|
231
|
+
b = Person.first(:name => 'Amy')
|
232
|
+
Person.get(b.id).should == b
|
233
|
+
|
234
|
+
c = Person.first(:name => 'Bob')
|
235
|
+
Person.get(c.id).should == c
|
236
|
+
|
237
|
+
database.execute("UPDATE people SET type = ? WHERE name = ?", nil, "Bob")
|
238
|
+
|
239
|
+
d = Person.first(:name => 'Bob')
|
240
|
+
Person.get(d.id).should == d
|
241
|
+
end
|
242
|
+
|
191
243
|
end
|
192
244
|
|
193
245
|
=begin
|
data/spec/models/animal.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
-
class Animal
|
2
|
-
|
1
|
+
class Animal #< DataMapper::Base
|
2
|
+
include DataMapper::Persistence
|
3
|
+
|
4
|
+
property :name, :string, :default => "No Name", :index => :unique
|
3
5
|
property :notes, :text
|
4
6
|
property :nice, :boolean
|
5
7
|
|
6
8
|
has_one :favourite_fruit, :class => 'Fruit', :foreign_key => 'devourer_id'
|
7
9
|
has_and_belongs_to_many :exhibits
|
10
|
+
|
11
|
+
DEFAULT_LIMIT = 5
|
8
12
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# This is just here to get around the fact I use a Class to load
|
2
2
|
# fixtures right now.
|
3
|
-
class AnimalsExhibit
|
3
|
+
class AnimalsExhibit #< DataMapper::Base
|
4
|
+
include DataMapper::Persistence
|
5
|
+
|
4
6
|
property :animal_id, :integer, :key => true
|
5
7
|
property :exhibit_id, :integer, :key => true
|
6
8
|
end
|
data/spec/models/career.rb
CHANGED
data/spec/models/comment.rb
CHANGED
data/spec/models/exhibit.rb
CHANGED
data/spec/models/fruit.rb
CHANGED
data/spec/models/person.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
class Person
|
1
|
+
class Person #< DataMapper::Base
|
2
|
+
include DataMapper::Persistence
|
3
|
+
|
2
4
|
property :name, :string
|
3
5
|
property :age, :integer
|
4
6
|
property :occupation, :string
|
@@ -19,4 +21,11 @@ class Person < DataMapper::Base
|
|
19
21
|
end
|
20
22
|
|
21
23
|
belongs_to :career
|
24
|
+
|
25
|
+
before_save :before_save_callback
|
26
|
+
|
27
|
+
def before_save_callback
|
28
|
+
@notes = "Lorem ipsum dolor sit amet"
|
29
|
+
end
|
30
|
+
|
22
31
|
end
|
data/spec/models/post.rb
CHANGED
data/spec/models/project.rb
CHANGED
data/spec/models/section.rb
CHANGED
data/spec/models/serializer.rb
CHANGED
data/spec/models/user.rb
CHANGED
data/spec/models/zoo.rb
CHANGED
data/spec/paranoia_spec.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
# Only run these specs when the ADAPTER env-variable is set to 'postgresql'
|
4
|
+
# You will probably need to set the DATABASE and USERNAME vars as well.
|
5
|
+
if ENV['ADAPTER'] == 'postgresql'
|
6
|
+
|
7
|
+
describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Column do
|
8
|
+
it "should be able to set check-constraints on columns" do
|
9
|
+
mappings = DataMapper::Adapters::PostgresqlAdapter::Mappings
|
10
|
+
table = mappings::Table.new(database(:mock).adapter, "Zebu")
|
11
|
+
column = mappings::Column.new(database(:mock).adapter, table, :age,
|
12
|
+
:integer, 1, { :check => "age > 18"})
|
13
|
+
column.to_long_form.should match(/CHECK \(age > 18\)/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Table do
|
18
|
+
|
19
|
+
before(:all) do
|
20
|
+
class Cage < DataMapper::Base
|
21
|
+
set_table_name "cages"
|
22
|
+
property :name, :string
|
23
|
+
end
|
24
|
+
|
25
|
+
class CageInSchema < DataMapper::Base
|
26
|
+
set_table_name "my_schema.cages"
|
27
|
+
property :name, :string
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return a quoted table name for a simple table" do
|
32
|
+
table_sql = database.adapter.table(Cage).to_sql
|
33
|
+
table_sql.should == "\"cages\""
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return a quoted schema and table name for a table which specifies a schema" do
|
37
|
+
table_sql = database.adapter.table(CageInSchema).to_sql
|
38
|
+
table_sql.should == "\"my_schema\".\"cages\""
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should search only the specified schema if qualified" do
|
42
|
+
database.save(Cage)
|
43
|
+
database.adapter.table(CageInSchema).exists?.should == false
|
44
|
+
database.save(CageInSchema)
|
45
|
+
database.adapter.table(CageInSchema).exists?.should == true
|
46
|
+
end
|
47
|
+
|
48
|
+
after do
|
49
|
+
database.adapter.execute("DROP SCHEMA my_schema CASCADE") rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/spec/save_command_spec.rb
CHANGED
@@ -2,16 +2,20 @@ require File.dirname(__FILE__) + "/spec_helper"
|
|
2
2
|
|
3
3
|
describe "Save Commands" do
|
4
4
|
|
5
|
+
before(:all) do
|
6
|
+
fixtures(:zoos)
|
7
|
+
end
|
8
|
+
|
5
9
|
it "should create a new row" do
|
6
10
|
total = Zoo.all.length
|
7
11
|
Zoo.create({ :name => 'bob' })
|
8
|
-
zoo = Zoo
|
12
|
+
zoo = Zoo.first(:name => 'bob')
|
9
13
|
zoo.name.should == 'bob'
|
10
14
|
Zoo.all.length.should == total+1
|
11
15
|
end
|
12
16
|
|
13
17
|
it "should update an existing row" do
|
14
|
-
dallas = Zoo
|
18
|
+
dallas = Zoo.first(:name => 'Dallas')
|
15
19
|
dallas.name = 'bob'
|
16
20
|
dallas.save
|
17
21
|
dallas.name = 'Dallas'
|
@@ -25,15 +29,15 @@ describe "Save Commands" do
|
|
25
29
|
|
26
30
|
it "should stamp association on save" do
|
27
31
|
database do
|
28
|
-
dallas = Zoo
|
32
|
+
dallas = Zoo.first(:name => 'Dallas')
|
29
33
|
dallas.exhibits << Exhibit.new(:name => 'Flying Monkeys')
|
30
34
|
dallas.save
|
31
|
-
Exhibit
|
35
|
+
Exhibit.first(:name => 'Flying Monkeys').zoo.should == dallas
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
39
|
it "should be invalid if invalid associations are loaded" do
|
36
|
-
miami = Zoo
|
40
|
+
miami = Zoo.first(:name => 'Miami')
|
37
41
|
fish_fancy = Exhibit.new
|
38
42
|
miami.exhibits << fish_fancy
|
39
43
|
miami.should_not be_valid
|
data/spec/schema_spec.rb
CHANGED
@@ -6,94 +6,3 @@ describe DataMapper::Adapters::Sql::Mappings::Schema do
|
|
6
6
|
database.adapter.schema.database_tables.each { |table| table.should be_a_kind_of( DataMapper::Adapters::Sql::Mappings::Table ) }
|
7
7
|
end
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
|
-
if ENV['ADAPTER'] == 'postgresql' && false
|
12
|
-
|
13
|
-
describe DataMapper::Adapters::PostgresqlAdapter::Mappings::Table do
|
14
|
-
|
15
|
-
before(:all) do
|
16
|
-
class Cage < DataMapper::Base
|
17
|
-
set_table_name "cages"
|
18
|
-
property :name, :string
|
19
|
-
end
|
20
|
-
|
21
|
-
class CageInSchema < DataMapper::Base
|
22
|
-
set_table_name "my_schema.cages"
|
23
|
-
property :name, :string
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return a quoted table name for a simple table" do
|
28
|
-
table_sql = database.adapter.table(Cage).to_sql
|
29
|
-
table_sql.should == "\"cages\""
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should return a quoted schema and table name for a table which specifies a schema" do
|
33
|
-
table_sql = database.adapter.table(CageInSchema).to_sql
|
34
|
-
table_sql.should == "\"my_schema\".\"cages\""
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should search only the specified schema if qualified" do
|
38
|
-
database.save(Cage)
|
39
|
-
database.adapter.table(CageInSchema).exists?.should == false
|
40
|
-
database.save(CageInSchema)
|
41
|
-
database.adapter.table(CageInSchema).exists?.should == true
|
42
|
-
end
|
43
|
-
|
44
|
-
after do
|
45
|
-
database.adapter.execute("DROP SCHEMA my_schema CASCADE") rescue nil
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
describe DataMapper::Adapters::PostgresqlAdapter::Commands::SaveCommand do
|
51
|
-
|
52
|
-
before(:all) do
|
53
|
-
class Cage < DataMapper::Base
|
54
|
-
set_table_name "cages"
|
55
|
-
property :name, :string
|
56
|
-
end
|
57
|
-
|
58
|
-
class CageInSchema < DataMapper::Base
|
59
|
-
set_table_name "my_schema.cages"
|
60
|
-
property :name, :string
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def table_mapping_for(klass)
|
65
|
-
database_context = database
|
66
|
-
DataMapper::Adapters::PostgresqlAdapter::Commands::SaveCommand.new(database_context.adapter, database_context, klass)
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should create a schema if it doesn't already exist" do
|
70
|
-
create_sql = table_mapping_for(CageInSchema).to_create_table_sql
|
71
|
-
create_sql.should == <<-EOS.compress_lines
|
72
|
-
CREATE SCHEMA "my_schema"; CREATE TABLE "my_schema"."cages" ("id" serial primary key, "name" varchar)
|
73
|
-
EOS
|
74
|
-
end
|
75
|
-
|
76
|
-
it "shouldn't create a schema if it exists" do
|
77
|
-
database.save(CageInSchema)
|
78
|
-
create_sql = table_mapping_for(CageInSchema).to_create_table_sql
|
79
|
-
create_sql.should == <<-EOS.compress_lines
|
80
|
-
CREATE TABLE "my_schema"."cages" ("id" serial primary key, "name" varchar)
|
81
|
-
EOS
|
82
|
-
end
|
83
|
-
|
84
|
-
it "basic crud should work in schemas" do
|
85
|
-
database.save(CageInSchema)
|
86
|
-
CageInSchema.find(:all).size.should == 0
|
87
|
-
CageInSchema.create({ :name => 'bob' })
|
88
|
-
CageInSchema.find(:all).size.should == 1
|
89
|
-
cage = CageInSchema.first(:name => 'bob')
|
90
|
-
cage.name.should == 'bob'
|
91
|
-
cage.destroy!.should == true
|
92
|
-
end
|
93
|
-
|
94
|
-
after do
|
95
|
-
database.adapter.execute("DROP SCHEMA my_schema CASCADE") rescue nil
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|