pax_global_header00006660000000000000000000000064121517247730014523gustar00rootroot0000000000000052 comment=2b699b1ab5e70e2d9faa80a3a7db955ccb4c7a7b ruby-foreigner-1.4.1/000077500000000000000000000000001215172477300144655ustar00rootroot00000000000000ruby-foreigner-1.4.1/MIT-LICENSE000066400000000000000000000020541215172477300161220ustar00rootroot00000000000000Copyright (c) 2009 [name of plugin creator] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-foreigner-1.4.1/README.rdoc000066400000000000000000000042151215172477300162750ustar00rootroot00000000000000= Foreigner {}[http://travis-ci.org/matthuhiggins/foreigner] Foreigner introduces a few methods to your migrations for adding and removing foreign key constraints. It also dumps foreign keys to schema.rb. The following adapters are supported: * mysql2 * postgres * sqlite (foreign key methods are a no-op) == Installation Add the following to your Gemfile: gem 'foreigner' == API Examples Foreigner adds two methods to migrations. * add_foreign_key(from_table, to_table, options) * remove_foreign_key(from_table, options) (Options are documented in connection_adapters/abstract/schema_definitions.rb): For example, given the following model: class Comment < ActiveRecord::Base belongs_to :post end class Post < ActiveRecord::Base has_many :comments, dependent: :delete_all end You should add a foreign key in your migration: add_foreign_key(:comments, :posts) The :dependent option can be moved from the has_many definition to the foreign key: add_foreign_key(:comments, :posts, dependent: :delete) If the column is named article_id instead of post_id, use the :column option: add_foreign_key(:comments, :posts, column: 'article_id') A name can be specified for the foreign key constraint: add_foreign_key(:comments, :posts, name: 'comment_article_foreign_key') == Change Table Methods Foreigner adds extra methods to create_table and change_table. Create a new table with a foreign key: create_table :products do |t| t.string :name t.integer :factory_id t.foreign_key :factories end Add a missing foreign key to comments: change_table :comments do |t| t.foreign_key :posts, dependent: :delete end Remove an unwanted foreign key: change_table :comments do |t| t.remove_foreign_key :users end == Foreigner Add-ons * {immigrant}[https://github.com/jenseng/immigrant] - generate a migration that includes all missing foreign keys. * {sqlserver-foreigner}[https://github.com/cleblanc87/sqlserver-foreigner] - A plugin for SQL Server. == License Copyright (c) 2012 Matthew Higgins, released under the MIT license ruby-foreigner-1.4.1/Rakefile000066400000000000000000000006171215172477300161360ustar00rootroot00000000000000require 'rake' # begin # require 'bundler/setup' # rescue LoadError # puts 'You must `gem install bundler` and `bundle install` to run rake tasks' # end desc 'Default: run unit tests.' task :default => :test require 'rake/testtask' desc 'Test the foreigner plugin.' Rake::TestTask.new(:test) do |t| t.libs << 'lib' t.libs << 'test' t.pattern = 'test/**/*_test.rb' t.verbose = true end ruby-foreigner-1.4.1/checksums.yaml.gz000066400000000000000000000004151215172477300177550ustar00rootroot00000000000000‹Ÿ¬aQe;N@ Dûœ"²½»ö:='ð—Š¥âôl(¡´FOó<·ÛíòþöŠ÷ËõúYK{ØËÇ÷ý*ÔÓP7¯ÆèeËÔb{ ÷Â`=Ü/ó°¯_®o1_X†VÄœ*îAijX| Ðx¶.¤½–š-27©R˜0C¥l¤©à´•²fM`,G¡I•kž&Om {—ìNÏ*î)2l¢-rb%Tiv¤[4äï?›rW•J{'QQJ²W¸ŸåH5娳U=áìÇ (<¬ÝÒXå»OÖâ&ä:%Eùhçs6°ÏÖ@†+éòÄA,O¢ruby-foreigner-1.4.1/lib/000077500000000000000000000000001215172477300152335ustar00rootroot00000000000000ruby-foreigner-1.4.1/lib/foreigner.rb000066400000000000000000000021431215172477300175400ustar00rootroot00000000000000require 'active_support/all' module Foreigner extend ActiveSupport::Autoload autoload :Adapter autoload :SchemaDumper module ConnectionAdapters extend ActiveSupport::Autoload autoload :Sql2003 autoload_under 'abstract' do autoload :ForeignKeyDefinition autoload :SchemaDefinitions autoload :SchemaStatements autoload :Table autoload :TableDefinition end end module Migration autoload :CommandRecorder, 'foreigner/migration/command_recorder' end end Foreigner::Adapter.register 'mysql', 'foreigner/connection_adapters/mysql_adapter' Foreigner::Adapter.register 'mysql2', 'foreigner/connection_adapters/mysql2_adapter' Foreigner::Adapter.register 'jdbcmysql', 'foreigner/connection_adapters/mysql2_adapter' Foreigner::Adapter.register 'postgresql', 'foreigner/connection_adapters/postgresql_adapter' Foreigner::Adapter.register 'jdbcpostgresql', 'foreigner/connection_adapters/postgresql_adapter' Foreigner::Adapter.register 'sqlite3', 'foreigner/connection_adapters/noop_adapter' require 'foreigner/loader' require 'foreigner/railtie' if defined?(Rails) ruby-foreigner-1.4.1/lib/foreigner/000077500000000000000000000000001215172477300172135ustar00rootroot00000000000000ruby-foreigner-1.4.1/lib/foreigner/adapter.rb000066400000000000000000000012071215172477300211600ustar00rootroot00000000000000module Foreigner class Adapter class_attribute :registered self.registered = {} class << self def register(adapter_name, file_name) registered[adapter_name] = file_name end def load! if registered.key?(configured_name) require registered[configured_name] else p "Database adapter #{configured_name} not supported. Use:\n" + "Foreigner::Adapter.register '#{configured_name}', 'path/to/adapter'" end end def configured_name @configured_name ||= ActiveRecord::Base.connection_pool.spec.config[:adapter] end end end end ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/000077500000000000000000000000001215172477300232355ustar00rootroot00000000000000ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/000077500000000000000000000000001215172477300250405ustar00rootroot00000000000000ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/foreign_key_definition.rb000066400000000000000000000002251215172477300320750ustar00rootroot00000000000000module Foreigner module ConnectionAdapters class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc: end end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/schema_definitions.rb000066400000000000000000000005471215172477300312260ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module SchemaDefinitions def self.included(base) base::Table.class_eval do include Foreigner::ConnectionAdapters::Table end base::TableDefinition.class_eval do include Foreigner::ConnectionAdapters::TableDefinition end end end end end ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/schema_statements.rb000066400000000000000000000067701215172477300311060ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module SchemaStatements def self.included(base) base::AbstractAdapter.class_eval do include Foreigner::ConnectionAdapters::AbstractAdapter end end end module AbstractAdapter def create_table(table_name, *args, &block) definition = nil super do |td| definition = td # This is my trick to get the definition block.call(td) end definition.foreign_keys.each do |to_table, options_list| options_list.each do |options| add_foreign_key(table_name, to_table, options) end end end def supports_foreign_keys? false end # Adds a new foreign key to the +from_table+, referencing the primary key of +to_table+ # # The foreign key will be named after the from and to tables unless you pass # :name as an option. # # ===== Examples # ====== Creating a foreign key # add_foreign_key(:comments, :posts) # generates # ALTER TABLE `comments` ADD CONSTRAINT # `comments_post_id_fk` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) # # ====== Creating a named foreign key # add_foreign_key(:comments, :posts, name: 'comments_belongs_to_posts') # generates # ALTER TABLE `comments` ADD CONSTRAINT # `comments_belongs_to_posts` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) # # ====== Creating a cascading foreign_key on a custom column # add_foreign_key(:people, :people, column: 'best_friend_id', dependent: :nullify) # generates # ALTER TABLE `people` ADD CONSTRAINT # `people_best_friend_id_fk` FOREIGN KEY (`best_friend_id`) REFERENCES `people` (`id`) # ON DELETE SET NULL # # === Supported options # [:column] # Specify the column name on the from_table that references the to_table. By default this is guessed # to be the singular name of the to_table with "_id" suffixed. So a to_table of :posts will use "post_id" # as the default :column. # [:primary_key] # Specify the column name on the to_table that is referenced by this foreign key. By default this is # assumed to be "id". # [:name] # Specify the name of the foreign key constraint. This defaults to use from_table and foreign key column. # [:dependent] # If set to :delete, the associated records in from_table are deleted when records in to_table table are deleted. # If set to :nullify, the foreign key column is set to +NULL+. # [:options] # Any extra options you want appended to the foreign key definition. def add_foreign_key(from_table, to_table, options = {}) end # Remove the given foreign key from the table. # # ===== Examples # ====== Remove the suppliers_company_id_fk in the suppliers table. # remove_foreign_key :suppliers, :companies # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table. # remove_foreign_key :accounts, column: :branch_id # ====== Remove the foreign key named party_foreign_key in the accounts table. # remove_foreign_key :accounts, name: :party_foreign_key def remove_foreign_key(from_table, options) end # Return the foreign keys for the schema_dumper def foreign_keys(table_name) [] end end end end ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/table.rb000066400000000000000000000040601215172477300264540ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module Table extend ActiveSupport::Concern included do alias_method_chain :references, :foreign_keys end # Adds a new foreign key to the table. +to_table+ can be a single Symbol, or # an Array of Symbols. See SchemaStatements#add_foreign_key # # ===== Examples # ====== Creating a simple foreign key # t.foreign_key(:people) # ====== Defining the column # t.foreign_key(:people, column: :sender_id) # ====== Creating a named foreign key # t.foreign_key(:people, column: :sender_id, name: 'sender_foreign_key') # ====== Defining the column of the +to_table+. # t.foreign_key(:people, column: :sender_id, primary_key: :person_id) def foreign_key(to_table, options = {}) @base.add_foreign_key(@table_name, to_table, options) end # Remove the given foreign key from the table. # # ===== Examples # ====== Remove the suppliers_company_id_fk in the suppliers table. # change_table :suppliers do |t| # t.remove_foreign_key :companies # end # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table. # change_table :accounts do |t| # t.remove_foreign_key column: :branch_id # end # ====== Remove the foreign key named party_foreign_key in the accounts table. # change_table :accounts do |t| # t.remove_foreign_key name: :party_foreign_key # end def remove_foreign_key(options) @base.remove_foreign_key(@table_name, options) end # Deprecated def references_with_foreign_keys(*args) options = args.extract_options! if fk_options = options.delete(:foreign_key) p ActiveSupport::Deprecation.send(:deprecation_message, caller, ":foreign_key in t.references is deprecated. " \ "Use t.foreign_key instead") end references_without_foreign_keys(*(args.dup << options)) end end end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/abstract/table_definition.rb000066400000000000000000000004441215172477300306660ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module TableDefinition def foreign_key(to_table, options = {}) foreign_keys[to_table] ||= [] foreign_keys[to_table] << options end def foreign_keys @foreign_keys ||= {} end end end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/mysql2_adapter.rb000066400000000000000000000035511215172477300265150ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module Mysql2Adapter include Foreigner::ConnectionAdapters::Sql2003 def remove_foreign_key_sql(table, options) if Hash === options foreign_key_name = foreign_key_name(table, options[:column], options) else foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id") end "DROP FOREIGN KEY #{quote_column_name(foreign_key_name)}" end def foreign_keys(table_name) fk_info = select_all %{ SELECT fk.referenced_table_name as 'to_table' ,fk.referenced_column_name as 'primary_key' ,fk.column_name as 'column' ,fk.constraint_name as 'name' FROM information_schema.key_column_usage fk WHERE fk.referenced_column_name is not null AND fk.table_schema = '#{@config[:database]}' AND fk.table_name = '#{table_name}' } create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"] fk_info.map do |row| options = {:column => row['column'], :name => row['name'], :primary_key => row['primary_key']} if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .* ON DELETE (CASCADE|SET NULL|RESTRICT)/ options[:dependent] = case $1 when 'CASCADE' then :delete when 'SET NULL' then :nullify when 'RESTRICT' then :restrict end end ForeignKeyDefinition.new(table_name, row['to_table'], options) end end end end end [:Mysql2Adapter, :JdbcAdapter].each do |adapter| begin ActiveRecord::ConnectionAdapters.const_get(adapter).class_eval do include Foreigner::ConnectionAdapters::Mysql2Adapter end rescue end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/mysql_adapter.rb000066400000000000000000000001331215172477300264240ustar00rootroot00000000000000p "WARNING: Please upgrade to mysql2. The old mysql adapter is not supported by foreigner."ruby-foreigner-1.4.1/lib/foreigner/connection_adapters/noop_adapter.rb000066400000000000000000000001651215172477300262370ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module NoopAdapter # Used mainly for sqlite3 end end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/postgresql_adapter.rb000066400000000000000000000027541215172477300274750ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module PostgreSQLAdapter include Foreigner::ConnectionAdapters::Sql2003 def foreign_keys(table_name) fk_info = select_all %{ SELECT t2.relname AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confdeltype AS dependency FROM pg_constraint c JOIN pg_class t1 ON c.conrelid = t1.oid JOIN pg_class t2 ON c.confrelid = t2.oid JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid JOIN pg_namespace t3 ON c.connamespace = t3.oid WHERE c.contype = 'f' AND t1.relname = '#{table_name}' AND t3.nspname = ANY (current_schemas(false)) ORDER BY c.conname } fk_info.map do |row| options = {:column => row['column'], :name => row['name'], :primary_key => row['primary_key']} options[:dependent] = case row['dependency'] when 'c' then :delete when 'n' then :nullify when 'r' then :restrict end ForeignKeyDefinition.new(table_name, row['to_table'], options) end end end end end [:PostgreSQLAdapter, :JdbcAdapter].each do |adapter| begin ActiveRecord::ConnectionAdapters.const_get(adapter).class_eval do include Foreigner::ConnectionAdapters::PostgreSQLAdapter end rescue end endruby-foreigner-1.4.1/lib/foreigner/connection_adapters/sql2003.rb000066400000000000000000000042641215172477300246740ustar00rootroot00000000000000module Foreigner module ConnectionAdapters module Sql2003 def supports_foreign_keys? true end def drop_table(*args) options = args.extract_options! if options[:force] disable_referential_integrity { super } else super end end def add_foreign_key(from_table, to_table, options = {}) sql = "ALTER TABLE #{quote_table_name(from_table)} #{add_foreign_key_sql(from_table, to_table, options)}" execute(sql) end def add_foreign_key_sql(from_table, to_table, options = {}) column = options[:column] || "#{to_table.to_s.singularize}_id" foreign_key_name = foreign_key_name(from_table, column, options) primary_key = options[:primary_key] || "id" dependency = dependency_sql(options[:dependent]) sql = "ADD CONSTRAINT #{quote_column_name(foreign_key_name)} " + "FOREIGN KEY (#{quote_column_name(column)}) " + "REFERENCES #{quote_table_name(ActiveRecord::Migrator.proper_table_name(to_table))}(#{primary_key})" sql << " #{dependency}" if dependency.present? sql << " #{options[:options]}" if options[:options] sql end def remove_foreign_key(table, options) execute "ALTER TABLE #{quote_table_name(table)} #{remove_foreign_key_sql(table, options)}" end def remove_foreign_key_sql(table, options) if Hash === options foreign_key_name = foreign_key_name(table, options[:column], options) else foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id") end "DROP CONSTRAINT #{quote_column_name(foreign_key_name)}" end private def foreign_key_name(table, column, options = {}) if options[:name] options[:name] else "#{table}_#{column}_fk" end end def dependency_sql(dependency) case dependency when :nullify then "ON DELETE SET NULL" when :delete then "ON DELETE CASCADE" when :restrict then "ON DELETE RESTRICT" else "" end end end end endruby-foreigner-1.4.1/lib/foreigner/loader.rb000066400000000000000000000010351215172477300210050ustar00rootroot00000000000000module Foreigner def self.load ActiveRecord::ConnectionAdapters.module_eval do include Foreigner::ConnectionAdapters::SchemaStatements include Foreigner::ConnectionAdapters::SchemaDefinitions end ActiveRecord::SchemaDumper.class_eval do include Foreigner::SchemaDumper end if defined?(ActiveRecord::Migration::CommandRecorder) ActiveRecord::Migration::CommandRecorder.class_eval do include Foreigner::Migration::CommandRecorder end end Foreigner::Adapter.load! end endruby-foreigner-1.4.1/lib/foreigner/migration/000077500000000000000000000000001215172477300212045ustar00rootroot00000000000000ruby-foreigner-1.4.1/lib/foreigner/migration/command_recorder.rb000066400000000000000000000012201215172477300250270ustar00rootroot00000000000000module Foreigner module Migration module CommandRecorder def add_foreign_key(*args) record(:add_foreign_key, args) end def remove_foreign_key(*args) record(:remove_foreign_key, args) end def invert_add_foreign_key(args) from_table, to_table, add_options = *args add_options ||= {} if add_options[:name] options = {:name => add_options[:name]} elsif add_options[:column] options = {:column => add_options[:column]} else options = to_table end [:remove_foreign_key, [from_table, options]] end end end endruby-foreigner-1.4.1/lib/foreigner/railtie.rb000066400000000000000000000002761215172477300211760ustar00rootroot00000000000000module Foreigner class Railtie < Rails::Railtie initializer 'foreigner.load_adapter' do ActiveSupport.on_load :active_record do Foreigner.load end end end endruby-foreigner-1.4.1/lib/foreigner/schema_dumper.rb000066400000000000000000000041521215172477300223560ustar00rootroot00000000000000module Foreigner module SchemaDumper extend ActiveSupport::Concern included do alias_method_chain :tables, :foreign_keys end module ClassMethods def dump_foreign_key(foreign_key) statement_parts = [ ('add_foreign_key ' + remove_prefix_and_suffix(foreign_key.from_table).inspect) ] statement_parts << remove_prefix_and_suffix(foreign_key.to_table).inspect statement_parts << (':name => ' + foreign_key.options[:name].inspect) if foreign_key.options[:column] != "#{remove_prefix_and_suffix(foreign_key.to_table).singularize}_id" statement_parts << (':column => ' + foreign_key.options[:column].inspect) end if foreign_key.options[:primary_key] != 'id' statement_parts << (':primary_key => ' + foreign_key.options[:primary_key].inspect) end if foreign_key.options[:dependent].present? statement_parts << (':dependent => ' + foreign_key.options[:dependent].inspect) end statement_parts.join(', ') end def remove_prefix_and_suffix(table) table.gsub(/^(#{ActiveRecord::Base.table_name_prefix})(.+)(#{ActiveRecord::Base.table_name_suffix})$/, "\\2") end end def tables_with_foreign_keys(stream) tables_without_foreign_keys(stream) @connection.tables.sort.each do |table| next if ['schema_migrations', ignore_tables].flatten.any? do |ignored| case ignored when String; table == ignored when Regexp; table =~ ignored else raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.' end end foreign_keys(table, stream) end end private def foreign_keys(table_name, stream) if (foreign_keys = @connection.foreign_keys(table_name)).any? add_foreign_key_statements = foreign_keys.map do |foreign_key| ' ' + self.class.dump_foreign_key(foreign_key) end stream.puts add_foreign_key_statements.sort.join("\n") stream.puts end end end end ruby-foreigner-1.4.1/metadata.yml000066400000000000000000000057421215172477300170000ustar00rootroot00000000000000--- !ruby/object:Gem::Specification name: foreigner version: !ruby/object:Gem::Version version: 1.4.1 platform: ruby authors: - Matthew Higgins autorequire: bindir: bin cert_chain: [] date: 2013-04-07 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: activerecord requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.0.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.0.0 - !ruby/object:Gem::Dependency name: activerecord requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.1.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.1.0 description: Adds helpers to migrations and dumps foreign keys to schema.rb email: developer@matthewhiggins.com executables: [] extensions: [] extra_rdoc_files: - README.rdoc files: - MIT-LICENSE - Rakefile - README.rdoc - lib/foreigner/adapter.rb - lib/foreigner/connection_adapters/abstract/foreign_key_definition.rb - lib/foreigner/connection_adapters/abstract/schema_definitions.rb - lib/foreigner/connection_adapters/abstract/schema_statements.rb - lib/foreigner/connection_adapters/abstract/table.rb - lib/foreigner/connection_adapters/abstract/table_definition.rb - lib/foreigner/connection_adapters/mysql2_adapter.rb - lib/foreigner/connection_adapters/mysql_adapter.rb - lib/foreigner/connection_adapters/noop_adapter.rb - lib/foreigner/connection_adapters/postgresql_adapter.rb - lib/foreigner/connection_adapters/sql2003.rb - lib/foreigner/loader.rb - lib/foreigner/migration/command_recorder.rb - lib/foreigner/railtie.rb - lib/foreigner/schema_dumper.rb - lib/foreigner.rb - test/foreigner/adapter_test.rb - test/foreigner/connection_adapters/abstract/schema_statements_test.rb - test/foreigner/connection_adapters/abstract/table_definition_test.rb - test/foreigner/connection_adapters/mysql2_adapter_test.rb - test/foreigner/connection_adapters/mysql_adapter_test.rb - test/foreigner/connection_adapters/postgresql_adapter_test.rb - test/foreigner/connection_adapters/sql2003_test.rb - test/foreigner/migration/command_recorder_test.rb - test/foreigner/schema_dumper_test.rb - test/helper.rb homepage: http://github.com/matthuhiggins/foreigner licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.8.7 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.5 requirements: [] rubyforge_project: foreigner rubygems_version: 2.0.0 signing_key: specification_version: 4 summary: Foreign Keys for Rails test_files: [] ruby-foreigner-1.4.1/test/000077500000000000000000000000001215172477300154445ustar00rootroot00000000000000ruby-foreigner-1.4.1/test/foreigner/000077500000000000000000000000001215172477300174245ustar00rootroot00000000000000ruby-foreigner-1.4.1/test/foreigner/adapter_test.rb000066400000000000000000000004611215172477300224310ustar00rootroot00000000000000require 'helper' class Foreigner::AdapterTest < ActiveSupport::TestCase test "load" do Foreigner::Adapter.register 'foo', 'bar' Foreigner::Adapter.expects(:configured_name).at_least_once.returns('foo') Foreigner::Adapter.expects(:require).with('bar') Foreigner::Adapter.load! end endruby-foreigner-1.4.1/test/foreigner/connection_adapters/000077500000000000000000000000001215172477300234465ustar00rootroot00000000000000ruby-foreigner-1.4.1/test/foreigner/connection_adapters/abstract/000077500000000000000000000000001215172477300252515ustar00rootroot00000000000000ruby-foreigner-1.4.1/test/foreigner/connection_adapters/abstract/schema_statements_test.rb000066400000000000000000000001521215172477300323420ustar00rootroot00000000000000require 'helper' class Foreigner::ConnectionAdapters::SchemaStatementsTest < ActiveSupport::TestCase endruby-foreigner-1.4.1/test/foreigner/connection_adapters/abstract/table_definition_test.rb000066400000000000000000000012251215172477300321340ustar00rootroot00000000000000require 'helper' class Foreigner::ConnectionAdapters::TableDefinitionsTest < ActiveSupport::TestCase class TestDefinition include Foreigner::ConnectionAdapters::TableDefinition end test "foreign_key used once" do definition = TestDefinition.new definition.foreign_key :poops, and: :one; assert_equal [{ and: :one }], definition.foreign_keys[:poops] end test "foreign_key used twice" do definition = TestDefinition.new definition.foreign_key :nodes, column: :from_id definition.foreign_key :nodes, column: :to_id assert_equal [{ column: :from_id }, { column: :to_id }], definition.foreign_keys[:nodes] end endruby-foreigner-1.4.1/test/foreigner/connection_adapters/mysql2_adapter_test.rb000066400000000000000000000016041215172477300277620ustar00rootroot00000000000000require 'helper' require 'foreigner/connection_adapters/mysql2_adapter' class Foreigner::Mysql2AdapterTest < Foreigner::UnitTest class Mysql2Adapter include TestAdapterMethods include Foreigner::ConnectionAdapters::Mysql2Adapter end setup do @adapter = Mysql2Adapter.new end test 'remove_foreign_key_sql by table' do assert_equal( "DROP FOREIGN KEY `suppliers_company_id_fk`", @adapter.remove_foreign_key_sql(:suppliers, :companies) ) end test 'remove_foreign_key_sql by name' do assert_equal( "DROP FOREIGN KEY `belongs_to_supplier`", @adapter.remove_foreign_key_sql(:suppliers, :name => "belongs_to_supplier") ) end test 'remove_foreign_key_sql by column' do assert_equal( "DROP FOREIGN KEY `suppliers_ship_to_id_fk`", @adapter.remove_foreign_key_sql(:suppliers, :column => "ship_to_id") ) end endruby-foreigner-1.4.1/test/foreigner/connection_adapters/mysql_adapter_test.rb000066400000000000000000000004771215172477300277070ustar00rootroot00000000000000require 'helper' class Foreigner::MysqlAdapterTest < Foreigner::UnitTest test 'warning' do output = capture(:stdout) do require 'foreigner/connection_adapters/mysql_adapter' end assert_match /WARNING: Please upgrade to mysql2. The old mysql adapter is not supported by foreigner./, output end endruby-foreigner-1.4.1/test/foreigner/connection_adapters/postgresql_adapter_test.rb000066400000000000000000000003101215172477300307270ustar00rootroot00000000000000require 'helper' require 'foreigner/connection_adapters/postgresql_adapter' class Foreigner::PostgreSQLAdapterTest < Foreigner::UnitTest include Foreigner::ConnectionAdapters::PostgreSQLAdapter endruby-foreigner-1.4.1/test/foreigner/connection_adapters/sql2003_test.rb000066400000000000000000000066551215172477300261520ustar00rootroot00000000000000require 'helper' class Foreigner::Sql2003Test < Foreigner::UnitTest class TestAdapter include TestAdapterMethods include Foreigner::ConnectionAdapters::Sql2003 end setup do @adapter = TestAdapter.new end test 'drop_table without force' do @adapter.drop_table 'shoes' assert !@adapter.instance_variable_get(:@disable_referential_integrity) end test 'drop_table with force' do @adapter.drop_table 'shoes', force: true assert @adapter.instance_variable_get(:@disable_referential_integrity) end test 'add_without_options' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id)", @adapter.add_foreign_key(:employees, :companies) ) end test 'add_with_name' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `favorite_company_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id)", @adapter.add_foreign_key(:employees, :companies, :name => 'favorite_company_fk') ) end test 'add_with_column' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_last_employer_id_fk` FOREIGN KEY (`last_employer_id`) REFERENCES `companies`(id)", @adapter.add_foreign_key(:employees, :companies, :column => 'last_employer_id') ) end test 'add_with_column_and_name' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `favorite_company_fk` FOREIGN KEY (`last_employer_id`) REFERENCES `companies`(id)", @adapter.add_foreign_key(:employees, :companies, :column => 'last_employer_id', :name => 'favorite_company_fk') ) end test 'add_with_delete_dependency' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id) " + "ON DELETE CASCADE", @adapter.add_foreign_key(:employees, :companies, :dependent => :delete) ) end test 'add_with_nullify_dependency' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id) " + "ON DELETE SET NULL", @adapter.add_foreign_key(:employees, :companies, :dependent => :nullify) ) end test 'add_with_restrict_dependency' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id) " + "ON DELETE RESTRICT", @adapter.add_foreign_key(:employees, :companies, :dependent => :restrict) ) end test 'add_with_options' do assert_equal( "ALTER TABLE `employees` ADD CONSTRAINT `employees_company_id_fk` FOREIGN KEY (`company_id`) REFERENCES `companies`(id) " + "on delete foo", @adapter.add_foreign_key(:employees, :companies, :options => 'on delete foo') ) end test 'remove_by_table' do assert_equal( "ALTER TABLE `suppliers` DROP CONSTRAINT `suppliers_company_id_fk`", @adapter.remove_foreign_key(:suppliers, :companies) ) end test 'remove_by_name' do assert_equal( "ALTER TABLE `suppliers` DROP CONSTRAINT `belongs_to_supplier`", @adapter.remove_foreign_key(:suppliers, :name => "belongs_to_supplier") ) end test 'remove_by_column' do assert_equal( "ALTER TABLE `suppliers` DROP CONSTRAINT `suppliers_ship_to_id_fk`", @adapter.remove_foreign_key(:suppliers, :column => "ship_to_id") ) end endruby-foreigner-1.4.1/test/foreigner/migration/000077500000000000000000000000001215172477300214155ustar00rootroot00000000000000ruby-foreigner-1.4.1/test/foreigner/migration/command_recorder_test.rb000066400000000000000000000025041215172477300263050ustar00rootroot00000000000000require 'helper' ActiveRecord::Migration::CommandRecorder.class_eval do include ::Foreigner::Migration::CommandRecorder end class Foreigner::CommandRecorderTest < Foreigner::UnitTest def setup @recorder = ActiveRecord::Migration::CommandRecorder.new end test 'invert_add_foreign_key' do @recorder.add_foreign_key(:employees, :companies) remove = @recorder.inverse.first assert_equal [:remove_foreign_key, [:employees, :companies]], remove end test 'invert_add_foreign_key with column' do @recorder.add_foreign_key(:employees, :companies, :column => :place_id) remove = @recorder.inverse.first assert_equal [:remove_foreign_key, [:employees, {:column => :place_id}]], remove end test 'invert_add_foreign_key with name' do @recorder.add_foreign_key(:employees, :companies, :name => 'the_best_fk', :column => :place_id) remove = @recorder.inverse.first assert_equal [:remove_foreign_key, [:employees, {:name => 'the_best_fk'}]], remove @recorder.record :rename_table, [:old, :new] rename = @recorder.inverse.first assert_equal [:rename_table, [:new, :old]], rename end test 'remove_foreign_key is irreversible' do @recorder.remove_foreign_key(:employees, :companies) assert_raise ActiveRecord::IrreversibleMigration do @recorder.inverse end end endruby-foreigner-1.4.1/test/foreigner/schema_dumper_test.rb000066400000000000000000000046331215172477300236320ustar00rootroot00000000000000require 'helper' class Foreigner::SchemaDumperTest < Foreigner::UnitTest class MockConnection def tables [ 'foo', 'bar' ] end end class MockSchemaDumper cattr_accessor :ignore_tables attr_accessor :processed_tables def initialize @connection = MockConnection.new @processed_tables = [] end def tables(stream) end def foreign_keys(table, stream) processed_tables << table end include Foreigner::SchemaDumper end test 'dump_foreign_key' do assert_dump "add_foreign_key \"foos\", \"bars\", :name => \"lulz\"", Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('foos', 'bars', column: 'bar_id', primary_key: 'id', name: 'lulz') assert_dump "add_foreign_key \"foos\", \"bars\", :name => \"lulz\", :primary_key => \"uuid\"", Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('foos', 'bars', column: 'bar_id', primary_key: 'uuid', name: 'lulz') assert_dump "add_foreign_key \"foos\", \"bars\", :name => \"lulz\", :dependent => :delete", Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('foos', 'bars', column: 'bar_id', primary_key: 'id', name: 'lulz', dependent: :delete) assert_dump "add_foreign_key \"foos\", \"bars\", :name => \"lulz\", :column => \"mamma_id\"", Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('foos', 'bars', column: 'mamma_id', primary_key: 'id', name: 'lulz') end test 'all tables' do MockSchemaDumper.ignore_tables = [] dumper = MockSchemaDumper.new dumper.tables(StringIO.new) assert_equal ['bar', 'foo'].to_set, dumper.processed_tables.to_set end test 'ignores tables' do MockSchemaDumper.ignore_tables = ['foo'] dumper = MockSchemaDumper.new dumper.tables(StringIO.new) assert_equal ['bar'].to_set, dumper.processed_tables.to_set end test 'removes table name suffix and prefix' do begin ActiveRecord::Base.table_name_prefix = 'pre_' ActiveRecord::Base.table_name_suffix = '_suf' assert_dump "add_foreign_key \"foos\", \"bars\", :name => \"lulz\"", Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('pre_foos_suf', 'pre_bars_suf', column: 'bar_id', primary_key: 'id', name: 'lulz') ensure ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = '' end end private def assert_dump(expected, definition) assert_equal expected, MockSchemaDumper.dump_foreign_key(definition) end end ruby-foreigner-1.4.1/test/helper.rb000066400000000000000000000020141215172477300172450ustar00rootroot00000000000000require 'bundler/setup' Bundler.require(:default) require 'test/unit' require 'active_record' require 'mocha' # Foreigner::Adapter.registered.values.each do |file_name| # require file_name # end module TestAdapterMethods def execute(sql, name = nil) sql_statements << sql sql end def quote_table_name(name) quote_column_name(name).gsub('.', '`.`') end def quote_column_name(name) "`#{name}`" end def sql_statements @sql_statements ||= [] end def drop_table(name, options = {}) end def disable_referential_integrity @disable_referential_integrity = true yield end private def execute(sql, name = nil) sql_statements << sql sql end end module Foreigner class UnitTest < ActiveSupport::TestCase end class IntegrationTest < ActiveSupport::TestCase def with_migration(&blk) migration = Class.new(ActiveRecord::Migration) migration.singleton_class do define_method(:up, &blk) end migration end end end