Atribuir mais de uma variável no mesmo SQL – PL/pgSQL

Por esses dias precisei criar uma função no Postgres, e em determinada parte precisei popular duas variáveis de uma mesma query. Porém, não queria executar esta mesma query duas vezes para popular minhas variáveis.

Usualmente seria:

CREATE OR REPLACE FUNCTION funcao(codigo integer)
RETURNS SETOF character varying AS
$BODY$
DECLARE
variavel int;
variavel2 int;
BEGIN

--ATRIBUINDO A VARIÁVEL 1
select into variavel campo_tabela from tabela where campo = codigo;

--ATRIBUINDO A VARIÁVEL 2
select into variavel2 campo_tabela2 from tabela where campo = codigo;

END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION funcao(integer)
OWNER TO postgres;

Para popular várias de uma só vez, basta trazer as variáveis e em seguida na mesma ordem os campos das tabelas:

...
select into variavel, variavel2
campo_tabela, campo_tabela2
from tabela
where campo = codigo;
...

Até…

Anúncios

Debug Remoto em Aplicação Web no NetBeans

Eu que desenvolvo aplicações web com o WI, sei como é difícil criar conectores e tentar achar os bugs no erro e acerto, utilizando System.out em todo o processo.
Uma vez estava cansando disso e resolvi achar uma maneira melhor de achar esses bugs. Uma forma rápida e fácil é utilizar o modo debug do NetBeans, porém não conseguia integrá-lo com o meu tomcat.
Após algumas pesquisa consegui achar uma solução que compartilho com vocês agora, não lembro em que site foi que achei, pois faz muito tempo.

Vamos la!!!

Crie um arquivo .bat(será por ele que vamos iniciar nosso tomcat), pode ser satartup_tomcat.bat

Abra o arquivo e cole esse código

@echo off

cd C:\Program Files\Java\jre1.6.0_06\bin\

call java.exe  -jar -Djavax.net.debug=all -Xdebug -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7001 -Duser.dir="C:\Tomcat6" -Djava.endorsed.dirs="C:\Tomcat6\common\endorsed" "C:\tomcat6\bin\bootstrap.jar" start

:end

Agora substitua os caminhos do JRE e tomcat por da sua máquina.

Agora execute o .bat que foi criado, espere inciar.

Abra o NetBeans, vá no menu Depurar e clique em Anexar Depurador, em porta coloque 7001, em host coloque localhost ou seu ip, em timeout coloque 6000, agora clique em OK e seja feliz, agora todo conector que for executado o debug será ativado.

Criando uma Grid Java no WI

Saudações queridos amigos da terra média… digo, do planeta terra :). Atendo a pedidos, farei um passo a passo de como utilizar a opção Grid Java no WI. A Grid java é muito útil quando queremos realizar alguma lógica que não é possível resolver com SQL, ou montar registros que venham de algum arquivo ou WebService.
O exemplo que mostrarei abaixo é com uma grid sendo montada com registros fixos, que a partir dele pode ser substituido por registros vindo do banco, arquivos ou webservices.

Para construir este exemplo vou utilizar o último projeto que criamos, chamado projeto_objeto e o projeto de classes chamado ProjetoConector.

Primeiro passo, vamos separar nossa classe que será uma grid das outras classes que já existem. Crie o pacote br.com.projetoteste.grids e dentro do pacote crie a classe ExemploGridJava(Ta vendo Rodrigo, seguindo o CodeConvetions do Java ;p ). Seu projeto deverá ficar da seguinte maneira:

1

Para que o WI reconheça que esta classe será uma grid é necessário estender as seguintes interfaces na classe: InterfaceGrid, InterfaceParameters. Mais uma vez a interface InterfaceParameters é implementada, como vimos no post anterior ela serve para ler e exporta variáveis da página.

Após estender estas interfaces será necessário implementar os métodos abstratos dela, basta clicar no ícone de sugestão e importar os métodos, os métodos importados são:

execute – Espera um MAP[] que serão os registros que a grid espera.

