O NeoMatrix Tech está de casa nova!

Você deverá ser redirecionado em 6 segundos. Se não, visite:
http://www.leonelfraga.com/neomatrixtech
e atualize seus favoritos.

Aviso IMPORTANTÍSSIMO!

Aviso aos navegantes:

O NeoMatrix Tech mudou de casa!!!

A partir de agora, acessem pelo novo endereço:

http://www.leonelfraga.com/neomatrixtech

Ué... mas é só o domínio mudou de lugar?

R: Na verdade, não é bem assim hehe. Este domínio que você acessa agora aponta para um blog hospedado no Blogger, enquanto no novo, aponta para um blog na plataforma Wordpress, hospedagem própria, muito mais rápida e com um layout mais agradável de ler ;)

Não vou fechar este domínio igual ao que eu fiz com o NM Light (que já está 100% na nova plataforma). Talvez beeeeeeem depois eu faça isso.

Todos os posts daqui se encontram lá, e novos posts serão colocados somente no novo endereço.
A única coisa que não consegui importar foram os comentários. Mas em breve vai ter um post contando sobre a epopéia que foi migrar o NeoMatrix Tech!

Somente vou fechar a área de comentários daqui. Caso queiram comentar, favor ver o post correspondente no "Novo NeoMatrix Tech" e comentem por lá. É bem melhor! (pena que os permalinks "amigáveis para SEO" não funcionam lá, dá erro 404 e não consigo fazer a configuração funcionar. E olha que eu já vi vários artigos falando desse assunto :( ).

Quem assina o feed, já está lendo o conteúdo do novo NeoMatrix Tech!

quarta-feira, 31 de dezembro de 2008

Retrospectiva Tech 2008 e Feliz 2009!

É, o ano tá acabando!

Muita coisa na nossa área de tecnologia surgiu, como novas ferramentas de desenvolvimento (mais basicamente, novos frameworks e melhorias, como o .NET, o Ruby on Rails, ferramentas para RIA como Microsoft Silverlight, Adobe Flex, entre outros).

E em hardware? A Intel ainda leva uma vantagem nos processadores. Seja com os Core 2 Duo, Core 2 Quad, o novo Core i7. A AMD vai ter que correr atrás com os seus Phenom.

Já em Placas de Vídeo, parece que a nVidia retomou a dianteira com a sua GeForce GTX 260 com 216 processadores, em uma disputa pau-a-pau com a ATI Radeon 4870 (sou um feliz proprietário desta maravilha da ATI/AMD, cuja montagem foi feita pela Sapphire Tech :-) ).

É CrossFire, SLI, Hybrid CrossFire e Hybrid SLI... Tecnologias que servem para que possamos em um primeiro momento economizar na VGA para usar o micro para tarefas não tão pesadas (jogos estado-da-arte) para depois poder barbarizar em um futuro upgrade e ainda economizar energia (as tecnologias Hybrid CrossFire/SLI são utilizadas em conjunto com o vídeo on-board da placa mãe; quando não é necessário muita potência, ele desliga a "vga de verdade" e usa o onboard).

E ainda temos as iniciativas da AMD, chamada de Fusion, que promete uma tremenda econimia de energia e por que não espaço físico, unindo CPU e GPU em um único chip. E a Intel com seus Atom. Os netbooks irão agradecer :-)

E por falar em netbook... Novos modelos de Asus EEE, Positivo Mobo, Accer... Mas, será que vale a pena pagar um preço alto por um deles, já que com o valor (pelo menos, os praticados aqui no Brasil) dariam para comprar um notebook mais potente (ou como dizem, um "notebook de verdade")?

Como diz uma amiga minha, um "luxo desnecessário". Bem, eu pelo menos não acho, já que se é somente para navegar e fazer tarefas bem básicas (editar um texto, planilha, um joguinho bem de leve), a mobilidade proporcionada pelos netbooks não se comparam às de um note. Por enquanto, meu smartphone Nokia N95 está me suprindo bem a necessidade de navegar :-)

