cartodb/services/table-geocoder/lib/abstract_table_geocoder.rb
2020-06-15 10:58:47 +08:00

100 lines
2.7 KiB
Ruby

require_relative 'exceptions'
require 'active_support/core_ext/numeric'
module CartoDB
class AbstractTableGeocoder
DB_STATEMENT_TIMEOUT_MS = 5.hours.to_i * 1000
attr_reader :connection
def initialize(arguments)
@connection = arguments.fetch(:connection)
@table_name = arguments[:table_name]
@table_schema = arguments[:table_schema]
@qualified_table_name = arguments[:qualified_table_name]
@sequel_qualified_table_name = arguments[:sequel_qualified_table_name]
@schema = arguments[:schema] || 'cdb'
@state = 'submitted'
@connection.run("SET statement_timeout TO #{DB_STATEMENT_TIMEOUT_MS}")
end
def cancel
raise 'Not implemented'
end
def run
raise 'Not implemented'
end
def remote_id
raise 'Not implemented'
end
def update_geocoding_status
raise 'Not implemented'
end
def process_results
raise 'Not implemented'
end
def name
raise 'Not implemented'
end
def used_batch_request?
false
end
def reset_cartodb_georef_status
ensure_georef_status_colummn_valid
set_georef_status_to_null
end
# Makes sure there's a cartodb_georef_status_column and marks all geocodifiable rows with NULL.
# This is important because otherwise it is hard to track what rows have been processed or not.
def mark_rows_to_geocode
ensure_georef_status_colummn_valid
set_georef_status_from_false_to_null
end
protected
def ensure_georef_status_colummn_valid
connection.run(%Q{
ALTER TABLE #{@qualified_table_name}
ADD COLUMN cartodb_georef_status BOOLEAN DEFAULT NULL
})
rescue Sequel::DatabaseError => e
if e.message =~ /canceling statement due to statement timeout/
raise Carto::GeocoderErrors::AddGeorefStatusColumnDbTimeoutError.new
end
raise unless e.message =~ /column .* of relation .* already exists/
cast_georef_status_column
end
private
def set_georef_status_to_null
connection.select.from(@sequel_qualified_table_name).update(:cartodb_georef_status => nil)
end
def set_georef_status_from_false_to_null
connection.select.from(@sequel_qualified_table_name).where(:cartodb_georef_status => false).update(:cartodb_georef_status => nil)
end
def cast_georef_status_column
connection.run(%Q{
ALTER TABLE #{@qualified_table_name} ALTER COLUMN cartodb_georef_status
TYPE boolean USING cast(cartodb_georef_status as boolean)
})
rescue => e
raise "Error converting cartodb_georef_status to boolean, please, convert it manually or remove it."
end
end
end