datamapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/CHANGELOG +2 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README +1 -0
  4. data/example.rb +25 -0
  5. data/lib/data_mapper.rb +30 -0
  6. data/lib/data_mapper/adapters/abstract_adapter.rb +229 -0
  7. data/lib/data_mapper/adapters/mysql_adapter.rb +171 -0
  8. data/lib/data_mapper/adapters/sqlite3_adapter.rb +189 -0
  9. data/lib/data_mapper/associations.rb +19 -0
  10. data/lib/data_mapper/associations/belongs_to_association.rb +111 -0
  11. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +100 -0
  12. data/lib/data_mapper/associations/has_many_association.rb +101 -0
  13. data/lib/data_mapper/associations/has_one_association.rb +107 -0
  14. data/lib/data_mapper/base.rb +160 -0
  15. data/lib/data_mapper/callbacks.rb +47 -0
  16. data/lib/data_mapper/database.rb +134 -0
  17. data/lib/data_mapper/extensions/active_record_impersonation.rb +69 -0
  18. data/lib/data_mapper/extensions/callback_helpers.rb +35 -0
  19. data/lib/data_mapper/identity_map.rb +21 -0
  20. data/lib/data_mapper/loaded_set.rb +45 -0
  21. data/lib/data_mapper/mappings/column.rb +78 -0
  22. data/lib/data_mapper/mappings/schema.rb +28 -0
  23. data/lib/data_mapper/mappings/table.rb +99 -0
  24. data/lib/data_mapper/queries/conditions.rb +141 -0
  25. data/lib/data_mapper/queries/connection.rb +34 -0
  26. data/lib/data_mapper/queries/create_table_statement.rb +38 -0
  27. data/lib/data_mapper/queries/delete_statement.rb +17 -0
  28. data/lib/data_mapper/queries/drop_table_statement.rb +17 -0
  29. data/lib/data_mapper/queries/insert_statement.rb +29 -0
  30. data/lib/data_mapper/queries/reader.rb +42 -0
  31. data/lib/data_mapper/queries/result.rb +19 -0
  32. data/lib/data_mapper/queries/select_statement.rb +103 -0
  33. data/lib/data_mapper/queries/table_exists_statement.rb +17 -0
  34. data/lib/data_mapper/queries/truncate_table_statement.rb +17 -0
  35. data/lib/data_mapper/queries/update_statement.rb +25 -0
  36. data/lib/data_mapper/session.rb +240 -0
  37. data/lib/data_mapper/support/blank_slate.rb +3 -0
  38. data/lib/data_mapper/support/connection_pool.rb +117 -0
  39. data/lib/data_mapper/support/enumerable.rb +27 -0
  40. data/lib/data_mapper/support/inflector.rb +329 -0
  41. data/lib/data_mapper/support/proc.rb +69 -0
  42. data/lib/data_mapper/support/string.rb +23 -0
  43. data/lib/data_mapper/support/symbol.rb +91 -0
  44. data/lib/data_mapper/support/weak_hash.rb +46 -0
  45. data/lib/data_mapper/unit_of_work.rb +38 -0
  46. data/lib/data_mapper/validations/confirmation_validator.rb +55 -0
  47. data/lib/data_mapper/validations/contextual_validations.rb +50 -0
  48. data/lib/data_mapper/validations/format_validator.rb +85 -0
  49. data/lib/data_mapper/validations/formats/email.rb +78 -0
  50. data/lib/data_mapper/validations/generic_validator.rb +27 -0
  51. data/lib/data_mapper/validations/length_validator.rb +75 -0
  52. data/lib/data_mapper/validations/required_field_validator.rb +47 -0
  53. data/lib/data_mapper/validations/unique_validator.rb +65 -0
  54. data/lib/data_mapper/validations/validation_errors.rb +34 -0
  55. data/lib/data_mapper/validations/validation_helper.rb +60 -0
  56. data/performance.rb +156 -0
  57. data/profile_data_mapper.rb +18 -0
  58. data/rakefile.rb +80 -0
  59. data/spec/basic_finder.rb +67 -0
  60. data/spec/belongs_to.rb +47 -0
  61. data/spec/fixtures/animals.yaml +32 -0
  62. data/spec/fixtures/exhibits.yaml +90 -0
  63. data/spec/fixtures/fruit.yaml +6 -0
  64. data/spec/fixtures/people.yaml +15 -0
  65. data/spec/fixtures/zoos.yaml +20 -0
  66. data/spec/has_and_belongs_to_many.rb +25 -0
  67. data/spec/has_many.rb +34 -0
  68. data/spec/legacy.rb +14 -0
  69. data/spec/models/animal.rb +7 -0
  70. data/spec/models/exhibit.rb +6 -0
  71. data/spec/models/fruit.rb +6 -0
  72. data/spec/models/person.rb +7 -0
  73. data/spec/models/post.rb +4 -0
  74. data/spec/models/sales_person.rb +4 -0
  75. data/spec/models/zoo.rb +5 -0
  76. data/spec/new_record.rb +24 -0
  77. data/spec/spec_helper.rb +61 -0
  78. data/spec/sub_select.rb +16 -0
  79. data/spec/symbolic_operators.rb +21 -0
  80. data/spec/validates_confirmation_of.rb +36 -0
  81. data/spec/validates_format_of.rb +61 -0
  82. data/spec/validates_length_of.rb +101 -0
  83. data/spec/validates_uniqueness_of.rb +45 -0
  84. data/spec/validations.rb +63 -0
  85. metadata +134 -0