E por falar em smartphones... Novos modelos, como os da Sony Ericsson, Samsung, LG, Nokia... e claro, o campeão de hype iPhone 3G.

E a decolagem dos serviços 3G aqui no Brasil também. Os minimodens das operadoras de telefonia celular estão fazendo a festa, mas com um serviço que está deixando muito a desejar. Uma conexão discada é mais estável e rápida até, dependendo do caso :P

E por falar em telefonia... é o ano da introdução (ui!) da portabilidade numérica aqui no Brasil, pelo menos onde não "bomba", e a entrada (uuuui!!) de duas novas operadoras de telefonia celular aqui em São Paulo: AEIOU (Unicel) e a Oi iniciando suas operações por essas bandas.

E que hype foi o início de operação da Oi aqui em SP! Todo mundo correndo para conseguir um chip para falar de graça por três meses. E a turma desbloqueando seus celulares nos quiosques espalhados em shoppings e estações de metrô.

E como não pode deixar de ser, o serviço não está 100%. 3G? Só lá para o final do primeiro trimestre de 2009.

AEIOU? Hum... só foi uma pequena lembrança, assim como foi o Cuil nos serviços de busca.

Sim, o Cuil prometeu ser um serviço de busca com o maior número de páginas indexadas.

Criado por  ex-googlers, teve uma divulgação animal em todo o mundo, em todos os meios: TV, Rádio, Revistas, Internet...

Mas quando o serviço foi posto à prova, decepção... ele tem um jeito diferente de apresentar os resultados, mas estes resultados não era exatamente o que queríamos, sendo muito distorcidos e mostrando coisas nada a ver! Um hype que passou rápido...

E falando em Google, será que teremos uma nova Guerra dos Browsers?

Outra coisa que também teve massiva divulgação foi o navegador Google Chrome. Mais velocidade, maneira diferente de funcionar (um processo para cada aba), navegação privada (o famoso "pr0n mode", ou "porn mode", "modo pornô") um nome como o Google por trás (epa!).

Do outro lado, temos o Firefox e o Internet Explorer. O IE estagnou na versão 7, sendo a 8 já em beta, e o Firefox com a sua versão 3, já com uma 3.1 em vista, que promete um novo motor JavaScript além de outras melhorias.

Aqui nas bandas do meu PC, o Firefox reina absoluto. IE e Chrome somente entram para testar sites. No caso do primeiro, ainda existem sites que são "IE only", mas para esses eu não preciso abandonar o Firefox graças à extensão IE Tab :-) E o IE é utilizado para debugar no VS também...

E o Tio Bill, o que aprontou?

Uma campanha para melhorar a imagem do Windows Vista, parodiando as campanhas I'm a Mac da Apple, a promessa do Windows Seven (que já estou testando um beta :-) ), melhorias no IE, novos serviços em núvem (Skydrive, entre outos serviços do Windows Live), Photosynth.

Por falar em Windows Vista, eu tinha preconceito em relação a ele. Resolvi dar uma chance, e isso mudou radicalmente: estou adorando o Vista. Roda lisinho no meu PC, com todos os efeitos, é mais bonito, mais estável que o XP (que eu tenho em dual boot).

E a turma do Pinguim?

Mais distribuições sendo criadas, o Ubuntu mais do que consolidado como a distribuição preferida para ser utilizada em desktops, melhorias nos ambientes gráficos (KDE 4, Gnome), a eterna corrida para deixar uma maior quantidade de hardware compatível...

Será que 2009 vai ser o "Ano do Linux no Desktop"?

Calma, não vou fazer a famosa piadinha "Ano_Do_Linux = YEAR() + 1".

Por mais que os freetards alegam, eu acho que AINDA não está 100% pronto para o usuário comum. Aquele que quer que qualquer programe funcione. Para esses, o Windows ainda continua sendo a melhor alternativa.

E por falar em freetards, são esses que mancham a imagem do Linux e outros softwares livres.

Falar que um programa é bom por ideologia pura e simples não rola. Tem que ser avaliado o que o usuário quer, aspectos técnicos mesmo. Essa evangelização constante da filosofia por parte dos freetards irrita.