getOutputParameters – Campo(s) de saída, que pode ser utilizado para jogar alguma variável de resposta da classe na página. Em caso de erro por exemplo é possível setar o erro nessa variável.

GetInputParameters – Campo(s) de entrada, serve de filtro para a consulta que montará a grid.

Seu código deve ficar da seguinte maneira:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.projetoteste.grids;

import br.com.itx.exception.UserException;
import br.com.itx.integration.DatabaseAliases;
import br.com.itx.integration.InterfaceGrid;
import br.com.itx.integration.InterfaceParameters;
import br.com.itx.integration.JavaParameter;
import br.com.itx.util.WIMap;
import java.util.Map;

/**
 *
 * @author Santana
 */
public class ExemploGridJava implements InterfaceGrid, InterfaceParameters{

    @Override
    public Map[] execute(WIMap wimap, DatabaseAliases da) throws UserException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int returnType() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public JavaParameter[] getInputParameters() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public JavaParameter[] getOutputParameters() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
}

Agora vamos colocar a mão na massa. Para este exemplo vamos utilizar nosso bean frutas populando com alguns registros para fazer a montagem da grid, ficando como o código abaixo:

    @Override
    public Map[] execute(WIMap wimap, DatabaseAliases da) throws UserException {
        
        fruta f1 = new fruta();
        f1.setDs_nome("MANGA");
        f1.setNr_peso(13.0);
        f1.setNr_preco(5.55);
        
        fruta f2 = new fruta();
        f2.setDs_nome("CAJU");
        f2.setNr_peso(12.0);
        f2.setNr_preco(3.55);
        
        
        fruta f3 = new fruta();
        f3.setDs_nome("LARANJA");
        f3.setNr_peso(5.0);
        f3.setNr_preco(3.40);
        
        
        List<fruta> lf = new ArrayList<fruta>();
        
        lf.add(f1);
        lf.add(f2);
        lf.add(f3);
         
        return null;
    }

Agora vamos criar um método chamado getMapFruta que espera um objeto fruta e retorna um map, popula nossas variáveis da grid, como no exemplo abaixo:

  public Map getMapGta(fruta d) {
        Map map = new HashMap();
        map.put("tmp.ds_nome", d.getDs_nome());
        map.put("tmp.nr_peso", String.valueOf(d.getNr_peso()));
        map.put("tmp.nr_preco", String.valueOf(d.getNr_preco()));
        return map;
    }

Um detalhe neste código é que todas as variáveis devem ser String, por algum motivo que não sei explicar, é que se for exportado uma variável que não seja String é mostrado o nome Object na página. Neste caso devemos da um parse em todas as variáveis que não sejam do tipo String.

Feito isto basta apenas criar uma variável do tipo Map[] do tamanho do nosso list no método execute da nossa classe e incluir nosso método getMapFruta que trata os campos do objeto fruta. Código abaixo:

  Map[] map = new Map[lf.size()];
  for (int i = 0; i < lf.size(); i++) {
       map[i] = getMapFruta(lf.get(i));
   }
        
   return map;

Código completo da classe:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.projetoteste.grids;

import br.com.itx.exception.UserException;
import br.com.itx.integration.DatabaseAliases;
import br.com.itx.integration.InterfaceGrid;
import br.com.itx.integration.InterfaceParameters;
import br.com.itx.integration.JavaParameter;
import br.com.itx.util.WIMap;
import br.com.projetoteste.fruta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Santana
 */
public class ExemploGridJava implements InterfaceGrid, InterfaceParameters {

    @Override
    public Map[] execute(WIMap wimap, DatabaseAliases da) throws UserException {

        fruta f1 = new fruta();
        f1.setDs_nome("MANGA");
        f1.setNr_peso(13.0);
        f1.setNr_preco(5.55);

        fruta f2 = new fruta();
        f2.setDs_nome("CAJU");
        f2.setNr_peso(12.0);
        f2.setNr_preco(3.55);


        fruta f3 = new fruta();
        f3.setDs_nome("LARANJA");
        f3.setNr_peso(5.0);
        f3.setNr_preco(3.40);


        List<fruta> lf = new ArrayList<fruta>();

        lf.add(f1);
        lf.add(f2);
        lf.add(f3);

        Map[] map = new Map[lf.size()];
        for (int i = 0; i < lf.size(); i++) {
            map[i] = getMapFruta(lf.get(i));
        }
        
        return map;
    }

