Problema com SQL Server 2000 full-text search (FTS) accent sensitive
Publicado; 02/03/2005 Arquivado em: ColdFusion 5 ComentáriosFor english, see here.
Ontem perdi um belo tempo tentando resolver um problema que não me era estranho, mas não me lembrava. Depois de muito tempo queimando neurônios, um estalo me fez lembrar de tudo. Desta vez vou blogar para não esquecer mais e para registrar para os leitores (e usuários do Google) a solução, bastante estranha, mas eficaz.
Quem me deu a dica na época foi um brasileiro, em alguma lista de discussão (se bobear na própria CF-Brasil), mas agora não consigo me lembrar de quem (caramba, estou precisando tomar fosfosól). Ele merecia os créditos, por isso se você souber quem foi, me avise.
O SQL Server 2000 (assim como outros bancos de dados mais parrudos) oferecem um interessante recurso chamado Full-text search (também chamado de “fulltext”, ou simplesmente FTS). As buscas do tipo full-text são mais rápidas (especialmente em tabelas grandes) e mais inteligentes que as feitas usando o bom e velho comando SQL LIKE. Entretanto no SQL Server 2000 existe um bug (não necessariamente do SQL Server, mas de um componente dele, veja abaixo) que não permite se realizar buscas full-text que sejam accent insensitive (que não diferencia palavras acentuadas das não acentuadas), mesmo se o seu collation do seu banco, tabela ou coluna seja explicitamente configurado como AI_CI (accent insensitive e case insensitive).
O problema parece estar no Microsoft Search Service, responsável pelas buscas do tipo full-text search para o SQL Server 2000. O SQL Server 2000 SP3a vêm com uma versão do Microsoft Search que não realiza buscas do tipo accent-insensitive, ou seja, ele diferencia palavras de acordo com sua acentuação, dificultando bastante a busca, uma vez que as ocorrências de, por exemplo, “Fábio”, serão diferentes das de “Fabio” (sem acento). A versão do mssearch.exe (responsável pelos processos de indexação e busca) que vem com o SQLServer 2000 é a 9.107.x.x.
Ao que parece, outros produtos da Microsoft também utilizam o Microsoft Search, porém com versões mais atualizadas, que suportam buscas accent insensitive, justamente o que precisava. O porquê da Microsoft não ter incluido esta(s) versão(ões) mais atualizada(s) no SP3 do SQL Server 2000 é um mistério para mim, porque na época do lançamento deste service pack certamente já existiam versões mais atualizadas. Talvez o diáologo abaixo, encontrado num transcript deste WebCast e um trecho deste artigo expliquem:
No Webcast:
Otto: Is there any way to have accent insensitive searches? Currently I have to preprocess the search to normalize foreign-accented characters.
Rashid: As far as I know, this has not changed on SP3. I remember reading a question that another customer submitted earlier and, as far as I know, it has not changed as part of SP3, but I think you can now do it on SP3. That will definitely be something that we could follow up and get a definite answer to because I cannot be 100 percent for sure right now.
Follow-up answer: This issue was not fixed in Service Pack 3.
No artigo:
T-SQL improvements–Look for thesaurus support as well as a full-text index creation syntax very similar to the CREATE INDEX syntax used for tables. You may realize that the current versions of Search SQL don’t handle noise words or accents well. Happily, the version of Search SQL that ships in SQL 2005 solves these problems. You can also selectively query one or more columns in your full-text query.
Ou seja, teríamos que esperar o Yukon (SQL Server 2005) para corrigir o problema… Nada disso!
Eis que para salvar nossa pele, existe o Microsoft SharePoint Portal Server 2001 (nem existe mais à venda). Este software de servidor é um destes que tem uma versão atualizada do tal Microsoft Search Service. Nele encontramos a versão 10.145.x.x, que resolve o problema das buscas accent-sensitive. A solução portanto é extrair o Microsoft Search do SharePoint e usá-la. Para isso basta seguir estas instruções. Mas como encontrar o SharePoint Portal Server 2001?
Bem, neste caso tive que fazer uma coisa muito feia, mas bastante comum em terra-brasilis (continue lendo). Como eu sou um cara estressado, e fico com pulga atrás da orelha por não saber registrar dlls e entradas no registry corretamente, resolvi instalar e logo em seguida desinstalar o SharePoint Portal Server 2001 que, confesso, consegui baixar de um site piratão, destes onde se lê “appz” e se reza para não pegar nenhum vírus ao se navegar. Afinal de contas, o que eu preciso não é o SharePoint Server, mas sim a versão atualizada (“corrigida” seria o termo mais adequado) do Microsoft Search, que é gratuíto e parte integrante do SQL Server 2000 Standard, do qual tenho licença (sei que tem gente que não vai acreditar, mas quem me conhece sabe que eu tenho sim). Mesmo assim, vale lembrar que o SharePoint Portal Server 2001, apesar de antigo, existe em versão trial, limitada a 120 dias, mas que atualiza o Microsoft Search de qualquer maneira, mesmo que você desinstale o dito cujo por completo. Eu tinha este CD (que veio num daqueles pacotes MSDN) e poderia tê-lo usado perfeitamente (e legalmente), mas infelizmente joguei fora.
Ao instalar e desinstalar o MS SharePoint Server 2001, seja a versão full ou a trial, o Microsoft Search continua atualizado na 10.145.x.x (ele não retorna à versão antiga) e as buscas do tipo fulltext são agora accent-insensitive. Wonderfull. Nada que uma boa “”reengenharia”” chinfrim não resolva.
Fica aí a dica para os mais desesperados, como eu. 😉
UPDATE: o trial do SharePoint Server 2003 também oferece a versão atualizada do Microsoft Search e pode ser baixado aqui.
Sourceless & Package Creation
Publicado; 23/02/2005 Arquivado em: ColdFusion Comentários desativados em Sourceless & Package CreationClarifying Sourceless Deployment And Deployment Package Creation
Esse assunto inclusive também foi alvo de dúvidas na lista CF-Brasil.
Validação CFFORM e submit via onClick, bug ou o que?
Publicado; 21/02/2005 Arquivado em: ColdFusion 11 ComentáriosSemana passada estava desenvolvendo um website quando surgiu a necessidade de se submeter um formulário (criado com CFFORM) com um link de texto, ao invés de uma imagem ou tradicional botão de submit. Pensei: nada mais simples. Basta chamar a função submit(); invocando JavaScript direto na tag <a> (<a href=”JavaScript:submit();”>) ou usando o método OnClick (<a href=”#” OnClick=”submit();”>).
Mas acontecia um problema estranho: ao se clicar no link para submeter o formulário, toda em qualquer validação necessária para este formulário (justamente o que mais nos interessa na tag CFFORM) era ignorada e o formulário submetido assim mesmo. Campos obrigatórios que eram, por exemplo, deixados em branco, eram submetidos assim mesmo, ignorando a validação gerada pelo CFFORM (atributo required=”yes”).
Confira o problema aqui. Googlei a respeito mas não encontrei nada, apenas alguns relatos de problemas parecidos, porém sem solução. Para resolver o meu problema imediato, acabei encontrando uma forma de contorno (workaround) relativamente simpls, vulgo gambiarra, que funciona bem e que consiste na criação de uma nova função, exclusiva para (1) forçar as verificações pendentes (onSubmit) e (2) submeter o formulário na seqüência, assim (supondo que o seu formulário seja nomeado como “formulario”):
<script language="JavaScript">
function submitform() {
if (_CF_checkformulario(formulario))
formulario.submit();
}
</script>
O workaround pode ser visto em funcionamento também aqui. Na seqüência postei o meu problema na CF-Brasil e tive a ajuda do Fernando Barros que me disse acertadamente não se tratar de um bug do CFFORM, mas sim de algum outro elemento, muito provavelmente o browser, que não estava seguindo uma recomendação do W3, com base nesta informação. É difícil dizer se o problema é simplesmente este, uma vez que a recomendação é bastante clara: o evento submit deve submeter o formulário (o que efetivamente acontece), mas não fala nada sobre eventuais handlers pendentes e existentes para este mesmo formulário. IE, Mozilla/Firefox e Opera apresentam o mesmo problema. Como JavaScript não é necessariamente uma área cujas recomendações do W3 valham, procurei na Nestcape (mãe do JavaScript) qualquer informação a respeito e de novo acertei a água, nada.
Até agora não encontrei nenhuma explicação definitiva e conclusiva. Por isso pergunto: alguém aí sabe de alguma coisa? Poderia nos dar uma luz?
UDF: cardinalParaOrdinal()
Publicado; 20/02/2005 Arquivado em: ColdFusion 4 ComentáriosDisponibilizei uma função que converte um número cardinal (1, 5, 27, etc) para seu correspondente ordinal (que denotam ordem), como primeiro, quinto, vigésimo sétimo, etc. Ela aceita como valor máximo 999.999 (e eu duvido que alguém realmente precise converter para ordinal um número maior do que esse) que convertido para ordinal resulta no belíssimo noningentésimo nonagésimo nono milésimo noningentésimo nonagésimo nono.
Faça o download aqui.
Wallpaper do CFMX 7
Publicado; 18/02/2005 Arquivado em: ColdFusion Comentários desativados em Wallpaper do CFMX 7
Ok, fui eu que fiz (com base num material do SAM), tá meia-boca, mas em começo de namoro a gente sempre anda como uma fotinho do amor em nossa mesa de trabalho não é? Então aproveitem.
OBS: fiz para 1152×864, que é a definição que uso. Tem este outro, que fiz quando do lançamento da versão MX, ainda em 2002.
ColdFusion MX 7 ‘COM’ problema
Publicado; 17/02/2005 Arquivado em: ColdFusion 6 ComentáriosHoje fui instalar o CFMX 7 sob a minha versão do 6.1 em casa. Caramba! A coisa não foi fácil não!
Tudo começou com aquele velho problema do instalador fechar logo depois do extract dos arquivos. Ok, ok… isso está previsto na seção de “troubleshooting” do CF7, mas o que recomendam não adiantou. Eis que apliquei as dicas daqui (que foram adicionadas ao livedocs) e pimba, rodou beleza.
A instalação foi iniciada, passei os passos iniciais, configurei as pastas, coloquei a senha, etc, etc… e no final: PUM! Os conectores do IIS não funcionaram como deveriam e a instalação foi interrompida faltando justamente a parte onde acontece a migração de settings do 6.1 para o 7.0 (migração de datasources, mappings e afins). Vale notar que nesta migração vêm tudo, exceto suas colletions Verity, que agora é uma outra versão, incompatível com a que vinha com o 6.1.
Mas o que raios aconteceu com a instalação? Mas claro! Como eu sou burro! Me esqueci de desligar o “firewall” de TCP/Filter (no nível do kernel) que eu uso no Windows… Bem que o release notes (e já no CFMX 6.1) isso já era avisado. Caramba, como fui esquecer? O conector jamais consegueria configurar nada.
Pensei: calma, nem tudo está perdido, tenho um .car que tive o cuidado de gerar antes de partir para a migração (para vocês verem como eu confio nos upgrades do CF). Interrompida a instalação (com direito a crtl+del e “end application”), reestarto a minha máquina e faço o óbvio: começar tudo de novo. Mas dessa vez vou ser esperto, claro. Já que tudo ficou bichado, com as duas instalações coexistindo, nenhum dos servidores funcionando, dois serviços dentro do windows services, duas pastas distintas (CFusionMX e CFusionMX7) no meu C: (uma puta zona em resumo), vou primeiro desinstalar o CFMX 6.1 pelo menu “Add/Remove” programs. Limpar o que sobrou de sujeira dele no registro e no drive, reiniciar a máquina e repetir a operação com a “semi” instalação do CF7.
Duas horas e uns três reboots depois – não que isso fosse necessário, mas sou usuário Windows das antigas, daqueles que curte dar uma reiniciada na máquina por qualquer motivo – eis que estou com a minha máquina limpinha. Maravilha! Corre instalar o CF7 de novo. Tudo perfeito, tudo funcionando, instalação completada perfeitamente, conectores do IIS tinindo… vamos ver nossas aplicações: vejamos… esta aqui ok, esta outra beleza… epa! O que raios é esse errinho “500 nul” num código que invoca um componente COM?…
Começava mais outra hora de tentativas frustadas de entender o que raios acontecia com o dito cujo e meus componentes COM (inclusive custom tags em C++). Eis que quase perdendo as esperanças vejo o seguinte comentário: “When you uninstall ColdFusion MX 7, COM is disabled“.. Ahhh.. Que ótima notícia! Vamos fazer o que eles sugerem, re-registar a “typeviewer.dll”. Um comandinho simples de DOS e pronto. Reiniciar o CF, rodar a aplicação e…. “500 null”. CARAL&¨%.!
Umas três latas de coca-light, 200 re-registradas da dll de novo, e nada. Eis que encontro este technote e tomo uma decisão radical: vou limar do registro todas as entradas para essa tal de “typeviewer.dll”.
Feito. Uma reiniciadinha a mais (claro…) e vamos lá nós outra vez re-registrar a dll: “regsvr32 cf_rootlibtypeviewer.dll“… Abrir o browser, acessar a aplicação maldita e … pimba! A porcaria do COM voltou a funcionar!! Isso é possível ou eu ando dormindo pouco?
Independentemente, fica o registro da minha dificuldade e um conselho: monte um .car, desinstale o CFMX 6.1 e instale o CFMX 7.0 do zero. 😉
Solução radical? Talvez, mas pelo menos é segura… Afinal de contas, veja só que bela dica a Macromedia dá:
Data sources not recognized
Problem: When you migrate from a previous version of ColdFusion to ColdFusion MX 7, your application does not recognize data sources.
Solution: Redefine the data sources.
Go for it! 😉
Administrator API do CFMX 7
Publicado; 16/02/2005 Arquivado em: ColdFusion 61 ComentáriosIa falar disso logo na seqüência, mas perdi a vez para o Rafa. Vale a pena conferir o post sobre uma nova (e interessantíssima) feature do CFMX 7: Administrator API do CFMX 7
Melhorias para sandbox security no CFMX 7
Publicado; 14/02/2005 Arquivado em: ColdFusion Comentários desativados em Melhorias para sandbox security no CFMX 7Uma das mudanças positivas em termos de segurança que o CFMX 7 trouxe foi a divisão das permissões de acesso à tag CFOBJECT e à função CreateObject(). Nas versões anteriores do servidor esta tag e função deveriam ser desabilitadas para maior segurança em ambientes compartilhados (mesmo usando-se sandbox security) devido à possibilidade de se acessar dados e configurações sensíveis do servidor via Java API. Este é um assunto exaustivamente comentado aqui no CFGIGOLO e em listas de discussão como a CF-Brasil, inclusive com críticas, que quase sempre esbarram na dificuldade de se encontrar um bom provedor de hospedagem ColdFusion no Brasil que ofereça todos os recursos e ao mesmo tempo seja responsável. Uma das maiores críticas à restrição desta tag e função vem do fato de que a função CreateObject() é frequentemente usada para invocar componentes ColdFusion (CFCs) e webservices que são nativos em inúmeras aplicações e também em frameworks famosos tais como o Mach-II e afins.
Pois eis que no CFMX7 a Macromedia encontrou uma maneira de granular o acesso/proibição a esta tag/função, permitindo que se libere o uso de CFOBJECT e CreateObject() com base no tipo de invoke que será feito, que são divididos basicamente em: COM, Java, ColdFusion (CFCs) e Webservices. Com isso poderemos encontrar, numa sandbox (sob a orelha “CF Functions”), quatro opções de enable/disable para CreateObject() ao invés de apenas uma, como antigamente. São as opções “CreateObject(COM)”, “CreateObject(Java)”, “CreateObject(Webservices) e “CreateObject”, esta última que diz respeito somente à CFCs. Na orelha “CF Tags” existe apenas uma opção de CFOBJECT, como antigamente, porém esta é subordinada/obedece o que está determinado na orelha “CF functions”. Entenda: ao se habilitar a tag CFOBJECT, ela só poderá invocar componentes Java, COM ou outros se isso estiver explicitamente permitido através da função CreateObject(Java) e/ou CreateObject(COM) na orelha “CF functions”. O release notes do CF7 explica: “Note: Turning off access to Java, COM, or Web Service objects through the CreateObject function also turns off access through the cfobject tag.”
É uma mudança extremamente bem vinda, que queriamos há tempos. Fiz barulho, batuque de panela e questão de votar como enhancement desejado ainda no programa Alpha 1 do Blackstone, quando eram poucos (ou nenhum) brasileiros pé-rapados e que dependem de hospedagem compartilhada (como eu) participando. Vale lembrar que depois de adotado a melhoria, houve também a correção de um bug importante já no RC, poucos meses atrás, que com a ajuda de vocês foi resolvido. É uma mudança bem vinda especialmente para provedores que não podem oferecer hospedagem do tipo múltipla instância (recurso também melhorado no CFMX7) e que com este enhancement poderão agora resolver 80% da chiadeira dos seus clientes com a proibição ao uso de CreateObject() e CFOBJECT.
E os 20% restantes? Bem, eu sempre fui da opinião de que se você quer usar Java, deve usar Java, se quer usar ColdFusion, use ColdFusion. Misturar os dois é possível? Claro que sim, além de ser altamente recomendável, mas eu pergunto: quais aplicações, das do tipo que são hospedadas em ambiente compartilhado, requerem uso da complexidade de recursos da API do Java ou de componentes COM? Vale notar que componentes COM nem são tão perigosos assim em termos de segurança. Seu invoke via CFMX é relativamente tranquilo pois os componentes podem ser protegidos ad hoc (componente à componente), diferente do que acontece com a API Java, mais difícil, do ponto de vista do CFMX, de se bloquear o uso irrestrito (afinal, o CFMX é uma aplicação Java e precisa acessá-la por inteiro). Oras bolas, o que a API Java tem a oferecer para uma pequena aplicação (que é hospedada num servidor compartilhado) em termos de recursos que não manipular imagens, arquivos e outras firulas do tipo? IMHO estas funções básicas podem ser mimetizadas perfeitamente apenas com os próprios recursos oferecidos pela CFML. Invocar custom tags JSP? Claro que sim! Mas via CFIMPORT por favor… não via CreateObject().
Muita gente chia por ter o Java “bloqueado” no CFMX, mas eu estou para ver quem usa o Java com CFML pra valer, em coisas que não podem ser suplantadas por CustomTags ou CFML puro. Sua aplicação CFML vai invocar EJB? Servlets? Será que é este o tipo de aplicação que se encontra em uma hospedagem compartilhada? Muito raro e difícil, quando acontece a aplicação ou site tem uma importância e tamanho que não justificam sua hospedagem em um ambiente compartilhado tradicional. Por isso deixe de ser muquirana e contrate uma hospedagem dedicada se este for o caso… Enquanto isso viva as melhorias do CFMX 7. 😉
Variáveis locais à funções
Publicado; 13/02/2005 Arquivado em: ColdFusion Comentários desativados em Variáveis locais à funçõesVariáveis locais de funções são variáveis que existem apenas dentro da função, não existindo na página que chamou a função. Dessa maneira, não só a memória é gerenciada de melhor maneira, como também as variáveis da função não interferem nas da página que a chamou, a vice-versa.
Variáveis locais são criadas com a palavra-chave var:
var valor = 3; //dentro de um bloco CFSCRIPT
ou
<CFSET VAR valor="3">
Ao criar UDFs, é comum (e recomendado), já declarar todas as variáveis que você irá utilizar no início da função, com a devida palavra-chave var. Aliás, declaração de variáveis locais só podem ser no início da função.
O problema é que muitas pessoas – inclusive eu – esquecem de declarar como variáveis locais as variáveis de loops!
Veja o código abaixo:
for(i=1; i LTE 13; i=i+1) {
thisDigit = mid(thisCNPJ, i, 1);
somaDigitoDois = somaDigitoDois + thisDigit * aMultipliers[i];
}
O código é parte da função CNPJvalidate() e cria uma nova variávei i. Se já existir uma variável i na página que a chamou, o valor desta será sobreposto pelo novo valor setado nesse loop. O correto seria, no início da função já declarar a variável i, mesmo que com qualquer valor.
Em tempo: as funções CNPJvalidate() e CPFvalidate() já foram atualizadas. 🙂
Ah, e não posso esquecer de dar parabéns ao nosso mais novo milionário!
Senha do RDS do ColdFusion 7
Publicado; 10/02/2005 Arquivado em: ColdFusion Comentários desativados em Senha do RDS do ColdFusion 7Apenas um adendo sobre o post anterior.. Embora a senha do ColdFusion Administrator agora seja melhor criptografada, a senha do servidor RDS não.
Essa continua criptografada via Encrypt()/Decrypt(), com o algorítimo “TripleDES”. É portanto, “raqueável”. Descobrir a chave (e a “seed” que gera essa chave!) é bem mais complicado que antes, sem contar que não é “adivinhável” como antes, mas é possível, e eu posso provar. :o)
Alô administradores!, desabilitem o RDS!