Demonizar uma empresa ou um programa só porque ele é pago já encheu o saco. Por isso que Linux não pega muito bem, e em alguns casos é mal visto.

Eu gosto do Linux, tanto que tenho um Tux de pelúcia aqui na minha mesa, ao lado do monitor, e uso Slackware, Ubuntu, já testei o DSL, entre outros virtualizados.

Uso vários SW Livres, como o Firefox, Audacity para editar áudio, GIMP para dar um retoque nas imagens.

Mas meu SO preferido agora por enquanto é o Windows Vista, meu editor de blogs favorito é o Windows Live Writer, ambiente de desenvolvimento o Visual Studio, linguagem de programação favorita o C#...

Mas o ambiente que eu acho mais elegante de se ver é o terminal do Linux mesmo. As mensagens de boot, o prompt de comando, a estrutura (e a apresentação no prompt) de diretórios, o shell em modo texto poderosíssimo, onde fazemos o que quisermos. Isso me fascina muito.

Nem freetard, nem Wintard, MStard, whathever... Muito menos Appletard, pois não gosto das restrições impostas pela Apple aos seus produtos (fora o plugin Quicktime, não uso mais nada da Apple, e nem possuo produtos da empresa da - ou seria de? hehe - frutinha).

É, em 2008 aconteceu muita coisa em tecnologia!

Eu desejo a todos os leitores que 2009 seja um ano de inúmeras realizações, seja profissionalmente, pessoalmente, tecnologicamente também hehe.

Feliz 2009 a todos, e leiam também a retrospectiva que fiz no NeoMatrix Light :-)

Um grande abraço, e (mais uma vez), Feliz 2009 e Adeus 2008!

Leia o restante deste post...

domingo, 28 de dezembro de 2008

Conciliando Janelas Modais e ASP.NET Validators

Não resisti e postei um artigo antes do fim do ano (viciado é F*** hehe) :P

Você, que seguiu os tutoriais de como utilizar janelas modais com ASP.NET, de como resolver alguns pepinos que acontecem quando usamos o AJAX, agora tem um outro pepininho:

Tem vezes que as janelas modais não disparam quando utilizamos Validators na página!

Acompanhe o seguinte exemplo (design e code-behind parciais):

   1: <div>
   2:     <asp:UpdatePanel ID="upd1" runat="server">
   3:         <ContentTemplate>
   4:             <span>Box 1</span><br />
   5:             <asp:TextBox runat="server" ID="tbx1"></asp:TextBox><br />
   6:             <asp:RequiredFieldValidator runat="server" ControlToValidate="tbx1" ID="Val1" Text="*" ErrorMessage="O Box 1 é obrigatório"></asp:RequiredFieldValidator>
   7:             <span>Box 2</span><br />
   8:             <asp:TextBox runat="server" ID="tbx2"></asp:TextBox><br />
   9:            <asp:RequiredFieldValidator runat="server" ControlToValidate="tbx1" ID="Val2" Text="*" ErrorMessage="O Box 2 é obrigatório"></asp:RequiredFieldValidator>
  10:            <br />
  11:            <asp:Button runat="server" ID="btnSalvar" Text="Salvar" />
  12:            <asp:Button runat="server" ID="btnAbreModal" Text="Abrir Modal" OnClick="btnAbreModal_Click" />
  13:         </ContentTemplate>
  14:     </asp:UpdatePanel>
  15: </div>
  16: <div class="jqmWindow" id="Modal">
  17:     <asp:UpdatePanel runat="server" ID="upd2"><ContentTemplate>
  18:             <span>Box 3</span><br />
  19:             <asp:TextBox runat="server" ID="tbx3"></asp:TextBox><br />
  20:             <asp:RequiredFieldValidator runat="server" ControlToValidate="tbx3" ID="Val3" Text="*" ErrorMessage="O Box 3 é obrigatório"></asp:RequiredFieldValidator>
  21:             <span>Box 4</span><br />
  22:             <asp:TextBox runat="server" ID="tbx4"></asp:TextBox><br />
  23:             <asp:RequiredFieldValidator runat="server" ControlToValidate="tbx4" ID="Val4" Text="*" ErrorMessage="O Box 4 é obrigatório"></asp:RequiredFieldValidator>
  24:             <asp:Button runat="server" ID="btnProcessaModal" Text="Processar Modal" />
  25:             <asp:Button runat="server" ID="btnFecharModal" Text="Fechar Modal" OnClientClick="$Modal.jqmHide();return false;" />
  26:     </ContentTemplate></asp:UpdatePanel>
  27: </div>
  28: <script type="text/javascript">
   1:  
   2:         //Inicializa o Modal
   3:        var $dvUplModal = $('#Modal').jqm({modal:true,toTop:true,trigger:false});               