    public Map getMapFruta(fruta d) {
        Map map = new HashMap();
        map.put("tmp.ds_nome", d.getDs_nome());
        map.put("tmp.nr_peso", String.valueOf(d.getNr_peso()));
        map.put("tmp.nr_preco", String.valueOf(d.getNr_preco()));
        return map;
    }

    @Override
    public int returnType() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public JavaParameter[] getInputParameters() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public JavaParameter[] getOutputParameters() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

Pronto, finalizamos nossa classe, agora basta compilar nosso projeto e jogar no nosso projeto web na seguinte pasta: tomcat6/webapps/projeto_objeto/WEB-INF/classes.
Deve ficar na seguinte disposição:

2

Agora abra o WI, e vá na sessão de grids, lá você vai encontrar 3 opções de grid, grid sql, grid html e grid xml out. Clique em grid html

Em identificador coloque exemplogridjava, em tipo coloque JAVA, em início da linha, deixe como está e clique em gravar. Deverá ficar da seguinte maneira:

3

Após clicar em gravar, ele monta um layout padrão para nossa grid, para ver isto clique em modelo.
Deverá estar da seguinte maneira:

<html>
<body>
<table border="1" cellspacing="0">
  <tr>
    <td align="center"><b>JAVA</b></td>
  </tr>
  <tr>
    <td>|coluna|&nbsp;</td>
  </tr>
  <tr>
    <td colspan="10">
      <p align="center">Empty</p>
    </td>
  </tr>
</table>
</body>
</html>

No nome Java coloque os nomes dos nossos campos, ou seja, Nome da Fruta, Peso, Valor e mais em embaixo no campo coluna, vamos colocar nossas variáveis, ou seja, tmp.ds_nome, tmp.nr_peso, tmp.nr_preco e no lugar do nome Empty, substitua por Nenhum registro encontrado e clique em gravar. Deverá ficar da seguinte maneira.

<html>
<body>
<table border="1" cellspacing="0">
  <tr>
    <td align="center"><b>Nome da Fruta</b></td>
    <td align="center"><b>Peso</b></td>
    <td align="center"><b>Valor</b></td>
  </tr>
  <tr>
    <td>|tmp.ds_nome|&nbsp;</td>
    <td>|tmp.nr_peso|&nbsp;</td>
    <td>|tmp.nr_preco|&nbsp;</td>
  </tr>
  <tr>
    <td colspan="10">
      <p align="center">Nenhum registro encontrado</p>
    </td>
  </tr>
</table>
</body>
</html>

Após isto crie uma página de teste com o nome exemplogridjava. No pré-pagina existe uma opção grid java, clique nela. No campo nome da classe, coloque o caminho e nome complete da nossa classe que criamos, seria br.com.projetoteste.grids.ExemploGridJava e no campo Grid, selecione a grid que criamos no passo anterior. Deverá ficar da seguinte maneira:

4

Clique em editar html e coloque a chamada da nossa grid e clique em gravar, ficando da seguinte maneira:

5

Agora basta clicar em vizualizar:

6

Então é isso, fica aqui mais um tutorial para o pessoal que tinha dúvida de como implementar uma grid java. Grid Java pode salvar você quando fica impossível realizar lógicas ninjas com querys ou consumir algum webservice. Espero que tenha ajudado e abraços a todos.

Problema com handler, Android…

Há algum tempo foi desenvolvido uma aplicação la na empresa feita em Android, eu fui um dos participantes do desenvolvimento.

É muito gratificante desenvolver em Android, ele possui uma gama de ferramentas que te ajudam e facilitam o desenvolvimento, existem vários tutoriais e muitos livros bons no mercado.

Um desses livros que recomendo que me ajudou muito no inicio foi “Google Android – Aprenda A Criar Aplicações Para Dispositivos Móveis”, é um livro para iniciantes com muitos exemplos . Porém, como tudo na vida não são flores, um problema do Android, são suas várias versões, é simplesmente um parto compatibilizar sua aplicação com essas versões. No incio me bati bastante no desenvolvimento da aplicação lá da empresa, pois os tablets que testamos eram com versões 4.1, e algumas funcionalidades deixavam de funcionar. Porém, uma que mais me intrigou foi um erro que era gerado quando a aplicação executava uma impressão de um documento em uma impressora bluetooth em uma versão do android 3.2.

O erro que dava era esse “Can’t create handler inside thread that has not called Looper.prepare()”.

Após perder várias horas pesquisando no pai dos burros(google hehehe), descobri uma solução simples e elegante em um blog de um cara Indiano. Ele passou pelo mesmo problema e a solução simplesmente era chamar o método Looper.loop(). Por algum motivo na versão 4.1 do Android não é preciso chamar essa função. Abaixo segue o código completo e a fonte de onde foi encontrado. Espero que ajude vocês que estão passando pelo mesmo problema.

Antes segue um vídeo que fiz demonstrando o uso da aplicação:
Video: http://www.youtube.com/watch?v=UpNWYRvcou4

Fonte: http://mukeshyadav4u.blogspot.com.br/2012/11/cant-create-handler-inside-thread-that_8.html#comment-form

private Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {

 final SyncRequestManager test = new SyncRequestManager(Test.this);
 try {
            message = message.replaceAll("\n", "");
            progressDialog= ProgressDialog.show(Test.this,
                   "", "Shairing please wait....",true);

        new Thread() {
                  public void run() {
                         try{
                             <strong>Looper.prepare();</strong>
                             JSONObject jsonObject = test.postOnFacebookWall(message,byteArray);

                                 JSONObject response = jsonObject.getJSONObject("response");
                                 final String iconUrl = response.getString("icon");
                                 Log.i(" Response" , ""+response);
                                 Log.i(" Icon" , ""+iconUrl);

                                      final FacebookUtil fbUtil = new FacebookUtil(ShareMotekon.this);
       fbUtil.postMessageOnWall(message, iconUrl,byteArray);
       sleep(8000);
      } catch (Exception e) {
          Log.d("Exception", e.getMessage());
      }
           progressDialog.dismiss();                       
           mhandler.sendEmptyMessage(0);
     }
   }.start();
 } catch (Exception e) {
 e.printStackTrace();

   }
  }
};

 private Handler mhandler = new Handler() {

  @Override
    public void handleMessage(Message msg) {
   btnNext.setEnabled(true);
   Toast.makeText(ShareMotekon.this,
                       "Message Shared Successfully!", Toast.LENGTH_LONG).show();

    Log.d("INSIDE HANDLER","FB SHARE");

    <strong>myLooper = Looper.myLooper();
            Looper.loop();
                         myLooper.quit();</strong>  
             }
    };

