terça-feira, 17 de junho de 2008

Erro esotérico ao inserir clobs e blobs no oracle

A mensagem de erro do Oracle "table or view does not exist" é simples e direta. O problema acontece quando você está fazendo uma série de inserções em uma tabela, utilizando a mesma String de SQL para todas, e lá pela sexta inserção a mensagem de erro aparece:
java.sql.SQLException: ORA-00942: table or view does not exist

Até que você descubra que pode haver algum problema com o sexto registro da tabela, você perde um bom tempo tentando encontrar algum problema de lógica ou alguma desatenção sua. Até mesmo bufa de raiva achando que é algum bug do Oracle. E de certa forma é.

No meu caso descobri que o erro acontecia quando inseria textos grandes demais em uma coluna clob. Encontrei então um documento da oracle explicando como gravar clobs no oracle utilizando JDBC. O macete é configurar o JDBC com o parâmetro SetBigStringTryClob, assim:
Properties propriedades = new Properties();
propriedades.put("user", "meuUsuario" );
propriedades.put("password", "pensaQueVouTeContar?");
propriedades.put("SetBigStringTryClob", "true");
return DriverManager.getConnection("jdbc:oracle:thin:@meuserver.com:filmes", propriedades);

Fazendo isso o estranho erro parou de acontecer. De certa forma acredito que este é um bug do Oracle, pois no mínimo a mensagem de erro deveria ser algo informando que o tamanho do valor excede o permitido na coluna. Ou até informando que não foi possivel inserir devido a erros no preenchimento da coluna tal.

Contudo, essa não foi a unica vez que este erro aconteceu comigo. Ao inserir dados em um campo blob o maldito "table or view does not exist" deu as caras novamente. No caso eu errei o tipo de dado utilizando setString. Mas dessa vez eu já estava calejado, então bastou verificar que para inserir blobs bastaria fazer algo como o mostrado abaixo:
byte[] arr = new byte[] {0,1};
ByteArrayInputStream b = new ByteArrayInputStream(arr);
statement.setBinaryStream(i, b, b.available() );

Mas que fique bem claro que o fato de eu estar inserindo clobs e blobs no banco não quer dizer que eu ache isso uma boa prática e que eu recomende. Ao contrário, acredito que seja melhor na maioria das situações que esses dados fiquem no sistema de arquivos.

sábado, 7 de junho de 2008

Cálculo da variância com Ruby

No blog Kodumaro foi publicado uma comparação de cálculos estatísticos entre linguagens imperativas, como C, e linguagens funcionais, no caso o Lisp. Os cálculos utilizados como exemplificação foram os de variância da população e variância da amostra. Como estou estudando ruby, me empolguei e resolvi fazer a versão desses cálculos nessa linguagem.

Veja como o código ficou:
class Array
def acumula()
acc = 0
each { |a| acc += yield(a) }
acc
end
def media()
total = acumula { |a| a }
total / length
end
def numerador_de_variancia()
m = media
acumula { |a| (a - media)**2 }
end
def variancia_populacional()
numerador_de_variancia / length
end
def variancia_da_amostra()
numerador_de_variancia / (length-1)
end
end
O que fiz foi criar novos métodos na classe Array para fazer todos os cálculos necessários. O interessante é que não encontrei na documentação do Ruby nenhum método que iterasse sobre um array e retornasse um acumulo dos valores calculados por um bloco. Para suprir isso criei então o método acumula.

Apesar do código ter ficado um pouco mais verboso que o código em lisp exibido no Kodumaro, o uso ficou mais simples. Como são novos métodos, para obter a variância da amostra em um array basta por exemplo fazer [2,4,6].variancia_da_amostra. Veja abaixo um exemplo de uso desses métodos:
array = [2,4,6]
puts "Media: #{array.media}"
puts "Numerador de variancia: #{array.numerador_de_variancia}"
puts "Variancia populacional: #{array.variancia_populacional}"
puts "Variancia da amostra: #{array.variancia_da_amostra}"
Mas é importante ressaltar o perigo dessa alteração de classe. Veja que não faço nenhum tratamento sobre o tipo de dado do array. No caso, estou assumindo que todo array que vá utilizar esses métodos tenham sempre todos os indices preenchidos por numeros.

EDS: Excell Driven Scrum

Para quem não sabe, EDS é o Excell Driven Scrum. Ou vocês achavam que siglas com a palavra mágica Driven serviam somente para Development? Estavam enganados. O EDS ocorre quando o P.O. elabora previamente um planejamento, sprint a sprint, do que deve ser feito pelo time para um longo período de tempo. Este planejamento é então gravado em um arquivo excell read-only.

Pelo pouco que entendo de Scrum, esse padrão é uma maneira muito equivocada de se pôr em prática um ambiente de desenvolvimento ágil. Isso porque a definição dos sprints deveria ser feita com a particiação do time. E mesmo se esse tal planejamento anual fosse feito com o time, ainda sim eu consideraria errado, pois é impossivel prever com muita antecedência fatores ambientais que fatalmente mudam as necessidades e problemas que precisam ser resolvidos.

Além disso, o fato de termos escopos definidos para cada sprint, faz o sprint planning 1 ficar engessado. O time perde a liberdade de sugerir histórias prioritárias que garantam a qualidade do sistema. Isso acaba causando um desgaste durante a reunião, o time não entendendo como o P.O. pode ignorar os possiveis problemas da aplicação e os riscos que eles podem causar, e o P.O. sem entender porque o time não aceita seguir o planejamento anual.

Acontece que muitas vezes o uso deste padrão não é culpa do P.O., é uma parte da cultura anterior à adoção do Scrum que ainda não foi possivel mudar. Contudo, não se pode fechar os olhos para este problema. Para acabar com o EDS, é preciso que o P.O. brigue corajosamente contra ele. O time também precisa bater o pé o máximo possivel para mudar esta cultura. E a briga não é apenas para mudar a cabeça de quem está acima hierarquicamente, é também para mudar suas próprias mentes.

Portanto, apesar de ter pouca experiência com scrum, acredito que utilizar o padrão EDS não é uma boa alternativa de implantação dele. Pela minha vivência de menos de um ano e a participação em apenas um curso, me parece que um dos principais benefícios que o Scrum traz é a liberdade que o time tem para identificar problemas e resolve-los para garantir a qualidade do produto. Com o EDS isso não é possivel.

sexta-feira, 6 de junho de 2008

Como obter a URL do SWF

Essa aqui é básica, mas eu procurei bastante no Google e não encontrei. Acabei só achando no help do próprio flash. Caso você precise obter no seu aplicativo flash qual é o caminho completo do seu SWF, basta utilizar a propriedade loaderURL do objeto loaderInfo contido no seu MovieClip. Veja abaixo:

package {
public class Main extends MovieClip {
function Main() {
trace( "URL do SWF: " + this.loaderInfo.loaderURL );
}
}
}