</script>

Code-Behind:

   1: using System;
   2: using System.Data;
   3: using System.Configuration;
   4: using System.Web;
   5: using System.Web.Security;
   6: using System.Web.UI;
   7: using System.Web.UI.WebControls;
   8: using System.Web.UI.WebControls.WebParts;
   9: using System.Web.UI.HtmlControls;
  10:  
  11: public partial class _Default : System.Web.UI.Page 
  12: {
  13:     protected void Page_Load(object sender, EventArgs e)
  14:     {
  15:         // :-)
  16:     }
  17:  
  18:     protected void btnAbreModal_Click(object sender, EventArgs e)
  19:     {
  20:         string script = "$Modal.jqmShow();";
  21:         /*Algum processamento pode ser feito aqui, por exemplo, alimentar componentes da janela modal antes de abrir:*/
  22:         tbx3.Text = "Um texto qualquer...";
  23:         ScriptManager.RegisterStartupScript(this, this.GetType(), "abremodal", script, true);
  24:     }
  25: }

Como podemos ver acima, o código JavaScript que aciona a janela modal é disparado através de um RegisterStartupScript, via code-behind.

Temos na página quatro RequiredFieldsValidators, sendo dois dentro e outros dois fora da janela modal, porém só iremos salvar os dados (e portanto, validá-los) quando clicarmos no botão "Salvar". O botão "Abrir Modal" somente abre a janela.

Então por que quando clico no botão "Abrir Modal" não acontece nada?

Bem, não é bem "nada" que acontece. Do jeito que se encontra no código acima, os Validators utilizam rotinas JavaScript para executar sua função; estas rotinas em JS são disparadas no momento do postback da página. E é ANTES do postback que a validação é executada: Se algum validator não tiver sua condição satisfeita, a página não é postada para o servidor e o texto do validator irá aparecer.

Então, como resolver este pepino?

Vou descrever algumas das soluções que poderemos aplicar neste caso:

 

Solução 1 - Utilizar um evento HTML para abrir o modal:

Nesta solução, caso utilizemos um botão (ou um ImageButton) ASP.NET para abrir o modal, colocamos a rotina JavaScript para abrir o modal dentro da propriedade OnClientClick (não, embora se chame OnClientClick, isto NÃO é um evento de servidor :-) ), acompanhado de uma instrução "return false" após o comando. Veja como ficou o design deste botão:

   1: <asp:Button runat="server" ID="btnAbreModal" Text="Abrir Modal" OnClick="btnAbreModal_Click" OnClientClick="$Modal.jqmShow(); return false" />

Vendo o HTML que é renderizado no navegador, temos a nossa rotina no evento HTML onClick do nosso botão. Quando clicamos neste botão, o navegador irá executar esta rotina ANTES de postar a página.

Como temos um "return false;" no final do comando, o navegador entende que a rotina deverá ser abortada, e portanto, não é executado nenhum postback. Repare que o evento onClick que codificamos não é mais executado também, exatamente por causa deste "return false" que evita o postback. Utilizamos este artifício no botão "Fechar Modal", já que ele somente fechará o modal, sem processar nada.

Mas, outra coisa: Como a validação é executada via JavaScript, o que será executado primeiro? O nosso código do OnClientClick!