Tratamento de Objetos Entre Conectores JAVA – WebIntegrator

Pessoal, conforme prometido, segue meu primeiro post, é um tutorial abordando como tratar objetos entre conectores, ou seja, exportar um objeto para a sessão do WI e outro lendo este objeto da sessão. O que me motivou a tentar fazer esse processo, foi um caso aqui no trabalho, onde eu consumia um WebService que me retornava um array de objetos e precisava usar esse objeto em outro momento dentro de outra pagina. Para resolver este problema eu criei um conetor que lia esse objeto exportado e montava um GRID JAVA(Posso fazer um outro tutorial explicando como usar essa GRID JAVA, em caso de pedidos 🙂 ) com o resultado do WebService. Bom, então vamos ao que interessa.

1 – Primeiro Passo
Primeiro vamos criar um projeto de teste, chamado projeto_objeto. (Assume-se que já saiba criar um projeto no WI):

imagem_1

Feito isto criaremos um projeto JAVA que conterá os 2 conectores, um sendo que exportará um objeto chamado  FRUTAS’ e outro conector que lerá esse objeto e mostrará na página.(Para criação do conector usaremos o NetBeans)

imagem_2

Selecione a opção Aplicação Java e clique em next.

imagem_3

Coloque o nome do projeto e clique em finalizar. Usaremos o nome ProjetoConector.