@@ -0,0 +1,18 @@
1
+ require 'example'
2
+ require 'ruby-prof'
3
+
4
+ # RubyProf, making profiling Ruby pretty since 1899!
5
+ def profile(&b)
6
+ result = RubyProf.profile &b
7
+
8
+ printer = RubyProf::GraphHtmlPrinter.new(result)
9
+ File::open('profile_results.html', 'w+') do |file|
10
+ printer.print(file, 0)
11
+ end
12
+ end
13
+
14
+ profile do
15
+ 1000.times do
16
+ Zoo[:name => 'Galveston']
17
+ end
18
+ end
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rake'
4
+ require 'spec/rake/spectask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ task :default => 'test'
10
+
11
+ desc "Run specifications"
12
+ Spec::Rake::SpecTask.new('test') do |t|
13
+ t.spec_opts = [ '-rspec/spec_helper' ]
14
+ t.spec_files = FileList[ENV['FILES'] || 'spec/*.rb']
15
+ end
16
+
17
+ desc "Run comparison with ActiveRecord"
18
+ task :perf do
19
+ load 'performance.rb'
20
+ end
21
+
22
+ desc "Profile DataMapper"
23
+ task :profile do
24
+ load 'profile_data_mapper.rb'
25
+ end
26
+
27
+ PACKAGE_VERSION = '0.1.0'
28
+
29
+ PACKAGE_FILES = FileList[
30
+ 'README',
31
+ 'CHANGELOG',
32
+ 'MIT-LICENSE',
33
+ '*.rb',
34
+ 'lib/**/*.rb',
35
+ 'spec/**/*.{rb,yaml}'
36
+ ].to_a
37
+
38
+ PROJECT = 'datamapper'
39
+
40
+ desc "Generate Documentation"
41
+ rd = Rake::RDocTask.new do |rdoc|
42
+ rdoc.rdoc_dir = 'doc'
43
+ rdoc.title = "DataMapper -- An Object/Relational Mapper for Ruby"
44
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
45
+ rdoc.rdoc_files.include(PACKAGE_FILES.reject { |path| path =~ /^(spec|\w+\.rb)/ })
46
+ end
47
+
48
+ gem_spec = Gem::Specification.new do |s|
49
+ s.platform = Gem::Platform::RUBY
50
+ s.name = PROJECT
51
+ s.summary = "An Object/Relational Mapper for Ruby"
52
+ s.description = "It's ActiveRecord, but Faster, Better, Simpler."
53
+ s.version = PACKAGE_VERSION
54
+
55
+ s.authors = 'Sam Smoot'
56
+ s.email = 'ssmoot@gmail.com'
57
+ s.rubyforge_project = PROJECT
58
+ s.homepage = 'http://datamapper.org'
59
+
60
+ s.files = PACKAGE_FILES
61
+
62
+ s.require_path = 'lib'
63
+ s.requirements << 'none'
64
+ s.autorequire = 'data_mapper'
65
+
66
+ s.has_rdoc = true
67
+ s.rdoc_options << '--line-numbers' << '--inline-source' << '--main' << 'README'
68
+ s.extra_rdoc_files = rd.rdoc_files.reject { |path| path =~ /\.rb$/ }.to_a
69
+ end
70
+
71
+ Rake::GemPackageTask.new(gem_spec) do |p|
72
+ p.gem_spec = gem_spec
73
+ p.need_tar = true
74
+ p.need_zip = true
75
+ end
76
+
77
+ desc "Publish to RubyForge"
78
+ task :rubyforge => [ :rdoc, :gem ] do
79
+ Rake::SshDirPublisher.new(ENV['RUBYFORGE_USER'], "/var/www/gforge-projects/#{PROJECT}", 'doc').upload
80
+ end
@@ -0,0 +1,67 @@
1
+ context 'Finder' do
2
+
3
+ specify 'database-specific load should not fail' do
4
+
5
+ DataMapper::database do |db|
6
+ froggy = db.find(Animal, :first, :conditions => ['name = ?', 'Frog'])
7
+ froggy.name.should == 'Frog'
8
+ end
9
+
10
+ end
11
+
12
+ specify 'current-database load should not fail' do
13
+ froggy = DataMapper::database.find(Animal, :first).name.should == 'Frog'
14
+ end
15
+
16
+ specify 'load through ActiveRecord impersonation should not fail' do
17
+ Animal.find(:all).size.should == 16
18
+ end
19
+
20
+ specify 'load through Og impersonation should not fail' do
21
+ Animal.all.size.should == 16
22
+ end
23
+
24
+ specify ':conditions option should accept a hash' do
25
+ Animal.all(:conditions => { :name => 'Frog' }).size.should == 1
26
+ end
27
+
28
+ specify 'non-standard options should be considered part of the conditions' do
29
+ database.log.debug('non-standard options should be considered part of the conditions')
30
+ zebra = Animal.first(:name => 'Zebra')
31
+ zebra.name.should == 'Zebra'
32
+
33
+ elephant = Animal[:name => 'Elephant']
34
+ elephant.name.should == 'Elephant'
35
+
36
+ aged = Person.all(:age => 29)
37
+ aged.size.should == 2
38
+ aged.first.name.should == 'Sam'
39
+ aged.last.name.should == 'Bob'
40
+
41
+ fixtures(:animals)
42
+ end
43
+
44
+ specify 'should not find deleted objects' do
45
+ database do
46
+ wally = Animal[:name => 'Whale']
47
+ wally.destroy!.should == true
48
+
49
+ wallys_evil_twin = Animal[:name => 'Whale']
50
+ wallys_evil_twin.should == nil
51
+
52
+ wally.new_record?.should == true
53
+ wally.save
54
+
55
+ Animal[:name => 'Whale'].should == wally
56
+ end
57
+ end
58
+
59
+ specify 'lazy-loads should issue for whole sets' do
60
+ people = Person.all
61
+
62
+ people.each do |person|
63
+ person.notes
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,47 @@
1
+ context 'An Exhibit' do
2
+
3
+ setup do
4
+ @aviary = Exhibit[:name => 'Monkey Mayhem']
5
+ end
6
+
7
+ specify 'has a zoo association' do
8
+ @aviary.zoo.class.should == Zoo
9
+ Exhibit.new.zoo.should == nil
10
+ end
11
+
12
+ specify 'belongs to a zoo' do
13
+ database do |db|
14
+ @aviary.zoo.should == @aviary.session.find(Zoo, :first, :name => 'San Diego')
15
+ end
16
+ end
17
+
18
+ specify 'can build its zoo' do
19
+ database do |db|
20
+ e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
21
+ e.zoo.should == nil
22
+ e.build_zoo({:name => 'Monkey Zoo'})
23
+ e.zoo.class == Zoo
24
+ e.zoo.new_record?.should == true
25
+
26
+ # Need to get associations working properly before this works ....
27
+ e.save
28
+ end
29
+ end
30
+
31
+ specify 'can build its zoo' do
32
+ database do |db|
33
+ e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
34
+ e.zoo.should == nil
35
+ e.create_zoo({:name => 'Monkey Zoo'})
36
+ e.zoo.class == Zoo
37
+ e.zoo.new_record?.should == false
38
+ e.save
39
+ end
40
+ end
41
+
42
+ teardown do
43
+ fixtures('zoos')
44
+ fixtures('exhibits')
45
+ end
46
+
47
+ end
@@ -0,0 +1,32 @@
1
+ - name: Frog
2
+ notes: I am a Frog!
3
+ - name: Bear
4
+ notes: I am a Bear!
5
+ - name: Giraffe
6
+ notes: I am a Giraffe!
7
+ - name: Zebra
8
+ notes: I am a Zebra!
9
+ - name: Cow
10
+ notes: I am a Cow!
11
+ - name: Pig
12
+ notes: I am a Pig!
13
+ - name: Cup
14
+ notes: I am a Cup!
15
+ - name: Cat
16
+ notes: I am a Cat!
17
+ - name: Dog
18
+ notes: I am a Dog!
19
+ - name: Elephant
20
+ notes: I am a Elephant!
21
+ - name: Whale
22
+ notes: I am a Whale!
23
+ - name: Dolphin
24
+ notes: I am a Dolphin!
25
+ - name: Mouse
26
+ notes: I am a Mouse!
27
+ - name: Rat
28
+ notes: I am a Rat!
29
+ - name: Camel
30
+ notes: I am a Camel!
31
+ - name: Fox
32
+ notes: I am a Fox!
@@ -0,0 +1,90 @@
1
+ - name: Horses & Courses
2
+ zoo_id: 1
3
+ - name: Aviary
4
+ zoo_id: 1
5
+ - name: Polar Planet
6
+ zoo_id: 2
7
+ - name: Monkey Mayhem
8
+ zoo_id: 2
9
+ - name: Amazonia
10
+ zoo_id: 3
11
+ - name: Deep Blue Ocean
12
+ zoo_id: 3
13
+ - name: Fish Fight!
14
+ zoo_id: 3
15
+ - name: The Dolphin Show
16
+ zoo_id: 3
17
+ - name: Canal Life
18
+ zoo_id: 4
19
+ - name: The Reptile Pit
20
+ zoo_id: 4
21
+ - name: Kangaroo Exhibit
22
+ zoo_id: 4
23
+ - name: A Million Years Ago...
24
+ zoo_id: 5
25
+ - name: The Wild West
26
+ zoo_id: 5
27
+ - name: Tumble Weeds
28
+ zoo_id: 5
29
+ - name: Missisipi Mud
30
+ zoo_id: 6
31
+ - name: Craw-Daddy's of the Deep!
32
+ zoo_id: 6
33
+ - name: The Littlest Big City
34
+ zoo_id: 7
35
+ - name: Jellyfish On Parade
36
+ zoo_id: 8
37
+ - name: Sea-Life Among the Rigs
38
+ zoo_id: 8
39
+ - name: Monsters of the Rainforest
40
+ zoo_id: 8
41
+ - name: So You Wanna Be A Street-Kid?
42
+ zoo_id: 9
43
+ - name: Don't Feed the Hippies!
44
+ zoo_id: 9
45
+ - name: At the Equator
46
+ zoo_id: 10
47
+ - name: River Habitats
48
+ zoo_id: 10
49
+ - name: A Fiesta of Plant-life
50
+ zoo_id: 10
51
+ - name: Smog World!
52
+ zoo_id: 11
53
+ - name: Where Are They Now? Extinct Species Edition
54
+ zoo_id: 11
55
+ - name: The Fragile Eco-System of the Cheese-Steak
56
+ zoo_id: 12
57
+ - name: Rats!
58
+ zoo_id: 13
59
+ - name: Penguins on Wall St.
60
+ zoo_id: 13
61
+ - name: King of the Jungle
62
+ zoo_id: 13
63
+ - name: The World's Fish-Market
64
+ zoo_id: 14
65
+ - name: Water-World
66
+ zoo_id: 14
67
+ - name: Micro-sized Soft-shelled Crabs
68
+ zoo_id: 14
69
+ - name: Do Animals Like Coffee?
70
+ zoo_id: 14
71
+ - name: On A Clear Day...
72
+ zoo_id: 15
73
+ - name: Twenty Thousand Leagues Under the Sky
74
+ zoo_id: 15
75
+ - name: Closed for Renovation
76
+ zoo_id: 16
77
+ - name: Ducks!
78
+ zoo_id: 17
79
+ - name: Retired Animal Life
80
+ zoo_id: 18
81
+ - name: The Clean Side of the Gulf
82
+ zoo_id: 18
83
+ - name: The Complete History of Rice
84
+ zoo_id: 19
85
+ - name: Safari World
86
+ zoo_id: 19
87
+ - name: Of Mice & Men
88
+ zoo_id: 20
89
+ - name: Snakes!
90
+ zoo_id: 20
@@ -0,0 +1,6 @@
1
+ - name: Kiwi
2
+ devourer_id: 5
3
+ - name: Pear
4
+ devourer_id: 11
5
+ - name: Watermelon
6
+ devourer_id: 7
@@ -0,0 +1,15 @@
1
+ - name: Sam
2
+ age: 29
3
+ occupation: Programmer
4
+ - name: Amy
5
+ age: 28
6
+ occupation: Business Analyst Manager
7
+ - name: Scott
8
+ age: 25
9
+ occupation: Programmer
10
+ - name: Josh
11
+ age: 23
12
+ occupation: Supervisor
13
+ - name: Bob
14
+ age: 29
15
+ occupation: Peon
@@ -0,0 +1,20 @@
1
+ - name: Dallas
2
+ - name: San Diego
3
+ - name: Miami
4
+ - name: Ft. Lauderdale
5
+ - name: Ft. Worth
6
+ - name: New Orleans
7
+ - name: San Antonio
8
+ - name: Galveston
9
+ - name: Austin
10
+ - name: Brownsville
11
+ - name: Los Angeles
12
+ - name: Phillidelphia
13
+ - name: New York
14
+ - name: Seattle
15
+ - name: Houston
16
+ - name: Corpus Christi
17
+ - name: Sacramento
18
+ - name: Pensacola
19
+ - name: Santa Francisco
20
+ - name: Orlando
@@ -0,0 +1,25 @@
1
+ # context 'An Exhibit' do
2
+ #
3
+ # setup do
4
+ # @amazonia = Exhibit[:name => 'Amazonia']
5
+ # end
6
+ #
7
+ # specify 'has an animals association' do
8
+ # [@amazonia, Exhibit.new].each do |exhibit|
9
+ # exhibit.animals.class.should == DataMapper::Associations::HasAndBelongsToManyAssociation
10
+ # end
11
+ # end
12
+ #
13
+ # specify 'has many animals' do
14
+ # @amazonia.animals.size.should == 2
15
+ # end
16
+ #
17
+ # specify 'should load associations magically' do
18
+ # Exhibit.all.each do |exhibit|
19
+ # exhibit.animals.each do |animal|
20
+ # animal.exhibits.should.include?(exhibit)
21
+ # end
22
+ # end
23
+ # end
24
+ #
25
+ # end
@@ -0,0 +1,34 @@
1
+ describe DataMapper::Associations::HasManyAssociation do
2
+
3
+ before(:all) do
4
+ fixtures(:zoos)
5
+ fixtures(:exhibits)
6
+
7
+ @san_diego = Zoo[:name => 'San Diego']
8
+ @dallas = Zoo[:name => 'Dallas']
9
+ @miami = Zoo[:name => 'Miami']
10
+ end
11
+
12
+ it 'should expose a proxy for the accessor' do
13
+ [@miami, Zoo.new].each do |z|
14
+ z.exhibits.class.should == DataMapper::Associations::HasManyAssociation
15
+ end
16
+ end
17
+
18
+ it 'should lazily-load the association when Enumerable methods are called' do
19
+ database do |db|
20
+ @san_diego.exhibits.size.should == 2
21
+ @san_diego.exhibits.should include(@san_diego.session.find(Exhibit, :first, :name => 'Monkey Mayhem'))
22
+ end
23
+ end
24
+
25
+ it 'should eager-load associations for an entire set' do
26
+ zoos = Zoo.all
27
+ zoos.each do |zoo|
28
+ zoo.exhibits.each do |exhibit|
29
+ exhibit.zoo.should == zoo
30
+ end
31
+ end
32
+ end
33
+
34
+ end