Mas se o evento onClick do code-behind tem um "return false" antes, lá no navegador, que evita o postback, como irei pré-processar algo no servidor quando clico no botão e não quero disparar o validator? Neste caso, devemos abandonar a idéia do OnClientClick, setar a propriedade CausesValidation do botão em questão para false partir para a Solução 2:

Solução 2 - Colocar a propriedade CausesValidation do Botão para False:

Como descrito no final da Solução 1, caso algum processamento tenha que ser feito antes de abrir a janela modal (por exemplo, alimentar alguns controles da janela modal), disparamos a abertura do modal via code-behind e não precise validar o restante da página, colocamos a propriedade CausesValidation do botão que irá executar este código em False.

Fazendo isso, ao clicarmos no botão os validators não serão disparados e nosso código será executado. Veja como ficou:

   1: <asp:Button runat="server" ID="btnAbreModal" Text="Abrir Modal" OnClick="btnAbreModal_Click" CausesValidation="false" />

Mas... tem vezes que o JavaScript do validator ferra com as minhas rotinas JavaScript customizadas... o que fazer?

Eu geralmente não utilizo o validator nú e cru... eu geralmente faço o que vou indicar abaixo.

 

Solução 3 - Disparando os validators via code-behind:

Para disparar a validação via code-behind, ou seja, enquanto o servidor processa a página, devemos desabilitar o JavaScript dos validators. Isto é feito colocando-se a propriedade EnableClientScript de cada validator para false, e depois utilizar a propriedade IsValid dentro do code-behind. Veja o exemplo abaixo:

   1: <asp:UpdatePanel ID="upd1" runat="server">
   2:     <ContentTemplate>
   3:         <span>Box 1</span><br />
   4:         <asp:TextBox runat="server" ID="tbx1"></asp:TextBox><br />
   5:         <asp:RequiredFieldValidator runat="server" EnableClientScript="false" ControlToValidate="tbx1" ID="Val1" Text="*" ErrorMessage="O Box 1 é obrigatório"></asp:RequiredFieldValidator>
   6:         <span>Box 2</span><br />
   7:         <asp:TextBox runat="server" ID="tbx2"></asp:TextBox><br />
   8:        <asp:RequiredFieldValidator runat="server" EnableClientScript="false" ControlToValidate="tbx1" ID="Val2" Text="*" ErrorMessage="O Box 2 é obrigatório"></asp:RequiredFieldValidator>
   9:        <br />
  10:        <asp:Button runat="server" ID="btnSalvar" Text="Salvar" />
  11:        <asp:Button runat="server" ID="btnAbreModal" Text="Abrir Modal" OnClick="btnAbreModal_Click" />
  12:     </ContentTemplate> 
  13: </asp:UpdatePanel>

Com isso, poderemos checar cada validator individualmente, validando somente o que for necessário ao processamento, como no exemplo abaixo:

   1: if (!Val1.IsValid)
   2: {
   3:     string mensagem = Val1.ErrorMessage;
   4: }

Mas... e se eu tenho vários validators na página, terei que validá-los um a um?

Não! Há um jeito mais fácil: Se formos validar todos os validators de uma página, basta varrer a coleção Validators do objeto Page, e ir verificando a propriedade IsValid de dentro de um laço foreach, como no exemplo abaixo:

   1: protected string Validar()
   2: {
   3:     string msg = "";
   4:  
   5:     foreach(IValidator v in this.Validators)
   6:     {
   7:         if (!v.IsValid)
   8:         {
   9:             msg += "- " + v.ErrorMessage + " \n";
  10:         }
  11:     }
  12:  
  13:     return msg;
  14: }

Para começo de conversa, crio uma função especificamente para fazer validação da página, e primeiramente inicializo uma variável que irá conter as mensagens de retorno. Dentro do laço foreach, se a propriedade IsValid do validator que está na iteração for false, concateno sua ErrorMessage dentro desta variável de retorno. A mesma coisa para validações em que não são utilizados validators; se a condição não for satisfeita, concateno com uma mensagem de erro.

