Skip to content

Commit

Permalink
SQLite adapter now supports preserving foreign keys on alter tables.
Browse files Browse the repository at this point in the history
  • Loading branch information
DirtYiCE committed Aug 30, 2010
1 parent 3796101 commit dbb5d70
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
29 changes: 28 additions & 1 deletion lib/sequel/adapters/shared/sqlite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ def column_list_sql(generator)
generator.is_a?(Schema::Generator) ? super : generator.map{|c| column_definition_sql(c)}.join(', ')
end

# Does the reverse of on_delete_clause, eg. converts strings like +'SET NULL'+
# to symbols +:set_null+.
def on_delete_sql_to_sym str
case str
when 'RESTRICT'
:restrict
when 'CASCADE'
:cascade
when 'SET NULL'
:set_null
when 'SET DEFAULT'
:set_default
when 'NO ACTION'
:no_action
end
end

# The array of column schema hashes, except for the ones given in opts[:except]
def defined_columns_for(table, opts={})
cols = parse_pragma(table, {})
Expand All @@ -192,9 +209,19 @@ def defined_columns_for(table, opts={})
nono= Array(opts[:except]).compact.map{|n| n.to_s}
cols.reject!{|c| nono.include? c[:name] }
end

# get foreign key list
metadata_dataset.with_sql("PRAGMA foreign_key_list(?)", input_identifier_meth.call(table)).each do |row|
c = cols.find {|co| co[:name] == row[:from] } or next
c[:table] = row[:table]
c[:key] = row[:to]
c[:on_update] = on_delete_sql_to_sym(row[:on_update])
c[:on_delete] = on_delete_sql_to_sym(row[:on_delete])
# is there any way to get deferrable status?
end
cols
end

# Duplicate an existing table by creating a new table, copying all records
# from the existing table into the new table, deleting the existing table
# and renaming the new table to the existing table's name.
Expand Down
9 changes: 8 additions & 1 deletion spec/adapters/sqlite_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
primary_key :id
text :name
integer :value
foreign_key :test2_name, :test2, :key => :name, :on_delete => :set_null, :on_update => :cascade
end

# This lame set of additions and deletions are to test that the primary keys
Expand All @@ -325,10 +326,16 @@
@db[:test3] << { :name => "foo", :value => 2}
@db[:test3] << { :name => "foo", :value => 3}
@db[:test3].filter(:id => 2).delete

@db.drop_column :test3, :value

@db['PRAGMA table_info(?)', :test3][:id][:pk].to_i.should == 1
fi = @db['PRAGMA foreign_key_list(?)', :test3].first # and only
fi[:table].should == 'test2'
fi[:from].should == 'test2_name'
fi[:to].should == 'name'
fi[:on_update].should == 'CASCADE'
fi[:on_delete].should == 'SET NULL'
@db[:test3].select(:id).all.should == [{:id => 1}, {:id => 3}]
end

Expand Down

0 comments on commit dbb5d70

Please sign in to comment.