Crie a seguinte classe exportaobjeto que exportará nosso obejeto para a sessão e exportaobjetorecebe que recebe o objeto, todos no pacote br.com.projetoteste. Ficará na seguinte
disposição:

imagem_4

2- Vamos criar o conetor

Para que o WI reconheça um conector em seu projeto é necessário estender as seguintes interfaces em suas classes: InterfaceConnector, InterfaceParameters:

public class exportaobjetorecebe implements InterfaceConnector, InterfaceParameters{

}

Para corrigir o erro, faz-se necessário importar a lib do wi. Clique com o botão direito do projeto no netbeans, depois clicar no botão propriedades. Ao abrir uma janela, selecione bibliotecas, após clicar em Adicionar JAR/Pasta. Selecione a lib do WI que pode ser encontrada dentro do projeto criado pelo próprio WI(projeto_objeto).

imagem_5

Feito isto, clique na sugestão do NetBeans e importe os métodos abstratos das intefaces:
Dois métodos serão criados, o getOutputParameters() que exporta os parâmetros desejados.
Conforme exemplo a seguir:

   @Override
    public JavaParameter[] getOutputParameters() {
        JavaParameter[] out = new JavaParameter[1];
        out[0] = new JavaParameter("tmp.objeto", "Retorna Obejto");
        return out;
    }

E o getInputParameters() serve para ler os parâmetros que estão na sessão do WI. Podemos determinar os nomes do parâmetros de entrada, como no exemplo a seguir.

    @Override
    public JavaParameter[] getInputParameters() {
        JavaParameter[] in = new JavaParameter[1];
        in[0] = new JavaParameter("tmp.objeto", "Retorna Obejto");
        return in;
    }

Outro método criado e muito importante é o execute. Dentro dele é criada toda a lógica que precisamos, pois é o primeiro método que o WI executa em um conector.

    @Override
    public void execute(ExecuteParams ep) throws UserException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

Feito isto, criaremos nosso bean que será o objeto a ser exportado, chamaremos de fruta com os seguintes campos, ds_nome, nr_preco, nr_peso.

public class fruta {
    private String ds_nome;
    private Double nr_preco;
    private Double nr_peso;

    /**
     * @return the ds_nome
     */
    public String getDs_nome() {
        return ds_nome;
    }

    /**
     * @param ds_nome the ds_nome to set
     */
    public void setDs_nome(String ds_nome) {
        this.ds_nome = ds_nome;
    }

    /**
     * @return the nr_preco
     */
    public Double getNr_preco() {
        return nr_preco;
    }

    /**
     * @param nr_preco the nr_preco to set
     */
    public void setNr_preco(Double nr_preco) {
        this.nr_preco = nr_preco;
    }

    /**
     * @return the nr_peso
     */
    public Double getNr_peso() {
        return nr_peso;
    }

    /**
     * @param nr_peso the nr_peso to set
     */
    public void setNr_peso(Double nr_peso) {
        this.nr_peso = nr_peso;
    }
}

Veremos que para exportar o objeto não será nenhum bicho de sete cabeças, faremos simplesmente instanciar nossa classe bean frutas, populá-la e chamar o método WIMap.putobj, conforme imagem a seguir:

    @Override
    public void execute(ExecuteParams ep) throws UserException {
        fruta f = new fruta();
        f.setDs_nome("MANGA");
        f.setNr_peso(1.0);
        f.setNr_preco(8.55);

        ep.getWIMap().putObj("tmp.objeto", f);
    }

Deste jeito o WI exportará o objeto fruta para a sessão do seu projeto WEB em uma variável chamada tmp.obejeto.

