Conrado Saud Programador

Escrevo neste blog, códigos e teorias de programação que desenvolvo e são úteis para mim. Pelo mesmo, espero que seja útil para você. Todo conteúdo aqui é público e gratuito.

contato@conradosaud.com.br

Conheça meu trabalho

GeoIp: Transformar códigos da coluna Region em nomes de Estados e siglas UF

Escrito por Conrado Saud

contato@conradosaud.com.br

Este tutorial é uma continuação do artigo Tutorial GeoIP e aqui irei explicar como você pode converter a coluna Region que vem em formato integer (como uma espécie de id) em uma coluna onde os códigos são substituídos pelos nomes dos estados. E ainda, vou passar um mimo para você leitor, com um pequeno código que converte o nome do estado de extenso para apenas a sigla UF. Vamos lá então.

Primeiramente, é necessário fazer o download do CSV com os estados. Este CSV não está incluso no painel de downloads do MaxMind. Deveria estar.
Então para conseguir esse CSV, basta abrir a página abaixo, clicar com o botão direito na página e selecionar Download (ou Salvar como...). Segue o mesmo: Quando você fizer o download, provavelmente ele virá em formato .txt, basta mudar sua extensão para .csv e está tudo ok.
Diferente do que fizemos no artigo anterior, onde tratamos todos os arquivos CSV para que pudessem serem importados no banco de dados, este arquivo está perfeito e não precisa ser alterado. O maior problema para trabalhar com este arquivo será na hora do SELECT onde teremos que fazer um JOIN triplo.

Agora será necessário criar uma nova tabela no seu banco de dados para que possamos importar este arquivo com os estados. Para isso você pode criar uma tabela simples com colunas para texto. Você pode utilizar a query a seguir a se quiser:


CREATE TABLE public.geoip_states (
  country CHAR(2) NOT NULL,
  loc_id CHAR(2) NOT NULL,
  name VARCHAR(100) NOT NULL
) 
	

Tabela criada, basta ir até ela e importar o CSV manualmente, da mesma forma que eu havia explanado no artigo anterior. Se você não o leu, você pode lê-lo clicando aqui.

Hora de criar a nova função que irá trazer todos os dados que já tinhamos antes (com cidade, país, latitude, longitude, etc), mas agora substituindo o Region em códigos para um Region com o nome por extenso de todos os estados do mundo.
Para isto, execute a query:


CREATE OR REPLACE FUNCTION public.geoip_city_state (
  p_ip inet,
  out loc_id integer,
  out country char,
  out region char,
  out city varchar,
  out postal_code varchar,
  out latitude double precision,
  out longitude double precision,
  out metro_code integer,
  out area_code integer
)
RETURNS record AS
$body$
    SELECT l.loc_id, l.country, c.name, city, postal_code, latitude, longitude, metro_code, area_code
      FROM geoip_city_block b JOIN geoip_city_location l ON (b.loc_id = l.loc_id)
	JOIN geoip_states c ON (c.loc_id = l.region AND c.country = l.country)
     WHERE $1 >= begin_ip AND $1 <= end_ip ORDER BY begin_ip DESC LIMIT 1;
$body$
LANGUAGE 'sql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
	

Pequenas alterações devem ser feitas neste sql caso você não esteja utilizando o PostgreSql
Feito isto, tudo já estará funcionando. Basta executar a nova função para ver o resultado:


SELECT * FROM geoip_city_state('177.34.156.40');
	

Eu pessoalmente, fiz uma alteração que me ajuda muito na hora de utilizar essa função. Como você deve ter percebido, para que essa função funcione é necessário passar um parametro do tipo inet. O tipo inet é um atributo para Ips. Dependendo de como é feito a logistica do seu sistema, pode ser meio difícil ou trabalhoso utilizar essa função transferindo algo do tipo inet do seu back-end. Isso aconteceu comigo.
Então para consertar isso, vou passar aqui uma função extra que eu uso, onde o tipo de parametro que a função espera, invés de ser inet, será um varchar. É praticamente só isso que muda, mas a função continua a mesma.
Segue a query:


CREATE OR REPLACE FUNCTION public.geoip_buscalocalizacao (
  p_ip varchar
)
RETURNS public.geoip_type AS
$body$
   DECLARE
   		record		geoip_type;
        v_ip		inet := p_ip::inet;

   BEGIN
     SELECT
     	loc_id, country, region, city,postal_code, latitude, longitude, metro_code, area_code 
   	 INTO
     	record.loc_id, record.country, record.region, record.city,
        record.postal_code, record.latitude, record.longitude, record.metro_code, record.area_code 
     FROM 
     	geoip_localizacao(v_ip);
     
      RETURN record;

   END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
	

Com esta função, você pode tratar toda a função como varchar, o que facilita mais no back-end que você trabalha dependendo da ocasião.

Convertado o nome dos estados em UF


Pode ser que seja muito útil para você invés do nome por extenso dos estados, sua sigla UF. Então para isso, segue uma lógica feita em C#, mas que pode se adaptar para qualquer linguagem com poucas alterações para retornar o nome do estado em siglas UF.
Segue o código:


public string formataEstado(string nome) {
    switch(nome){
        case "Acre": return "AC";
        case "Alagoas":	return "AL"; 
        case "Amapa": return "AP";	 
        case "Amazonas": return "AM";	 
        case "Bahia": return "BA";	 
        case "Ceara": return "CE";	 
        case "Distrito Federal": return "DF";	 
        case "Espirito Santo": return "ES";	 
        case "Goias": return "GO";	 
        case "Maranhao": return "MA";	 
        case "Mato Grosso":	return "MT";	 
        case "Mato Grosso do Sul": return "MS";	 
        case "Minas Gerais": return "MG";	 
        case "Para": return "PA";	 
        case "Paraiba":	return "PB";	 
        case "Parana": return "PR";	 
        case "Pernambuco": return "PE";	 
        case "Piaui": return "PI";	 
        case "Rio de Janeiro": return "RJ";	 
        case "Rio Grande do Norte":	return "RN";	 
        case "Rio Grande do Sul": return "RS";	 
        case "Rondonia": return "RO";	 
        case "Roraima": return "RR";	 
        case "Santa Catarina": return "SC";	 
        case "Sao Paulo": return "SP";	 
        case "Sergipe":	return "SE";
        case "Tocantins": return "TO";
        default: return nome;
    }
}
	

Desta forma, tudo fica mais simples e bonito.
Espero que este artigo tenha lhe ajudado, e caso sim, não deixe de curtir minha página no Facebook e também deixar seu comentário do que achou em relação ao artigo e até mesmo do blog logo abaixo. Obrigado pela leitura!
Este artigo lhe ajudou? Você pode retribuir o favor curtindo minha página no Facebook:
Tags: geoip, sql, ip, region

Voltar ao início
Publicado em   12/04/2017

Topo

Faça um comentário a respeito deste artigo!