Como temos vários tipos de validators na página (CompareValidator, RegularExpressionValidator, RequiredFieldValidator, entre outros), o laço foreach trabalha com a interface IValidator, que todos os validators implementam e possui as propriedades que iremos trabalhar: IsValid e ErrorMessage.

Então, o retorno da função fica: string vazia = válido; string com alguma coisa = inválido.

Beleza, isto faz varrer todos os validators da página... agora, se eu quiser validar os dados ANTES de disparar o modal, porém de muitos campos, em apenas uma determinada área da página, fora do modal obviamente, pois assim ele validará o modal também, e quiser utilizar uma rotina genérica como essa?

Para isso, temos que pensar um pouco no design da página. Agrupar os dados que serão validados dentro de um mesmo contêiner. Isso mesmo, vamos colocar a área que queremos validar dentro de um componente Panel, e varreremos a coleção Controls deste Panel da seguinte forma:

   1: protected string ValidarArea()
   2: {
   3:     string msg = "";
   4:  
   5:     foreach (Control c in AreaAValidar1.Controls)
   6:     {
   7:         if (c is IValidator)
   8:         {
   9:             if (!(c as IValidator).IsValid)
  10:             {
  11:                 msg += "- " + (c as IValidator).ErrorMessage + " \n";
  12:             }
  13:         }
  14:     }
  15:  
  16:     return msg;
  17: }


É isso aí! Um grande abraço a todos :-)

Leia o restante deste post...

domingo, 21 de dezembro de 2008

Feliz Natal e Próspero Ano Novo!

É pessoal, mais um ano se finda.

Estamos na reta final do ano de 2008, onde muita coisa surgiu na tecnologia, seja em hardware, software, gadgets, telecom entre outros.
Então, o que fizeram de bom nesse ano? Qual foi a sua "guinada tecnológica"? hehe

Quero desejar a todos os leitores um Feliz Natal e um Próspero Ano Novo. Que o próximo ano seja de muitas realizações :-)

E ano que vem, mais e mais artigos sobre programação (principalmente :p), análises de aparelhos, programas aqui no NeoMatrix Tech! É, vou tirar umas férias nesse final de ano. Descansar um pouco, pois ninguém é de ferro!

Até lá!

Leia o restante deste post...

domingo, 14 de dezembro de 2008

Portando o Sistema de Controle de Usuários para o SQL Server

Olá pessoal! E aí, tudo indo bem?

Recentemente na empresa em que eu trabalho tivemos a necessidade de fazer um controle de acesso para um dos sistemas que estamos desenvolvendo. Este sistema é web, utilizando a tecnologia ASP.NET, e como eu já tinha o controle de usuários prontinho, só foi pegar ele daqui do N.M. Tech e implementar no programa, certo?

Em partes, explico o porquê:

Para implementar as telas em ASP.NET, foi sem maiores problemas, bastou alterar o CSS da página, e alguns outros detalhes.

Com as classes, a história foi um pouquinho diferente. Além de colocar os arquivos no projeto e alterar o namespace dos mesmos, tive um pequeno problema com algumas particularidades do banco de dados (no caso era o SQL Server), pois o Controle de Acesso é baseado em Firebird, e por conta disso alguns probleminhas em algumas instruções nas classes também. Vamos detalhá-los:

- Modificações no Banco de Dados:

Na parte da estrutura do banco de dados, além da sintaxe e de alguns tipos de dados, no SQL Server não temos generators e as exceptions disparadas pelo usuário funcionam de forma diferente.
O problema com a falta de generators, que utilizei no Firebird para fazer o auto-incremento dos campos, foi resolvido declarando o campo que iria ser alimentado com o valor do generator como identity (que é auto-incrementado) no SQL Server. Veja como ficou a tabela USUARIOS, para ter uma idéia:

   1: /*Original em Firebird*/
   2: create generator GEN_USUARIO_ID;
   3: create table USUARIOS (
   4:     USUARIO_ID integer not null primary key,
   5:     NOME varchar(100),
   6:     LOGIN varchar(15),
   7:     PERFIL_ID integer,
   8:     SENHA BLOB sub_type 0 segment size 80,
   9:     STATUS char(1) default 'A'
  10: );
  11:  
  12: /*Como ficou no SQL Server*/
  13: create table USUARIOS (
  14:     USUARIO_ID int not null primary key identity,
  15:     NOME varchar(100),
  16:     LOGIN varchar(15),
  17:     PERFIL_ID integer,
  18:     SENHA image,
  19:     STATUS char(1) default 'A'
  20: );

