terça-feira, 21 de agosto de 2018

Java dentro do Oracle

Programando em Java, no Oracle, sem usar Load Java tool

Existem 3 tipos de pessoas. As que sabem o que vou escrever aqui, as que já usaram apenas o Java Load para carregar classes no Oracle e as que acham que isso não existe. Pois bem, se você é a segunda ou a terceira, siga a leitura. Se for a primeira, veja foto de gatos.

A verdade é que faz um bom tempo que trabalhei com classes java dentro do Oracle. Algo em torno de 7 anos ou mais e um projeto em particular, me fez considerar utilizar java para compartilhar a solução na aplicação e no Oracle.

A abordagem utilizando Java Load Tool, basicamente pega um .class ou .jar e carrega dentro do Oracle usando uma ferramenta que existe junto com a instalação do Oracle (o Java Load). Essa solução é bem conhecida e foi exatamente essa que utilizei a alguns anos. E existe uma infinidade de referencias ensinando a trabalhar com essa abordagem, como por exemplo essa, essa outra e essa aqui também. Em resumo, com essa abordagem você escreve sua classe ou seu programa java, compila e utiliza o utilitário java load para carregar seu compilado dentro do Oracle, tornando as operações da sua classe disponíveis para executa-las dentro do Oracle. 


Bacana né? nem tanto! poderia ser melhor... 

Como algo tão simples como compilar uma classe e carregar usando uma ferramenta não é simples?
Primeiro que você tem que executar o Java Load dentro do servidor do Oracle e isso por si só, já é um problema. Imagina em empresas de grande porte? Solicitar ao DBA, aguardar a fila de execução dos chamados para saber se compilou com sucesso. Ou em alguns casos mais rigorosos, você teria de apresentar o código e explicar ao DBA cada linha que está entrando dentro do banco de dados. Afinal, é uma classe compilada que será carregada por um utilitário. Não é apenas abrir uma procedure (por exemplo). 


Então ta, vamos então burlar o DBA ? 

Não, não vamos enganar o DBA, vamos tornar as coisas mais claras e mais simples para nós.
Assim como functions, procedures e outros objetos, podemos compilar um arquivo ".jsp" (não é o que você está pensando). Esse arquivo é exatamente uma classe java, com uma assinatura semelhante a de uma procedure. Assim:

create or replace and compile java source named HojeEhDia as

import java.util.Date;
import java.util.Calendar;

public class HojeEhDia
{
    public static void main(String[] args) {
        System.out.println("hoje é dia: " : hoje("/"));
    }

    public static String hoje(String separador) {
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        int dia = calendar.get(Calendar.DATE);
        int mes = calendar.get(Calendar.MONTH);
        int ano = calendar.get(Calendar.YEAR);

        return dia+separador+mes+separador+ano;

    }
}

Feito isso, você só precisa chamar sua operação usando uma function do Oracle. Assim:

CREATE OR REPLACE FUNCTION HojeEhDia_Java(separador IN VARCHAR2)
RETURN varchar2 AS

LANGUAGE JAVA NAME 'HojeEhDia.hoje(java.lang.String) return java.lang.String';

E está pronto :) Criamos um objeto do tipo Java Source e uma function para chama-lo. Para testar, basta um select:

select HojeEhDia('/') from dual;

Tudo compilado, facilmente modificável, como um simples objeto Oracle deve ser. 
Só fique atento com os imports. Referencias que não são nativas do java, até funcionam, mas você deverá colocar o .jar delas lá no servidor de banco de dados, na instalação do Oracle.

Me ajudou, espero que te ajude também :) Até a próxima!

domingo, 12 de agosto de 2018

Programação funcional em C#

Programação funcional com C#, na prática, para o dia a dia

Tem algo mais frustrante do que abrir o stackoverflow e ver que a única resposta é uma que não serve para nada e foi claramente publicada ali, só para que o sujeito ganhasse pontos fáceis? Sim, tem!

Tente buscar no Google sobre programação funcional e terá a mesma sensação (teoria, teoria e mais teoria).

Na equipe onde trabalho, temos um evento periódico que carinhosamente atribui o nome de DevTalk. Esse é um espaço para que os times de desenvolvimento troquem informações sobre determinados assuntos. Eu sempre sugiro que eles apontem assuntos para pesquisarmos e discutirmos nesses encontros (não é nada aleatório, a ideia é pensarmos fora da caixa, trazer ideias e avaliar se cabe no nosso dia a dia; para que aos poucos coloquemos em prática).
Na semana passada, apontaram como assunto "programação funcional"... E foi ai que resolvi escrever esse post (depois de um bom tempo sem publicar nada) ;/

Mas que diabos é isso?