Agora para ler esse objeto é só fazer o processo contrário. Na classe exportaobjetorecebe leremos  essa variável tmp.objeto convertendo-a em nosso bean frutas, conforme imagem abaixo:

    @Override
    public void execute(ExecuteParams ep) throws UserException {
        fruta f = (fruta) ep.getWIMap().getObj("tmp.objeto");

        ep.getWIMap().put("tmp.ds_nome", f.getDs_nome());
        ep.getWIMap().put("tmp.nr_preco", String.valueOf(f.getNr_preco()));
        ep.getWIMap().put("tmp.nr_peso", String.valueOf(f.getNr_peso()));
    }

    @Override
    public boolean exit() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public JavaParameter[] getInputParameters() {
        JavaParameter[] in = new JavaParameter[1];
        in[0] = new JavaParameter("tmp.objeto", "Retorna Obejto");
        return in;
    }

Perceba que dessa vez usamos o método put do WI para exportar as variáveis do nosso objeto recebido da classe exportaobjeto.
Feito isto vamos compilar nosso projeto, gerar os .class e colocar dentro no nosso projeto WEB. O projeto final ficará na seguinte disposição:

imagem_4

Para jogar as classes compiladas em nosso projeto WEB é só copiar a raiz do pacote(br.com.projetoteste) e jogá-lo na pasta webapps/projetoteste/WEB-INF/classes. Caso a pasta classes não exista em seu projeto, crie-a. Ficará na seguinte disposição:

imagem_7

3- Reinicie o tomcat.

4- Executando o processo

Agora vamos fazer a chamada do conetor em uma pagina de teste que criaremos no WI.

Em uma pagina de teste selecione o Pré-Pagina. No Pré-Pagina existe uma opção Conetor Java, conforme imagem abaixo:

imagem_8

Na tela que irá se abrir, digite o caminho completo de sua classe no campo Nome da Classe, conforme imagem abaixo:

imagem_9

Volte para o pré-pagina e clique novamente em Conector Java. Faça o mesmo procedimento, porém para a classe exportaobjetorecebe.

imagem_14

Perceba que apareceu um campo em Parâmetros de Entrada, este campo será recebido do conector de cima, do qual exporta o objeto. Seu pré-página deverá ficar da seguinte maneira:

imagem_11

Agora clique na opção Editar HTML no WI e coloque os campos que são exportados do conector que lê o objeto. Ficando da seguinte maneira:

imagem_12

Agora basta apenas clicar em Vizualizar no WI.

imagem_13

Então é isso galera, espero que vocês tenham gostado do meu primeiro post, espero que seja de extrema ajuda para alguns e de estudo para outros, até o próximo post.

Emanuel, Uma Jornada Inesperada

Senhoras e Senhores, obrigado pela atenção de vocês. É com imenso prazer que depois de relutar bastante em criar um blog, resolvi ceder.

Há alguns dias, estava em um fórum de um framework que utilizo aqui na empresa e vi uma dúvida de um desenvolvedor. Respondi suas dúvidas, porém o mesmo encontrava dificuldades em resolvê-las, para ajudá-lo, criei um pequeno tutorial informando passo-a-passo como ele devia proceder.

Pensando nisto, e em uma melhor maneira de guardar este material, consultei um colega de trabalho(Tiago Passos),  o mesmo abriu minha mente para este tipo de espaço na WEB. Percebi que esta seria a melhor maneira de guardar aquelas informações do dia-a-dia que acumulamos no trabalho para consultas posteriores, além de ajudar quem esta à procura.

Então este blog destina-se a ser um arquivo de soluções que vivenciarei na minha carreira e poderei partilha-las com vocês, espero que seja de utilidade para todos.

Meu próximo post será este material, que é sobre o FrameWork de desenvolvimento WebIntegrator, nele eu explico como manipular objetos entre conectores. Como eu trabalho a 5 anos com esse framework, eu posso ajudar aos inexperientes criando tutoriais para vocês, é só deixar nos comentários o que vocês querem saber.

Até mais e abraços.