O campo SENHA da tabela USUARIOS foi declarado como image (que é um BLOB) no SQL Server.

Outra coisa que teve modificação drástica do FB para o SQL Server foi a procedure SP_INSERE_USUARIO. Ela foi modificada por causa da exception EXC_EXISTE_USUARIO, que é criada no Firebird, porém no SQL Server não temos o comando create exception, e sim a função Raise_Error que é utilizada dentro da procedure.
Portanto, esta função foi usada no SQL Server para disparar a mensagem de erro de usuário existente. Veja como ficou:

   1: /*Original em Firebird:*/
   2: CREATE EXCEPTION EXC_EXISTE_USUARIO 'Login já existente no sistema. Indique outro :-)';
   3: SET TERM ^ ;
   4:  
   5: CREATE PROCEDURE SP_INSERE_USUARIO (
   6:     nome varchar(100),
   7:     login varchar(15),
   8:     perfil_id integer,
   9:     senha blob sub_type 0 segment size 80,
  10:     status char(1))
  11: returns (
  12:     usuario_id integer)
  13: as
  14: begin
  15:     if (not exists(select * from USUARIOS where LOGIN = :login)) then
  16:     begin
  17:         usuario_id = gen_id(gen_usuario_id,1);
  18:         insert into USUARIOS (USUARIO_ID,NOME, LOGIN, PERFIL_ID, SENHA, STATUS) 
  19:         values (:usuario_id, :nome, :login, :perfil_id, :senha, :status);
  20:     end
  21:     else begin
  22:         exception exc_existe_usuario;
  23:     end
  24:     suspend;
  25: end^
  26:  
  27: SET TERM ; ^
  28:  
  29: /*Como ficou no SQL Server*/
  30: CREATE PROCEDURE SP_INSERE_USUARIO (
  31:     @nome varchar(100),
  32:     @login varchar(15),
  33:     @perfil_id int,
  34:     @senha image,
  35:     @status char(1), @usuario_id int output
  36: )
  37: AS
  38:     
  39:     if (not exists(select * from USUARIOS where LOGIN = @login))
  40:     begin
  41:         insert into USUARIOS (NOME, LOGIN, PERFIL_ID, SENHA, STATUS) values 
  42:         (@nome, @login, @perfil_id, @senha, @status);
  43:         select @USUARIO_ID = @@IDENTITY;
  44:     end
  45:     else begin
  46:         Raiserror('Login já existente no sistema. Indique outro :-)',16,1);
  47:     end

Note também uma inversão de instruções: No Firebird, primeiro geramos o ID da tabela com a função gen_id, que recebe como parâmetros o generator a ser incrementado e o fator de incremento, e guardamos o valor na variável usuario_id.
Já no SQL Server, primeiro executamos a instrução INSERT e em seguida pegamos o valor do IDENTITY gerado através de uma instrução select, onde guardamos na variável @USUARIO_ID o valor do ultimo identity gerado através da função @@IDENTITY.

Da parte do BD, é isso, agora vamos às classes :-)

