Docker: O Resumão

O Docker foi desenvolvido para S.Os que usam o kernal Linux. No ambiente Linux é possível usar Docker para Desenvolvimento e Produção. Recentemente foi disponibilizado a versão docker para Windows e esta só pode ser usada para Desenvolvimento.

Container 

É um binário/arquivo/cápsula que encapsula todo o ambiente necessário para sua aplicação funcionar. O ambiente e sua aplicação serão virtualizados na sua máquina física. 

É errado afirmar que um container é uma VM. Uma VM obrigatoriamente terá um S.O(e outros recursos) virtualizados em um software (KMV,VMWare, Virtualbox). Já o container usa os recursos da própria máquina onde está sendo executado. Ele não virtualiza um S.O, ele usa o S.O da máquina hospedeira onde o Docker está instalado  e através de alguns recursos disponibilizados pelo hospedeiro é criado toda a estrutura interna do container.

A diferença entre Imagem e Container é que uma imagem é um container parado. Quando essa imagem é executada ela se transforma em um Container. Análogo a uma imagem ISO de um DVD.

Chinmay Shah – Article Why you should care about Docker?

Storage Drives

São os caras responsáveis por gerenciar leitura/escrita dos dados no container.

AUFS

Esse foi o primeiro SD (Storage Driver) usado pelo Docker. Ele trabalha com o esquema de camadas:

Toda vez que é instalado um novo software ou adicionado arquivos ao container é criado uma nova camada(imagem) como se fosse formando uma pilha de camadas. É nesse momento que entra o conceito de Copy-on-Write.

Todas as camadas subjacentes são read-only, somente a camada superior é read/write, essa camada também é chamada de Camada Container.

Digamos que você vai editar o arquivo /etc/network/interfaces, esse arquivo está na camada image 1.0 (que é read-only). No momento de salvar a edição esse arquivo é copiado para a primeira camada da pilha(que é read/write), onde é salvo uma cópia dele. Na próximas vezes que você for usar a configuração feita nesse arquivo, o docker vai chamar o da primeira camada da pilha. Isso é o Copy-on-write !

Referências:

Como instalar o PostgreSQL e pgAdmin no Linux

Tutorial de instalação do SGBD PostgreSQL e a ferramenta de administração pgAdmin 4. No final é dado dicas caso esteja utilizando PHP.

Estou usando Ubuntu, qual a minha versão?

Se você estiver usando o Ubuntu ou uma distribuição baseada nele, um desses comandos pode te ajudar a descobrir:

lsb_release -cs
cat /etc/*-release

No resultado do comando acima, procure por ‘VERSION_CODENAME’.

Instalando o PostgreSQL

Preferencialmente siga a documentação de instalação do PostgreSQL. Caso tenha algum problema execute o comando abaixo:

sudo apt -y install postgresql

Estou com problema no arquivo /etc/apt/sources.list.d/pgdg.list

Algumas pessoas tem problema ao criar o arquivo /etc/apt/sources.list.d/pgdg.list utilizando o script da documentação do Postgres. Se for o seu caso, faça isso:

  • Descubra qual a sua versão utilizando a dica do tópico acima.
  • O comando abaixo ira criar o arquivo /etc/apt/sources.list.d/pgdg.list. Coloque no comando abaixo a sua versão:
sudo echo "deb http://apt.postgresql.org/pub/repos/apt suaVersao-pgdg main" > /etc/apt/sources.list.d/pgdg.list

Como remover o PostgreSQL?

Para remover totalmente o PostgreSQL siga esses passos:

sudo apt --purge remove postgresql\*

sudo rm -rf /etc/postgresql/
sudo rm -rf /etc/postgresql-common/
sudo rm -rf /var/lib/postgresql/
sudo userdel -r postgres
sudo groupdel postgres

Usando PHP?

Se você estiver usando php, instale também a extensão PDO do postgres

sudo apt install php8.1-pgsql

Instalando o pgAdmin 4

Preferencialmente siga a documentação de instalação do pgAdmin 4. Caso tenha algum problema execute o comando abaixo:

sudo apt install pgadmin4

Criando o banco de dados pelo terminal

Primeiro precisamos acessar o prompt de comando do usuário postgres. Este usuário foi criado automaticamente na instalação do PostgresSQL.

sudo su - postgres

Para criar o banco de dados:

createdb bancoTeste

Vamos manipular o banco utilizando a ferramenta psql:

psql -d bancoTeste

Vamos atribuindo uma nova senha para o usuário postgres:

\password postgres

Ele vai pedir que você digite a nova senha duas vezes.

O psql é uma ferramenta muito útil. Esse post é um bom começo: PostgreSQL: Basic psql Commands

Acessando o pgAdmin 4

– Você pode pesquisar no menu de aplicativos do seu S.O por: pgadmin4

– Ou iniciando pelo terminal usando o comando: pgadmin4

– A partir do usuário postgres você consegue criar e logar nos bancos.

Referências

Organizando uma base de dados de logradouros usando PHP e LibreOffice Calc

Em uma das minhas tarefas do dia a dia, me deparei com esse problema: Como organizar uma base de dados de logradouros(endereços) ?Como eu poderia fazer isso de maneira prática e utilizando ferramentas já disponíveis?

Foi então que resolver usar o PHP e o LibreOffice Calc.

Contexto

Existe um S.I (ERP+CRM) onde é feito a gerência de todos os clientes. Nesse sistema todas as informações do cadastro de pessoa física/jurídica são utilizadas em outras partes do mesmo sistema. O módulo de CRM desse sistema utiliza, em uma de suas funcionalidades, os dados de endereço (cidade, bairro, logradouro) para posicionar o cliente em um mapa.

Hoje tenho acesso ao BD do sistema mas não tenho permissão de escrita. Preciso corrigir os problemas, enviar por ticket para o suporte do sistema e um arquivo CSV para eles fazerem as alterações no BD.

Problemas

Os logradouros cadastrados estão fora do padrão utilizado no mapa onde precisam ser exibidos, com isso é impossível posicionar o cliente no mapa.

Essa é uma lista dos itens que serão corrigidos:

  • Os logradouros que se referem a mesma rua precisam ter a mesma grafia;
  • Abreviações no nome do logradouro;
  • Na grafia dos logradouros que tem números, precisam estar por extenso;
  • Logradouros que tem a numeração de início e fim no nome;
  • Logradouros com números Romanos;

Solução desenvolvida

No primeiro momento, conversando com a equipe do Comercial, me deram a ideia de utilizar o LibreOffice Calc para organizar os dados e fazer as correções.

Obtendo os dados, organizando e fazendo as primeiras correções

Utilizando o LibreOffice Calc:

Obtive os dados acessando o BD PostgreSQL do sistema e executando um SQL. Copiei os resultados para o LibreOffice Calc.

Dei nome as colunas facilitar a  identificação e manipulação, ficou assim:

ID LOGRADOURO CODBAIRRO CEP CODCIDADE

Dar nome as colunas me ajudou na hora de usar a opção Classificar do Calc. Selecionei toda área da tabela onde estava os dados, dentro da opção CLASSIFICAR eu selecionei a coluna LOGRADOURO na opção Chave de classificação 1.

Ainda no Calc, utilizando a opção Localizar e substituir alterei todos os registro que se enquadra nas condições:

TERMO SUBSTITUÍDO POR
R. Rua
R+ESPAÇO Rua
Tv. +ESPAÇO Travessa
RUA+ESPAÇO Rua
Av+ESPAÇO Avenida
Av.+ESPAÇO Avenida
Cel.+ESPAÇO Coronel
Dr.+ESPAÇO Doutor
Gen.+ESPAÇO General
Brig.+ESPAÇO Brigadeiro
Pre.+ESPAÇO Presidente

Obs: Em alguns casos, existe discordância se o logradouro é Rua, Avenida ou Travessa. Isso teve que ser corrigido também.

Utilizando PHP:

Depois de fazer todas as correções manuais comecei a analisar os problemas para identificar quais seriam possíveis de serem resolvidos usando programação em tempo hábil.

O resultado do código desenvolvido está abaixo:

<?php
//ativando os erros
ini_set(‘display_errors’, ‘On’);
//Exibindo todos os erros
error_reporting(E_ALL);

$caminho_do_csv = '/var/www/html/lista-enderecos-mk.csv';
//O parâmetro FILE_TEXT especifica que o arquivo é retornado na codificação UTF-8.
$array_csv = file($caminho_do_csv, FILE_TEXT);
$map_csv = array_map('str_getcsv', $array_csv);

////////// PROBLEMAS PARA RESOLVER
//(Feito) 1- Encontrar um padrão e tudo que estiver a direita desse padrão deve ser apagado. Ex: numeração de inicio e fim no nome da rua.
//(Feito) 2- Retirar os numeros do nome do logradouro. Geralmente os numeros errados estão no final do nome.

//Função para exibir os dados de um mapa de array
// @return Sem terno
function exibe_mapa(Array $mapa_de_array)
{
if($mapa_de_array != NULL)
{
foreach ($mapa_de_array as $key => $valor)
{
print("Posição do Array exteno: ".$key."<br/>");
print("------ID: ".$valor[0]."<br/>");
print("------Logradouro: ".$valor[1]."<br/>");
print("------CODBAIRRO: ".$valor[2]."<br/>");
print("------CEP: ".$valor[3]."<br/>");
print("------CODCIDADE: ".$valor[4]."<br/>");
print('---------------------------------------------------------');
print("<br/>");
};
};
};

//Função para encontrar um padrão de texto em um mapa de array
// @return Sem terno
function encontrar_padrao(String $padrao, Array $mapa_de_array)
{
//percorrer o array para achar o padrão, se for encontrato, o texto é destacado:
//<font color='red'> texto </font>
$qtd_encontrada=0;
foreach ($mapa_de_array as $key => $valor) {
print("Posição do Array exteno: ".$key."<br/>");
print("------ID: ".$valor[0]."<br/>");
if(stripos($valor[1],$padrao) !== false){
print("------Logradouro: <font color='red'>".$valor[1]."</font><br/>");
$qtd_encontrada=$qtd_encontrada+1;
}else{
print("------Logradouro: ".$valor[1]."<br/>");
};
print('---------------------------------------------------------');
print("<br/>");
};
echo 'Total de ocorrências do padrão: '.$qtd_encontrada;
};

//Essa função contem o array com as strings que devem ser desconsideradas na busca por algum tipo de padrão de string.
// @return Retorna 1 se a string passado por parâmetro estever no array e 0 para caso contrário.
function padrao_desconsiderado(String $string)
{
//Array com os padrões que devem ser desconsiderados
$desconsiderar_padrao = array("ms-","MS-","Ms-","Rua ");
foreach($desconsiderar_padrao as $valor)
{
//A pergunta feita no IF é: Algum dos padrões que estão no array coincide com a string passada por parâmetro?
//Em outras palavras: $valor C $string || $valor esta CONTIDO em $string?
if(stripos($string,$valor) !== false){
return 1;
break;
};
};
return 0;
};

//Salvando em um arquivo CSV
// @return Sem terno
function salvando_no_arq_csv(Array $mapa_de_array)
{
//O primeiro parâmetro é o arquivo.csv que eu já criei e dei permissão 777 nele.
$fp = fopen('file.csv', 'w+');
foreach ($mapa_de_array as $key => $valor)
{
fputcsv($fp, $valor);
};

fclose($fp);
};

//Solução do problema 2
// @return Retorna o mapa de Array com os campos editados
function problema2(String $padrao, Array $mapa_de_array)
{
//percorrer o Array para achar o padrão.
//Depois eu edito a posição do array onde foi achado o padrão e salvo o novo texto editado;
$novo_mapa_de_array = $mapa_de_array;
foreach ($mapa_de_array as $key => $valor) {
if(stripos($valor[1],$padrao) !== false){
//posição onde foi encontrado o padrão
$posicao = stripos($valor[1],$padrao);
//Copiando o o valor(Array) que
$array_temp = $novo_mapa_de_array[$key];
$array_temp[1] = substr($array_temp[1],0,$posicao);
$novo_mapa_de_array[$key] = $array_temp;
};
};
return $novo_mapa_de_array;
};

//Função para encontrar um padrão que atende a expresão regular passada por parâmetro
// @return Retorna um mapa de Array com o texto corrigido
function problema3(String $expressao, Array $mapa_de_array)
{
//Variável que salva temporáriamente um mapa de array com os padrões encontrados;
$matches;
// Novo Array que será retornado contendo o texto editado
$novo_mapa_de_array = $mapa_de_array;

//percorrer o Array para achar o padrão, se for encontrato o padrão é excluido;
foreach ($mapa_de_array as $key => $valor)
{
//IMPORTANTE: a expressão precisa estár entre barras -> EX: /[0-9]/
if(preg_match('/'.$expressao.'/',$valor[1]))
{
if(padrao_desconsiderado($valor[1]) == 0){
preg_match('/'.$expressao.'/',$valor[1],$matches, PREG_OFFSET_CAPTURE);
$temp = $matches[0];
$array_temp = $novo_mapa_de_array[$key];
$array_temp[1] = substr($valor[1],0,$temp[1]);
$novo_mapa_de_array[$key] = $array_temp;
}else{
print_r("Valor: ".$valor[1]."<br/>");
printf("Variável temp[0] padrão: ".$temp[0]."<br/>");
printf("Variável temp[1] posição: ".$temp[1]."<br/><br/>");
}
}
};
return $novo_array_de_mapa;
};

//Resolve problema 2
//padrão para achar as ruas que tem a numeração de inicio e fim no nome
$padrao = ' - ';

//Resolve Problema 3
//Para achar numeros que estão no final do nome da rua
$expressao_problema_3 = '[0-9]{2,5}$';

$corrigido = problema2($padrao, $map_csv);

$corrigido2 = problema3($expressao_problema_3,$corrigido);

salvando_no_arq_csv($corrigido2);

?>