Eu poderia escrever um monte de baboseiras aqui, como de onde veio, quando veio, quem teve a ideia. Mas não, isso está aos montes na internet (aqui, aqui e também aqui) e o paradigma funcional não é nada novo, só está em evidência pois agora o processamento paralelo está sendo amplamente utilizado nos sistemas web.


Então pra que esse artigo?

Como o próprio sub titulo diz. A ideia aqui é mostrar na prática como trabalhar com programação funcional em um cenário real (não esses montes de blocos de códigos espalhados nos artigos e que só trazem dúvidas ao invés de esclarecimentos).


Let it go, let it go...

Vou colocar abaixo uma classe c# com operações bancárias, da forma como fazemos no dia a dia e depois vou aplicar nessa classe os conceitos de programação funcional e explicar as vantagens de um modelo para o outro.

public class Caixa {
   private double Saldo {get; set; }

   public Caixa(double saldoInicial){
      this.Saldo = saldoInicial;
   }

   public void Depositar(double valor) {
       this.Saldo += valor;
   }


   public void Sacar(double valor) {
       this.Saldo -= valor;
   }


   public string ImprimirExtrato() {
       return "Seu saldo atual é de: " + this.Saldo;
   }
}

Usando exemplo 1):
var caixa = new Caixa(10.5);
caixa.ImprimirExtrato();
caixa.Depositar(31.4);
caixa.Sacar(5.7);
caixa.ImprimirExtrato();




public class Caixa {

   public double Depositar(this double saldoAtual, double valor) {
       return saldoAtual += valor;
   }


   public double Sacar(this double saldoAtual, double valor) {
       return saldoAtual += valor;
   }


   public string ImprimirExtrato(this double saldoAtual) {
       return "Seu saldo atual é de: " + saldoAtual;
   }
}

Usando exemplo 2):
double saldo = 10.5;
saldo.ImprimirExtrato().Depositar(31.4).Sacar(5.7).ImprimirExtrato();


Enquanto isso, no dia a dia...

Observando os exemplos acima, a grande "vantagem", é a forma como utilizamos os métodos. Parece mais "legível" e para por aí. Porém, se pensarmos em utilizar esse formato em um ambiente multi-threading, as vantagens crescem infinitamente. É possível executar operações exatamente após a operação anterior e os problemas com mutabilidade que frequentemente encontramos na programação imperativa, são minimizados ou até mesmo eliminados por completo. Mas, Porque? 

Imagine que as mesmas operações acima, são assíncronas (um app web, SPA por exemplo) e utilizam multi-processamento:

Se "caixa.Depositar(31.4)" fosse uma operação mais demorada que "caixa.ImprimirExtrato()", em um cenário multi-threading, o valor do extrato seria impresso sem considerar o depósito de 31.4, pois as operações executam paralelamente. Então, no mundo imperativo, utilizamos algo como: "caixa.Depositar(double valor, Action callback)" para resolver o problema e então teríamos algo semelhante a isso:


var caixa = new Caixa(10.5);
caixa.ImprimirExtrato(() => {
   caixa.Depositar(31.4, () => {
      caixa.Sacar(5.7, () => {
         caixa.ImprimirExtrato();
      });
   });
});

Certo, e qual o problema com isso?

Além de feio, bizarro e complexo? Observe o método "ImprimirExtrato()". Para essa implementação, eu teria de ter 2 métodos "ImprimirExtrato()" e "ImprimirExtrato(Action callback)" na minha classe Caixa. Um que recebe um parâmetro do tipo Action (para executar um callback) e outro sem esse parametro. Estaríamos aumentando a quantidade de código, os pontos de manutenção e a complexidade pelo simples fato de não utilizarmos o paradigma funcional.


Então eu devo utilizar funcional sempre que trabalho com multi-threading?

Preferencialmente, sim. Mas sempre vai depender da sua necessidade. Se seu problema exige trabalhar com Imutabilidade de estado; trabalhar com o paradigma funcional pode ser de grande ajuda. No geral, sistemas que trabalham com computação matemática, inteligência artificial e processamento paralelo são sistemas onde o paradigma funcional funcionará melhor do que a programação imperativa. Mas podemos ter sistemas tradicionais, aplicações web e em determinados pontos usarmos o paradigma funcional para resolver o problema com maior elegância, eficácia e eficiência.

Ah, se você tem pelo menos mais de 5 anos em desenvolvimento de software, certamente você já teve problemas com inclusão e processamento de arquivos em banco de dados e teve que criar controles absurdos para contornar esses problemas, não foi? Pense como sua vida teria sido mais fácil usando o paradigma funcional (não fica triste não, eu todos já passamos por isso rsrs).

Espero ter ajudado de alguma forma, até a próxima =)