As modificações nas classes foram necessárias por causa de algumas particularidades das instruções SQL utilizadas, que funcionavam no Firebird mas não no SQL Server.
Nas instruções de UPDATE das classes de Perfil e Usuário, originalmente declaramos as chaves primárias (USUARIO_ID e PERFIL_ID), que são auto-incrementadas, na cláusula SET da instrução SQL.
O Firebird simplesmente ignorava, enquanto que no SQL Server uma mensagem informando que campos declarados como identity não poderiam ser inclusos na cláusula SET de uma instrução de update. Os mesmos foram removidos da instrução.
Também teve uma pequena modificação na sintaxe do comando de execução de stored procedure via SQL. No Firebird, utilizamos a sintaxe "execute procedure nome_da_sp(<lista de parâmetros separados por vírgula)", enquanto que no SQL Server utilizamos a seguinte sintaxe: "execute nome_da_sp <lista de parâmetros separados por espaço>". 
Estas modificações farão a classe funcionar nos dois bancos de dados, seguindo a ressalva deste comando de execução de SP, bastando fazer um "if" conforme o BD :-)

Após isso, caso queira somente mudar o mecanismo de banco de dados, utilizando uma biblioteca de classes somente para o Controle de Acesso, ela (como qualquer projeto em que a classe Conexao é utilizada em sua forma original) deve ser compilada seguindo as diretrizes da Classe Conexao (o nosso motor de SQL):
Uma chave chamada "strConexao" deverá ser criada no seu arquivo web.config (para aplicações ASP.NET), e o seu valor deve ser a string de conexão referente ao banco de dados utilizado. Deve ficar assim:

   1: <appSettings>
   2:     <add key="strConexao" value="Data Source=LOCALHOST\SQLEXPRESS;Initial Catalog=USER_CONTROL;
   3:         Integrated Security=SSPI;persist security info=False;Trusted_Connection=Yes"/>
   4: </appSettings>

Esta string de conexão é utilizada para o SQL Server, com autenticação Windows Authentication. Uma boa referência sobre strings de conexão (que é a minha referência, por sinal) é o site Connection Strings.

A Classe Conexao também manda utilizar uma diretiva de compilação conforme o banco de dados a ser utilizado. Para isso, clique com o botão direito sobre o projeto da biblioteca de classes onde se encontra a classe Conexao e selecione a opção Properties. Selecione a guia "Build" na janela em que se abre, e no textbox "Conditional Compilation Symbols" coloque a diretiva correspondente ao provider a ser utilizado:

- SQL Server (utilizando o provider em System.Data.SqlClient): SQLSERVER
- Oracle (utilizando o provider em System.Data.OracleClient): ORACLE
- Firebird (utilizando o provider FirebirdSql.Data.FirebirdClient, podendo ser obtido no site do Firebird): FIREBIRD
- Bancos conectados via ODBC (utilizando o provider System.Data.Odbc): ODBC
- Bancos conectados via OLEDB (utilizando o provider System.Data.OleDb): OLEDB

Veja onde deve ser alterado, no Visual Studio:

 vs-diretivas

Não se esqueça de colocar a referência do provider utilizado no projeto da biblioteca de classes!

Para facilitar o trabalho, clique aqui para pegar o exemplo já portado para o SQL Server, contendo os scripts de criação da base de dados, uma base de dados exemplo (com um usuário cadastrado, chamado "teste", com a senha "teste"), que deve ser atachada ao seu servidor SQL, e a aplicação em si (bibliotecas de classe e o exemplo web).
Ao utilizar o exemplo, não se esqueça de setar a página "login.aspx" como a página inicial do projeto Web!

Logo logo penso em fazer um port para Windows Forms, onde vai ser só migrar a interface de usuário, não as classes ;-)

Um grande abraço a todos, e mais uma vez agradecimentos aos feedbacks positivos que venho recebendo deste site :-)

Leia o restante deste post...

Sobre o NeoMatrix Tech

Meu blog para assuntos profissionais, ligado com tecnologia.
Dicas de programação (grande parte de C# e ASP.NET, mas não limitado a essa plataforma :-) ), dicas de utilitários, análises de equipamentos e serviços, resenhas sobre sites que eu visito, relacionados com tecnologia, opinião sobre mercado de trabalho, metodologias de desenvolvimento, comportamento no mundo tecnológico...

NeoMatrix Light

  © Blogger templates ProBlogger Template by Ourblogtemplates.com 2008 - Editado e configurado por Leonel F.

Voltar ao TOPO