ensured_schema 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile.lock +23 -0
  3. data/Rakefile +19 -0
  4. data/ensured_schema.gemspec +4 -0
  5. data/lib/ensured_schema/column.rb +9 -0
  6. data/lib/ensured_schema/ensured_table.rb +53 -0
  7. data/lib/ensured_schema/mysql_column.rb +17 -0
  8. data/lib/ensured_schema/schema.rb +7 -0
  9. data/lib/ensured_schema/schema_statements.rb +69 -0
  10. data/lib/ensured_schema/version.rb +1 -1
  11. data/lib/ensured_schema.rb +5 -155
  12. data/test/cases/ensured_schema_test.rb +206 -0
  13. data/test/cases/helper.rb +70 -0
  14. data/test/cases/migration_test.rb +1523 -0
  15. data/test/cases/repair_helper.rb +50 -0
  16. data/test/config.rb +5 -0
  17. data/test/connections/native_mysql/connection.rb +25 -0
  18. data/test/migrations/broken/100_migration_that_raises_exception.rb +10 -0
  19. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
  20. data/test/migrations/duplicate/1_people_have_last_names.rb +9 -0
  21. data/test/migrations/duplicate/2_we_need_reminders.rb +12 -0
  22. data/test/migrations/duplicate/3_foo.rb +7 -0
  23. data/test/migrations/duplicate/3_innocent_jointable.rb +12 -0
  24. data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
  25. data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
  26. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +12 -0
  27. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +9 -0
  28. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +12 -0
  29. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +9 -0
  30. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
  31. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
  32. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
  33. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  34. data/test/migrations/missing/3_we_need_reminders.rb +12 -0
  35. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  36. data/test/migrations/valid/1_people_have_last_names.rb +9 -0
  37. data/test/migrations/valid/2_we_need_reminders.rb +12 -0
  38. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  39. data/test/models/author.rb +146 -0
  40. data/test/models/auto_id.rb +4 -0
  41. data/test/models/binary.rb +2 -0
  42. data/test/models/bird.rb +3 -0
  43. data/test/models/book.rb +4 -0
  44. data/test/models/categorization.rb +5 -0
  45. data/test/models/category.rb +34 -0
  46. data/test/models/citation.rb +6 -0
  47. data/test/models/club.rb +13 -0
  48. data/test/models/column_name.rb +3 -0
  49. data/test/models/comment.rb +29 -0
  50. data/test/models/company.rb +171 -0
  51. data/test/models/company_in_module.rb +61 -0
  52. data/test/models/computer.rb +3 -0
  53. data/test/models/contact.rb +16 -0
  54. data/test/models/contract.rb +5 -0
  55. data/test/models/course.rb +3 -0
  56. data/test/models/customer.rb +73 -0
  57. data/test/models/default.rb +2 -0
  58. data/test/models/developer.rb +101 -0
  59. data/test/models/edge.rb +5 -0
  60. data/test/models/entrant.rb +3 -0
  61. data/test/models/essay.rb +3 -0
  62. data/test/models/event.rb +3 -0
  63. data/test/models/guid.rb +2 -0
  64. data/test/models/item.rb +7 -0
  65. data/test/models/job.rb +5 -0
  66. data/test/models/joke.rb +3 -0
  67. data/test/models/keyboard.rb +3 -0
  68. data/test/models/legacy_thing.rb +3 -0
  69. data/test/models/matey.rb +4 -0
  70. data/test/models/member.rb +12 -0
  71. data/test/models/member_detail.rb +5 -0
  72. data/test/models/member_type.rb +3 -0
  73. data/test/models/membership.rb +9 -0
  74. data/test/models/minimalistic.rb +2 -0
  75. data/test/models/mixed_case_monkey.rb +3 -0
  76. data/test/models/movie.rb +5 -0
  77. data/test/models/order.rb +4 -0
  78. data/test/models/organization.rb +6 -0
  79. data/test/models/owner.rb +5 -0
  80. data/test/models/parrot.rb +16 -0
  81. data/test/models/person.rb +16 -0
  82. data/test/models/pet.rb +5 -0
  83. data/test/models/pirate.rb +70 -0
  84. data/test/models/post.rb +100 -0
  85. data/test/models/price_estimate.rb +3 -0
  86. data/test/models/project.rb +30 -0
  87. data/test/models/reader.rb +4 -0
  88. data/test/models/reference.rb +4 -0
  89. data/test/models/reply.rb +46 -0
  90. data/test/models/ship.rb +10 -0
  91. data/test/models/ship_part.rb +5 -0
  92. data/test/models/sponsor.rb +4 -0
  93. data/test/models/subject.rb +4 -0
  94. data/test/models/subscriber.rb +8 -0
  95. data/test/models/subscription.rb +4 -0
  96. data/test/models/tag.rb +7 -0
  97. data/test/models/tagging.rb +10 -0
  98. data/test/models/task.rb +3 -0
  99. data/test/models/topic.rb +80 -0
  100. data/test/models/toy.rb +6 -0
  101. data/test/models/treasure.rb +8 -0
  102. data/test/models/vertex.rb +9 -0
  103. data/test/models/warehouse_thing.rb +5 -0
  104. data/test/schema/mysql_specific_schema.rb +24 -0
  105. data/test/schema/postgresql_specific_schema.rb +114 -0
  106. data/test/schema/schema.rb +493 -0
  107. data/test/schema/schema2.rb +6 -0
  108. data/test/schema/sqlite_specific_schema.rb +25 -0
  109. metadata +237 -7
