class PG::Connection

def copy_data( sql, coder=nil )

def copy_data( sql, coder=nil )
	raise PG::NotInBlockingMode.new("copy_data can not be used in nonblocking mode", connection: self) if nonblocking?
	res = exec( sql )
	case res.result_status
	when PGRES_COPY_IN
		begin
			if coder
				old_coder = self.encoder_for_put_copy_data
				self.encoder_for_put_copy_data = coder
			end
			yield res
		rescue Exception => err
			errmsg = "%s while copy data: %s" % [ err.class.name, err.message ]
			put_copy_end( errmsg )
			get_result
			raise
		else
			put_copy_end
			get_last_result
		ensure
			self.encoder_for_put_copy_data = old_coder if coder
		end
	when PGRES_COPY_OUT
		begin
			if coder
				old_coder = self.decoder_for_get_copy_data
				self.decoder_for_get_copy_data = coder
			end
			yield res
		rescue Exception => err
			cancel
			begin
				while get_copy_data
				end
			rescue PG::Error
				# Ignore error in cleanup to avoid losing original exception
			end
			while get_result
			end
			raise err
		else
			res = get_last_result
			if !res || res.result_status != PGRES_COMMAND_OK
				while get_copy_data
				end
				while get_result
				end
				raise PG::NotAllCopyDataRetrieved.new("Not all COPY data retrieved", connection: self)
			end
			res
		ensure
			self.decoder_for_get_copy_data = old_coder if coder
		end
	else
		raise ArgumentError, "SQL command is no COPY statement: #{sql}"
	end
end