Modify column types and names, forcing the typecast

1.0
Fernando Blat 14 years ago
parent 7c85195e1a
commit 583d4aa551

@ -131,13 +131,15 @@ class Api::Json::TablesController < ApplicationController
def update_schema
respond_to do |format|
format.json do
if params[:what] && %W{ add drop }.include?(params[:what])
if params[:what] && %W{ add drop modify }.include?(params[:what])
unless params[:column].blank? || params[:column].empty?
begin
if params[:what] == 'add'
@table.add_column!(params[:column])
else
elsif params[:what] == 'drop'
@table.drop_column!(params[:column])
else
@table.modify_column!(params[:column])
end
render :nothing => true, :status => 200
rescue => e

@ -122,6 +122,30 @@ class Table < Sequel::Model(:user_tables)
end
end
def modify_column!(options)
owner.in_database do |user_database|
if options[:old_name] && options[:new_name]
user_database.rename_column name.to_sym, options[:old_name].to_sym, options[:new_name].to_sym
end
if options[:type]
begin
user_database.set_column_type name.to_sym, (options[:new_name] || options[:name]).to_sym, options[:type]
rescue => e
message = e.message.split("\n").first
if message =~ /cannot be cast to type/
user_database.transaction do
random_name = "new_column_#{rand(10)*Time.now.to_i}"
user_database.add_column name.to_sym, random_name, options[:type]
user_database["UPDATE #{name} SET #{random_name}=#{(options[:new_name] || options[:name])}::#{options[:type]}"]
user_database.drop_column name.to_sym, (options[:new_name] || options[:name]).to_sym
user_database.rename_column name.to_sym, random_name, (options[:new_name] || options[:name]).to_sym
end
end
end
end
end
end
def to_json(options = {})
rows, columns, rows_count = [], [], 0
limit = (options[:rows_per_page] || 10).to_i

@ -152,6 +152,15 @@ feature "Tables JSON API" do
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"postal code", "integer"]]
put_json "/api/json/tables/#{table.id}/update_schema", {
:what => "modify", :column => {
:type => "text", :name => "postal code"
}
}
response.status.should == 200
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"postal code", "text"]]
put_json "/api/json/tables/#{table.id}/update_schema", {
:what => "add", :column => {
:type => "integerrrr", :name => "no matter what"

@ -125,7 +125,19 @@ describe Table do
}.should raise_error
table.reload
table.add_column!(:name => "my new column", :type => "text")
table.add_column!(:name => "my new column", :type => "integer")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column", "integer"]]
table.modify_column!(:old_name => "my new column", :new_name => "my new column new name", :type => "text")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column new name", "text"]]
table.modify_column!(:old_name => "my new column new name", :new_name => "my new column")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column", "text"]]
table.modify_column!(:name => "my new column", :type => "text")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column", "text"]]
@ -140,5 +152,18 @@ describe Table do
table.schema.should == [[:id, "integer"], [:name, "text"], [:description, "text"], [:"my new column", "text"]]
end
it "should be able to modify it's schema with castings that the DB engine doesn't support" do
table = create_table
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"]]
table.add_column!(:name => "my new column", :type => "text")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column", "text"]]
table.modify_column!(:old_name => "my new column", :new_name => "my new column new name", :type => "integer", :force_value => "NULL")
table.reload
table.schema.should == [[:id, "integer"], [:name, "text"], [:location, "geometry"], [:description, "text"], [:"my new column new name", "integer"]]
end
end

Loading…
Cancel
Save