@@ -0,0 +1,70 @@
1
+ class Pirate < ActiveRecord::Base
2
+ belongs_to :parrot, :validate => true
3
+ belongs_to :non_validated_parrot, :class_name => 'Parrot'
4
+ has_and_belongs_to_many :parrots, :validate => true
5
+ has_and_belongs_to_many :non_validated_parrots, :class_name => 'Parrot'
6
+ has_and_belongs_to_many :parrots_with_method_callbacks, :class_name => "Parrot",
7
+ :before_add => :log_before_add,
8
+ :after_add => :log_after_add,
9
+ :before_remove => :log_before_remove,
10
+ :after_remove => :log_after_remove
11
+ has_and_belongs_to_many :parrots_with_proc_callbacks, :class_name => "Parrot",
12
+ :before_add => proc {|p,pa| p.ship_log << "before_adding_proc_parrot_#{pa.id || '<new>'}"},
13
+ :after_add => proc {|p,pa| p.ship_log << "after_adding_proc_parrot_#{pa.id || '<new>'}"},
14
+ :before_remove => proc {|p,pa| p.ship_log << "before_removing_proc_parrot_#{pa.id}"},
15
+ :after_remove => proc {|p,pa| p.ship_log << "after_removing_proc_parrot_#{pa.id}"}
16
+
17
+ has_many :treasures, :as => :looter
18
+ has_many :treasure_estimates, :through => :treasures, :source => :price_estimates
19
+
20
+ # These both have :autosave enabled because accepts_nested_attributes_for is used on them.
21
+ has_one :ship
22
+ has_one :non_validated_ship, :class_name => 'Ship'
23
+ has_many :birds
24
+ has_many :birds_with_method_callbacks, :class_name => "Bird",
25
+ :before_add => :log_before_add,
26
+ :after_add => :log_after_add,
27
+ :before_remove => :log_before_remove,
28
+ :after_remove => :log_after_remove
29
+ has_many :birds_with_proc_callbacks, :class_name => "Bird",
30
+ :before_add => proc {|p,b| p.ship_log << "before_adding_proc_bird_#{b.id || '<new>'}"},
31
+ :after_add => proc {|p,b| p.ship_log << "after_adding_proc_bird_#{b.id || '<new>'}"},
32
+ :before_remove => proc {|p,b| p.ship_log << "before_removing_proc_bird_#{b.id}"},
33
+ :after_remove => proc {|p,b| p.ship_log << "after_removing_proc_bird_#{b.id}"}
34
+
35
+ accepts_nested_attributes_for :parrots, :birds, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
36
+ accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
37
+ accepts_nested_attributes_for :parrots_with_method_callbacks, :parrots_with_proc_callbacks,
38
+ :birds_with_method_callbacks, :birds_with_proc_callbacks, :allow_destroy => true
39
+
40
+ validates_presence_of :catchphrase
41
+
42
+ def ship_log
43
+ @ship_log ||= []
44
+ end
45
+
46
+ def reject_empty_ships_on_create(attributes)
47
+ attributes.delete('_reject_me_if_new').present? && new_record?
48
+ end
49
+
50
+ private
51
+ def log_before_add(record)
52
+ log(record, "before_adding_method")
53
+ end
54
+
55
+ def log_after_add(record)
56
+ log(record, "after_adding_method")
57
+ end
58
+
59
+ def log_before_remove(record)
60
+ log(record, "before_removing_method")
61
+ end
62
+
63
+ def log_after_remove(record)
64
+ log(record, "after_removing_method")
65
+ end
66
+
67
+ def log(record, callback)
68
+ ship_log << "#{callback}_#{record.class.name.downcase}_#{record.id || '<new>'}"
69
+ end
70
+ end
@@ -0,0 +1,100 @@
1
+ class Post < ActiveRecord::Base
2
+ named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
3
+ named_scope :ranked_by_comments, :order => "comments_count DESC"
4
+ named_scope :limit, lambda {|limit| {:limit => limit} }
5
+ named_scope :with_authors_at_address, lambda { |address| {
6
+ :conditions => [ 'authors.author_address_id = ?', address.id ],
7
+ :joins => 'JOIN authors ON authors.id = posts.author_id'
8
+ }
9
+ }
10
+
11
+ belongs_to :author do
12
+ def greeting
13
+ "hello"
14
+ end
15
+ end
16
+
17
+ belongs_to :author_with_posts, :class_name => "Author", :foreign_key => :author_id, :include => :posts
18
+ belongs_to :author_with_address, :class_name => "Author", :foreign_key => :author_id, :include => :author_address
19
+
20
+ has_one :last_comment, :class_name => 'Comment', :order => 'id desc'
21
+
22
+ named_scope :with_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'SpecialComment'} }
23
+ named_scope :with_very_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'VerySpecialComment'} }
24
+ named_scope :with_post, lambda {|post_id|
25
+ { :joins => :comments, :conditions => {:comments => {:post_id => post_id} } }
26
+ }
27
+
28
+ has_many :comments, :order => "body" do
29
+ def find_most_recent
30
+ find(:first, :order => "id DESC")
31
+ end
32
+ end
33
+
34
+ has_many :author_favorites, :through => :author
35
+
36
+ has_many :comments_with_interpolated_conditions, :class_name => 'Comment',
37
+ :conditions => ['#{"#{aliased_table_name}." rescue ""}body = ?', 'Thank you for the welcome']
38
+
39
+ has_one :very_special_comment
40
+ has_one :very_special_comment_with_post, :class_name => "VerySpecialComment", :include => :post
41
+ has_many :special_comments
42
+ has_many :nonexistant_comments, :class_name => 'Comment', :conditions => 'comments.id < 0'
43
+
44
+ has_and_belongs_to_many :categories
45
+ has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id'
46
+
47
+ has_many :taggings, :as => :taggable
48
+ has_many :tags, :through => :taggings do
49
+ def add_joins_and_select
50
+ find :all, :select => 'tags.*, authors.id as author_id', :include => false,
51
+ :joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
52
+ end
53
+ end
54
+
55
+ has_many :funky_tags, :through => :taggings, :source => :tag
56
+ has_many :super_tags, :through => :taggings
57
+ has_one :tagging, :as => :taggable
58
+
59
+ has_many :invalid_taggings, :as => :taggable, :class_name => "Tagging", :conditions => 'taggings.id < 0'
60
+ has_many :invalid_tags, :through => :invalid_taggings, :source => :tag
61
+
62
+ has_many :categorizations, :foreign_key => :category_id
63
+ has_many :authors, :through => :categorizations
64
+
65
+ has_many :readers
66
+ has_many :people, :through => :readers
67
+ has_many :people_with_callbacks, :source=>:person, :through => :readers,
68
+ :before_add => lambda {|owner, reader| log(:added, :before, reader.first_name) },
69
+ :after_add => lambda {|owner, reader| log(:added, :after, reader.first_name) },
70
+ :before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
71
+ :after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
72
+
73
+ def self.top(limit)
74
+ ranked_by_comments.limit(limit)
75
+ end
76
+
77
+ def self.reset_log
78
+ @log = []
79
+ end
80
+
81
+ def self.log(message=nil, side=nil, new_record=nil)
82
+ return @log if message.nil?
83
+ @log << [message, side, new_record]
84
+ end
85
+
86
+ def self.what_are_you
87
+ 'a post...'
88
+ end
89
+ end
90
+
91
+ class SpecialPost < Post; end
92
+
93
+ class StiPost < Post
94
+ self.abstract_class = true
95
+ has_one :special_comment, :class_name => "SpecialComment"
96
+ end
97
+
98
+ class SubStiPost < StiPost
99
+ self.table_name = Post.table_name
100
+ end
@@ -0,0 +1,3 @@
1
+ class PriceEstimate < ActiveRecord::Base
2
+ belongs_to :estimate_of, :polymorphic => true
3
+ end
@@ -0,0 +1,30 @@
1
+ class Project < ActiveRecord::Base
2
+ has_and_belongs_to_many :developers, :uniq => true, :order => 'developers.name desc, developers.id desc'
3
+ has_and_belongs_to_many :readonly_developers, :class_name => "Developer", :readonly => true
4
+ has_and_belongs_to_many :selected_developers, :class_name => "Developer", :select => "developers.*", :uniq => true
5
+ has_and_belongs_to_many :non_unique_developers, :order => 'developers.name desc, developers.id desc', :class_name => 'Developer'
6
+ has_and_belongs_to_many :limited_developers, :class_name => "Developer", :limit => 1
7
+ has_and_belongs_to_many :developers_named_david, :class_name => "Developer", :conditions => "name = 'David'", :uniq => true
8
+ has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name => "Developer", :conditions => { :name => 'David' }, :uniq => true
9
+ has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0"
10
+ has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
11
+ has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}"
12
+ has_and_belongs_to_many :developers_with_callbacks, :class_name => "Developer", :before_add => Proc.new {|o, r| o.developers_log << "before_adding#{r.id || '<new>'}"},
13
+ :after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id || '<new>'}"},
14
+ :before_remove => Proc.new {|o, r| o.developers_log << "before_removing#{r.id}"},
15
+ :after_remove => Proc.new {|o, r| o.developers_log << "after_removing#{r.id}"}
16
+ has_and_belongs_to_many :well_payed_salary_groups, :class_name => "Developer", :group => "developers.salary", :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary"
17
+
18
+ attr_accessor :developers_log
19
+
20
+ def after_initialize
21
+ @developers_log = []
22
+ end
23
+
24
+ end
25
+
26
+ class SpecialProject < Project
27
+ def hello_world
28
+ "hello there!"
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ class Reader < ActiveRecord::Base
2
+ belongs_to :post
3
+ belongs_to :person
4
+ end
@@ -0,0 +1,4 @@
1
+ class Reference < ActiveRecord::Base
2
+ belongs_to :person
3
+ belongs_to :job
4
+ end
@@ -0,0 +1,46 @@
1
+ require 'models/topic'
2
+
3
+ class Reply < Topic
4
+ named_scope :base
5
+
6
+ belongs_to :topic, :foreign_key => "parent_id", :counter_cache => true
7
+ belongs_to :topic_with_primary_key, :class_name => "Topic", :primary_key => "title", :foreign_key => "parent_title", :counter_cache => "replies_count"
8
+ has_many :replies, :class_name => "SillyReply", :dependent => :destroy, :foreign_key => "parent_id"
9
+
10
+ validate :errors_on_empty_content
11
+ validate_on_create :title_is_wrong_create
12
+
13
+ attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read, :parent_title
14
+
15
+ def validate
16
+ errors.add("title", "Empty") unless attribute_present? "title"
17
+ end
18
+
19
+ def errors_on_empty_content
20
+ errors.add("content", "Empty") unless attribute_present? "content"
21
+ end
22
+
23
+ def validate_on_create
24
+ if attribute_present?("title") && attribute_present?("content") && content == "Mismatch"
25
+ errors.add("title", "is Content Mismatch")
26
+ end
27
+ end
28
+
29
+ def title_is_wrong_create
30
+ errors.add("title", "is Wrong Create") if attribute_present?("title") && title == "Wrong Create"
31
+ end
32
+
33
+ def validate_on_update
34
+ errors.add("title", "is Wrong Update") if attribute_present?("title") && title == "Wrong Update"
35
+ end
36
+ end
37
+
38
+ class SillyReply < Reply
39
+ belongs_to :reply, :foreign_key => "parent_id", :counter_cache => :replies_count
40
+ end
41
+
42
+ module Web
43
+ class Reply < Web::Topic
44
+ belongs_to :topic, :foreign_key => "parent_id", :counter_cache => true, :class_name => 'Web::Topic'
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ class Ship < ActiveRecord::Base
2
+ self.record_timestamps = false
3
+
4
+ belongs_to :pirate
5
+ has_many :parts, :class_name => 'ShipPart', :autosave => true
6
+
7
+ accepts_nested_attributes_for :pirate, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
8
+
9
+ validates_presence_of :name
10
+ end
@@ -0,0 +1,5 @@
1
+ class ShipPart < ActiveRecord::Base
2
+ belongs_to :ship
3
+
4
+ validates_presence_of :name
5
+ end
@@ -0,0 +1,4 @@
1
+ class Sponsor < ActiveRecord::Base
2
+ belongs_to :sponsor_club, :class_name => "Club", :foreign_key => "club_id"
3
+ belongs_to :sponsorable, :polymorphic => true
4
+ end
@@ -0,0 +1,4 @@
1
+ # used for OracleSynonymTest, see test/synonym_test_oci.rb
2
+ #
3
+ class Subject < ActiveRecord::Base
4
+ end
@@ -0,0 +1,8 @@
1
+ class Subscriber < ActiveRecord::Base
2
+ set_primary_key 'nick'
3
+ has_many :subscriptions
4
+ has_many :books, :through => :subscriptions
5
+ end
6
+
7
+ class SpecialSubscriber < Subscriber
8
+ end
@@ -0,0 +1,4 @@
1
+ class Subscription < ActiveRecord::Base
2
+ belongs_to :subscriber
3
+ belongs_to :book
4
+ end
@@ -0,0 +1,7 @@
1
+ class Tag < ActiveRecord::Base
2
+ has_many :taggings
3
+ has_many :taggables, :through => :taggings
4
+ has_one :tagging
5
+
6
+ has_many :tagged_posts, :through => :taggings, :source => :taggable, :source_type => 'Post'
7
+ end
@@ -0,0 +1,10 @@
1
+ # test that attr_readonly isn't called on the :taggable polymorphic association
2
+ module Taggable
3
+ end
4
+
5
+ class Tagging < ActiveRecord::Base
6
+ belongs_to :tag, :include => :tagging
7
+ belongs_to :super_tag, :class_name => 'Tag', :foreign_key => 'super_tag_id'
8
+ belongs_to :invalid_tag, :class_name => 'Tag', :foreign_key => 'tag_id'
9
+ belongs_to :taggable, :polymorphic => true, :counter_cache => true
10
+ end
@@ -0,0 +1,3 @@
1
+ class Task < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,80 @@
1
+ class Topic < ActiveRecord::Base
2
+ named_scope :base
3
+ named_scope :written_before, lambda { |time|
4
+ if time
5
+ { :conditions => ['written_on < ?', time] }
6
+ end
7
+ }
8
+ named_scope :approved, :conditions => {:approved => true}
9
+ named_scope :rejected, :conditions => {:approved => false}
10
+
11
+ named_scope :by_lifo, :conditions => {:author_name => 'lifo'}
12
+
13
+ named_scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}}
14
+ named_scope 'approved_as_string', :conditions => {:approved => true}
15
+ named_scope :replied, :conditions => ['replies_count > 0']
16
+ named_scope :anonymous_extension do
17
+ def one
18
+ 1
19
+ end
20
+ end
21
+ module NamedExtension
22
+ def two
23
+ 2
24
+ end
25
+ end
26
+ module MultipleExtensionOne
27
+ def extension_one
28
+ 1
29
+ end
30
+ end
31
+ module MultipleExtensionTwo
32
+ def extension_two
33
+ 2
34
+ end
35
+ end
36
+ named_scope :named_extension, :extend => NamedExtension
37
+ named_scope :multiple_extensions, :extend => [MultipleExtensionTwo, MultipleExtensionOne]
38
+
39
+ has_many :replies, :dependent => :destroy, :foreign_key => "parent_id"
40
+ has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title"
41
+ serialize :content
42
+
43
+ before_create :default_written_on
44
+ before_destroy :destroy_children
45
+
46
+ def parent
47
+ Topic.find(parent_id)
48
+ end
49
+
50
+ # trivial method for testing Array#to_xml with :methods
51
+ def topic_id
52
+ id
53
+ end
54
+
55
+ protected
56
+ def approved=(val)
57
+ @custom_approved = val
58
+ write_attribute(:approved, val)
59
+ end
60
+
61
+ def default_written_on
62
+ self.written_on = Time.now unless attribute_present?("written_on")
63
+ end
64
+
65
+ def destroy_children
66
+ self.class.delete_all "parent_id = #{id}"
67
+ end
68
+
69
+ def after_initialize
70
+ if self.new_record?
71
+ self.author_email_address = 'test@test.com'
72
+ end
73
+ end
74
+ end
75
+
76
+ module Web
77
+ class Topic < ActiveRecord::Base
78
+ has_many :replies, :dependent => :destroy, :foreign_key => "parent_id", :class_name => 'Web::Reply'
79
+ end
80
+ end
@@ -0,0 +1,6 @@
1
+ class Toy < ActiveRecord::Base
2
+ set_primary_key :toy_id
3
+ belongs_to :pet
4
+
5
+ named_scope :with_name, lambda { |name| {:conditions => {:name => name}} }
6
+ end
@@ -0,0 +1,8 @@
1
+ class Treasure < ActiveRecord::Base
2
+ has_and_belongs_to_many :parrots
3
+ belongs_to :looter, :polymorphic => true
4
+
5
+ has_many :price_estimates, :as => :estimate_of
6
+
7
+ accepts_nested_attributes_for :looter
8
+ end
@@ -0,0 +1,9 @@
1
+ # This class models a vertex in a directed graph.
2
+ class Vertex < ActiveRecord::Base
3
+ has_many :sink_edges, :class_name => 'Edge', :foreign_key => 'source_id'
4
+ has_many :sinks, :through => :sink_edges
5
+
6
+ has_and_belongs_to_many :sources,
7
+ :class_name => 'Vertex', :join_table => 'edges',
8
+ :foreign_key => 'sink_id', :association_foreign_key => 'source_id'
9
+ end
@@ -0,0 +1,5 @@
1
+ class WarehouseThing < ActiveRecord::Base
2
+ set_table_name "warehouse-things"
3
+
4
+ validates_uniqueness_of :value
5
+ end
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :binary_fields, :force => true, :options => 'CHARACTER SET latin1' do |t|
3
+ t.binary :tiny_blob, :limit => 255
4
+ t.binary :normal_blob, :limit => 65535
5
+ t.binary :medium_blob, :limit => 16777215
6
+ t.binary :long_blob, :limit => 2147483647
7
+ t.text :tiny_text, :limit => 255
8
+ t.text :normal_text, :limit => 65535
9
+ t.text :medium_text, :limit => 16777215
10
+ t.text :long_text, :limit => 2147483647
11
+ end
12
+
13
+ ActiveRecord::Base.connection.execute <<-SQL
14
+ DROP PROCEDURE IF EXISTS ten;
15
+ SQL
16
+
17
+ ActiveRecord::Base.connection.execute <<-SQL
18
+ CREATE PROCEDURE ten() SQL SECURITY INVOKER
19
+ BEGIN
20
+ select 10;
21
+ END
22
+ SQL
23
+
24
+ end
@@ -0,0 +1,114 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ %w(postgresql_arrays postgresql_moneys postgresql_numbers postgresql_times postgresql_network_addresses postgresql_bit_strings
4
+ postgresql_oids postgresql_xml_data_type defaults geometrics).each do |table_name|
5
+ execute "DROP TABLE IF EXISTS #{quote_table_name table_name}"
6
+ end
7
+
8
+ execute 'DROP SEQUENCE IF EXISTS companies_nonstd_seq CASCADE'
9
+ execute 'CREATE SEQUENCE companies_nonstd_seq START 101 OWNED BY companies.id'
10
+ execute "ALTER TABLE companies ALTER COLUMN id SET DEFAULT nextval('companies_nonstd_seq')"
11
+ execute 'DROP SEQUENCE IF EXISTS companies_id_seq'
12
+
13
+ %w(accounts_id_seq developers_id_seq projects_id_seq topics_id_seq customers_id_seq orders_id_seq).each do |seq_name|
14
+ execute "SELECT setval('#{seq_name}', 100)"
15
+ end
16
+
17
+ execute <<_SQL
18
+ CREATE TABLE defaults (
19
+ id serial primary key,
20
+ modified_date date default CURRENT_DATE,
21
+ modified_date_function date default now(),
22
+ fixed_date date default '2004-01-01',
23
+ modified_time timestamp default CURRENT_TIMESTAMP,
24
+ modified_time_function timestamp default now(),
25
+ fixed_time timestamp default '2004-01-01 00:00:00.000000-00',
26
+ char1 char(1) default 'Y',
27
+ char2 character varying(50) default 'a varchar field',
28
+ char3 text default 'a text field',
29
+ positive_integer integer default 1,
30
+ negative_integer integer default -1,
31
+ decimal_number decimal(3,2) default 2.78,
32
+ multiline_default text DEFAULT '--- []
33
+
34
+ '::text
35
+ );
36
+ _SQL
37
+
38
+ execute <<_SQL
39
+ CREATE TABLE geometrics (
40
+ id serial primary key,
41
+ a_point point,
42
+ -- a_line line, (the line type is currently not implemented in postgresql)
43
+ a_line_segment lseg,
44
+ a_box box,
45
+ a_path path,
46
+ a_polygon polygon,
47
+ a_circle circle
48
+ );
49
+ _SQL
50
+
51
+ execute <<_SQL
52
+ CREATE TABLE postgresql_arrays (
53
+ id SERIAL PRIMARY KEY,
54
+ commission_by_quarter INTEGER[],
55
+ nicknames TEXT[]
56
+ );
57
+ _SQL
58
+ execute <<_SQL
59
+ CREATE TABLE postgresql_moneys (
60
+ id SERIAL PRIMARY KEY,
61
+ wealth MONEY
62
+ );
63
+ _SQL
64
+
65
+ execute <<_SQL
66
+ CREATE TABLE postgresql_numbers (
67
+ id SERIAL PRIMARY KEY,
68
+ single REAL,
69
+ double DOUBLE PRECISION
70
+ );
71
+ _SQL
72
+
73
+ execute <<_SQL
74
+ CREATE TABLE postgresql_times (
75
+ id SERIAL PRIMARY KEY,
76
+ time_interval INTERVAL
77
+ );
78
+ _SQL
79
+
80
+ execute <<_SQL
81
+ CREATE TABLE postgresql_network_addresses (
82
+ id SERIAL PRIMARY KEY,
83
+ cidr_address CIDR,
84
+ inet_address INET,
85
+ mac_address MACADDR
86
+ );
87
+ _SQL
88
+
89
+ execute <<_SQL
90
+ CREATE TABLE postgresql_bit_strings (
91
+ id SERIAL PRIMARY KEY,
92
+ bit_string BIT(8),
93
+ bit_string_varying BIT VARYING(8)
94
+ );
95
+ _SQL
96
+
97
+ execute <<_SQL
98
+ CREATE TABLE postgresql_oids (
99
+ id SERIAL PRIMARY KEY,
100
+ obj_id OID
101
+ );
102
+ _SQL
103
+
104
+ begin
105
+ execute <<_SQL
106
+ CREATE TABLE postgresql_xml_data_type (
107
+ id SERIAL PRIMARY KEY,
108
+ data xml
109
+ );
110
+ _SQL
111
+ rescue #This version of PostgreSQL either has no XML support or is was not compiled with XML support: skipping table
112
+ end
113
+ end
114
+