32
julho 2010

The Club - megazine · julho 2010 03 Delphi Trabalhando com Shadowing em bancos Interbase e Firebird 18 Autor: Felipe Santos Desafio The Club ... os periféricos ligados ao computador,

Embed Size (px)

Citation preview

julho 2010

julho 2010

julho 2010 03

Delphi

Trabalhando com Shadowing em bancos Interbase e Firebird 18Autor: Felipe Santos

Desafio The Club

.NET

- Dicas Delphi

29Dicas

- Cruzada

30

Delphi

Banco de Dados

índiceCaracterísticas do MySQL

Editorial Banco de Dados

09Copa do mundo chegou ao fim e

querendo ou não pre-cisamos retomar a ro-tina normal em nosso desenvolvimento de cada dia... 04

WIndows messages em Delphi

05Extraíndo Metadados

12Link: uma nova maneira de pesquisar no .NET

21

LegendaInicianteIntermediárioAvançado

Autor:Bruno Alcarás

Autor: Luciano PimentaAutor: Luciano Pimenta

Autor:Antonio Spitaleri Neto

.NET

Gravando videos com Expression Encoder

26Autor: Djonatas Tenfen

julho 201004

Bem-vindo

Delphi é marca registrada da Borland International, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Antonio Spitaleri Neto - Editor [email protected]

Copa do mundo chegou ao fim e querendo ou não precisamos retomar a rotina normal em nosso desen-volvimento de cada dia. Para auxiliá-los nessa (árdua) tarefa, preparamos uma série de artigos bastante interessantes para esse mês:

Nosso colaborador Luciano Pimenta trabalha dobrado nessa edição e nos traz os artigos: “Extraindo Metadados”, onde mostra a construção de um componente em Delphi para a consulta e exibição de meta-dados de diversos bancos. E “Linq – Uma nova forma de pesquisar em .NET”, onde aborda esse conceito muito interessante para quem utiliza a tecnologia .NET.

Ainda em .NET, Djonatas Tenfen traz o artigo “Gravando vídeos com Expression Encoder”, onde nos apresenta essa ferramenta da Microsoft para a manipulação de vídeo.

Nosso “DBA” Felipe Santos nos mostra esse mês como utilizar o recurso de Shadowing nos bancos Firebird e Interbase no artigo “Trabalhando com Shadowing em bancos Interbase e Firebird ”. Sha-dowing sem dúvida é um recurso muito importante quando se pensa em segurança desses bancos de dados.

Nosso consultor Bruno Alcarás segue em sua “cruzada” para des-vendar o banco MySql. Esse mês ele nos traz em seu artigo “Caracte-risticas do MySql”, informações importantes sobre os tipos de tabelas que podemos criar no MySql.

Por fim, esse mês escrevi o artigo “Windows Messages em Delphi”, onde abordo a importância das mensagens Windows e como podemos utilizá-las para facilitar o desenvolvimento de nossas aplicações.

Boa leitura a todos!

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações: (14) 3732-1529 Suporte: (14) 3733-1588

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club Megazine 2009

Diretor TécnicoMarcos César Silva

Diagramação e ArteVitor M. Rodrigues

RevisãoTassiane Fileto

ColunistasAntonio Spitaleri Neto

Bruno AlcarásDjonatas TenfenFelipe Santos

Luciano Pimenta

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

julho 2010 05

Delphi

Há alguns anos, na época dos sistemas operacionais em modo texto como o MS-DOS, o sistema operacional utilizava o recurso das interrupções de software para se comunicar com os aplicativos que rodavam sob sua “supervisão”. Esse recurso de interrupções pode ser visto ainda hoje no caso da comuni-cação do sistema operacional Windows com os periféricos ligados ao computador, como monitores, teclados entre outros. No caso dos periféricos, as interrupções não são de software e sim de hardware.

Uma interrupção é um sinal que o aplicativo enviava ao sistema operacional solicitando a execução de alguma tarefa. O sistema operacional era condicionado a tratar cada interrupção com um propósito específico, gerando assim as respostas dos aplicativos.

O que são as mensagens Windows?

Windows Messages em Delphi

O recurso de interrupções de software foi abandonado com o advento do sistema opera-cional Windows, por volta de 1994. Esse sistema operacional utiliza um outro recurso para se comunicar com os aplicativos que rodam em sua “jurisdição”. Trata-se das mensagens Windows (no inglês Windows Messages, a forma como são mais conhecidas). Uma mensagem é um sinal que o aplicativo envia ao Windows e o Windows devolve como resposta uma mensagem também. Por essa razão todos os aplicativos Win32 precisam ter uma função de callback para tratar as mensagens que o Windows vai enviar em resposta às solicitações desse aplicativo.

Embora presente em todas as ações feitas pelos aplicativos Win32, as mensagens ficam em segundo plano quando trabalhamos com ferramen-tas “RAD”, como é o caso do Delphi. As classes da VCL “encapsulam” as chamadas a API e o constante envio e retorno de mensagens do Windows neces-sárias ao funcionamento da aplicação.

Um exemplo de funcionamento das mensa-

gens é quando queremos fechar em aplicativo, seja clicando no botão fechar ou teclando alguma combinação para esse fim. O Windows envia a men-sagem ao WM_QUIT ao aplicativo, que encerra suas funções e envia PostQuitMessage para o Windows, para que esse saiba que o aplicativo terminou.

Uma mensagem Windows além da própria mensagem, contém parâmetros que complemen-tam sua funcionalidade. O mais importante é o handle, que é um ponteiro para a janela envolvida no envio ou recebimento da mensagem. Quando manipulamos mensagens Windows, precisamos estar atentos à qual janela estamos enviando a mensagem para determinado fim.

Em Delphi, as mensagens Windows e as cons-tantes Delphi que as representam estão contidas na unit Windows. Cada mensagem possui sua cons-tante para que possa ser utilizada nas aplicações Delphi. Nessa unit também estão as funções da API do Windows utilizadas pelo Delphi.

Para o programador Delphi, o conhecimento

julho 201006

das mensagens Windows, assim como o conheci-mento das API’s do sistema operacional, além de ser indispensável para uma compreensão de como as coisas funcionam sob a plataforma Windows, é de grande ajuda em várias situações no desenvol-vimento de aplicações Win32.

Rotinas que em alguns casos exigiriam alguma ou grande complexidade de código podem ser simplificadas a correta manipulação das mensagens Windows. E em se tratando se grandes projetos, tudo que vier a simplificar o código e a posterior manutenção do aplicativo é de grande ajuda.

Para todas as situações em nossos aplicativos Delphi podemos utilizar manipulação de mensa-gens. É claro que nesse artigo não abordarei todas essas formas nem todas as mensagens Windows disponíveis, pois isso seria assunto para talvez todo um livro.

Uma boa documentação a respeito de mensa-gens Windows pode ser encontrada no próprio help do Delphi, na seção Win32 Programmer’s Referen-ce. É um bom ponto de partida para se trabalhar com mensagens Windows em Delphi.

Utilizando as mensagens Windows em controles VCL

Foi mencionado no início do artigo que toda mensagem Windows precisa de um handle (pontei-ro) para a janela a qual se destina. Quando falamos em janelas no contexto Windows, incluem-se nesse conceito os controles visuais da VCL Delphi, como edits, buttons e listboxes. Todos os controles visuais em aplicativos Win32 são tratados como janelas e portanto podem ser manipulados com mensagens Windows.

Todos os controles VCL Delphi possuem um método chamado Perform, que é utilizado para o envio de mensagens tendo como destino o próprio controle.

Por exemplo, podemos utilizar o método Perform de um controle TEdit para escrever um caractere no mesmo.Veja:

Edit1.Perform(WM_

CHAR,Word(‘1’),0);

Nesse exemplo utilizamos a mensagem WM_CHAR, que insere um caractere no controle. Veja que utilizamos o primeiro parâmetro para indicar qual caractere queremos inserir na edit. Lembrando que os parâmetros para uma mensagem devem ser do tipo int, integer ou word.

Na sequência vamos utilizar o Perform para exibir o conteúdo de um combobox. Primeiro, uti-lizando Perfom, iremos verificar se o combo está aberto e se caso não estiver iremos abri-lo. Veja:

var

iDropDown:integer;

begin

iDropDown:=ComboBox1.

Perform(CB_

GETDROPPEDSTATE,0,0);

if iDropDown=0 then

ComboBox1.

Perform(CB_

SHOWDROPDOWN,1,0);

end;

Veja que utilizamos duas mensagens na com-bo: CB_GETDROPPEDSTATE verifica se o combo está aberto e CB_SHOWDROPDOWN mostra seu conteúdo.

Utilizando SendMessage

O Delphi possui uma função específica para envio de mensagens para o aplicativo. Trata-se da função SendMessage, que utilizaremos para o envio de mensagens nos exemplos a seguir.

SendMessage utiliza quatro parâmetros para sua execução: Handle, que é o endereço da janela destino da mensagem; Msg, onde passamos a constante que define a mensagem; E por fim wParam e lParam que são os parâmetros que a mensagem utiliza.

Com SendMessage combinado com o handle, podemos enviar mensagens a todos os controles contidos em um formulário e para o próprio formulário.

O Delphi fornece uma forma mais tranqüila de capturar o endereço da janela do controle sem a necessidade da manipulação direta de endereça-mento via ponteiros. Todo os controles possuem a propriedade Handle, que retorna um ponteiro com esse endereço. Nos exemplos seguintes estaremos utilizando essa propriedade para fazermos uso de SendMessage.

Vamos a um exemplo onde utilizaremos Sen-dMessage para selecionar uma parte de um texto em um controle TEdit. Veja o código:

procedure SelEdit;

var

Inicio,

iFinal:integer;

begin

Inicio:=StrToIn

t(InputBox(‘Indice

Inicial’,’Inicio’,’1’));

if Inicio >

Length(Form1.Text) then

Exit;

iFinal:=StrToIn

t(InputBox(‘Indice

final’,’Final’,’’));

SendMessage(Form1.

Edit1.Handle,WM_

SETFOCUS,0,0);

SendMessage(Form1.

Edit1.Handle,EM_

SETSEL,Inicio,iFinal);

end;

Nesse exemplo pedimos ao usuário a posição inicial e final a ser selecionada, e depois utilizamos SendMessage para colocar o foco no compo-nente através da mensagem WM_SETFOCUS e

julho 2010 07

depois selecionamos o texto na Edit através de EM_SETSEL.

No próximo exemplo utilizaremos SendMes-sage para rolar um componente RichEdit até sua última linha. Veja o código:

procedure RichEditScroll;

begin

Form1.RichEdit1.Lines.

LoadFromFile(‘caminho

arquivo texto’);

SendMessage(Form1.

RichEdit1.Handle,WM_

VSCROLL,SB_BOTTOM,0);

end;

Veja que nessa utilização do SendMessage, além da mensagem WM_VSCROLL, que executa o “scrolling” do componente utilizamos SB_BOT-TOM em wParam, que é uma constante que diz para a mensagem que o scrolling deve ser para a última linha.

Customização de mensagens Win-dows

Em nossos aplicativos Delphi, além do uso de mensagens através de SendMessage e Perform, podemos customizar algumas mensagens do Win-dows para que atendam a propósitos específicos em nossas aplicações.

Customizar mensagens Windows é criar procedures que irão “substituir” a mensagem em si. Ou seja, quando a mensagem for enviada ao nosso aplicativo, nossa procedure customizada será executada.

No exemplo vamos customizar a mensagem WM_PAINT, que é enviada quando nosso formu-lário é desenhado na tela.

O primeiro passo é declarar na seção private da classe do form o cabeçalho de nossa procedure de customização:

procedure CustomPaint(var

Msg:TWMPaint);message WM_

PAINT;

No cabeçalho definimos o nome de nossa procedure. O parâmetro do tipo TWMPaint é um Record com as informações da mensagem e indicamos qual mensagem queremos manipular precedida da palavra reservada message.

Nossa procedure customizada apenas irá escrever um texto no formulário através da men-sagem WM_PAINT. Veja o código:

procedure TForm1.

CustomPaint(var Msg:

TWMPaint);

begin

inherited;

Canvas.

TextOut(20,20,’Teste

mensagens Windows’);

end;

Vamos a mais um exemplo. Dessa vez custo-mizaremos a mensagem WM_KEYDOWN, que é enviada ao pressionarmos uma tecla. Iremos exibir o código ASCII da tecla em uma label utilizando a procedure de customização. O código é bem sim-ples e segue o padrão da customização anterior.

Veja o código:

procedure TForm1.

CustomKeyDown(var Msg:

TWMKeyDown);

begin

inherited;

Label1.Caption:=’Tecla

Pressionada

‘+IntToStr(Msg.CharCode);

end;

Essa mensagem WM_KEYDOWN pode ser customizada para a codificação de senhas em nossos projetos, além de outras utilizações inte-ressantes.

Controlando as mensagens da aplicação de forma global

Além dos usos que vimos até o momento, podemos criar uma procedure para capturarmos as mensagens que circulam pela aplicação de forma global. Para tal, precisamos utilizar a propriedade OnMessage do objeto Application, que representa nossa Aplicação.

Nossa procedure irá receber as informações da mensagem disparada e tratar algumas em particular. Vale ressaltar que esse monitoramento não interfere na execução das mensagens, a não ser que em nosso monitoramento direcionemos a execução para outro fim.

Antes de atribuirmos ao objeto Application nossa procedure de monitoramento, precisamos ter um nome para a mesma. No nosso exemplo uti-lizaremos MessageMonitor. Declare essa procedure em algum formulário a seu critério. A declaração deverá ficar assim:

procedure

MessageMonitor(var

Msg:TMsg;var

Handled:Boolean);

No OnCreate do formulário onde declarou a procedure, faça:

Application.

OnMessage:=MessageMonitor;

Iremos agora a implementação de nossa pro-cedure de monitoramento. Apenas para exemplo, iremos monitorar as mensagens WM_KEYDOWN e WM_KEYUP e substituir os valores numéricos pelo caractere ‘a’.

Veja o código:

julho 201008

procedure TForm1.

MessageMonitor(var Msg:

TMsg; var Handled:

Boolean);

begin

case Msg.message of

WM_KEYDOWN,WM_KEYUP:

case Msg.wParam

of

48..57:

Msg.

wParam:=65;

end;

end;

end;

Consultor Técnico The Club.

Sobre o autor

Antonio Spitaleri Neto

[email protected]

Veja que quando o código da tecla pressio-nada estiver entre 48 e 57, correspondendo aos caracteres de 0 a 9, trocamos o parâmetro da mensagem para que a aplicação entenda que a tecla pressionada foi a tecla ‘a’. Lembrando que como estamos tratando as mensagens de forma global, essa troca será feita em todos os controles do formulário.

Conclusão

Entender as mensagens do Windows e a forma como as interações em nossos aplicativos depen-dem delas é sem dúvida um passo fundamental para a criação de aplicativos robustos, além da economia de código que a manipulação dessas mensagens pode proporcionar.

Espero quer tenham gostado e até a próxi-ma!

julho 2010 09

Introdução

Quando estamos criando ou fazendo a manutenção de um banco MySQL nos depa-ramos com alguns detalhes que as vezes nem sabemos do que se trata, os tipos de tabela, algumas opções na criação dos campos. Nesse artigo pretendo dar uma pequena explicação dessas características.

Existem vários tipos de tabelas (storage engines) no MySQL, e quando criamos uma temos que definir seu tipo, existem os tipos nativos e os tipos criados por empresas e lançados no mercado. Aqui vai um pequeno comentário sobre os 5 principais tipos nativos do MySQL.

MyISAM

O tipo de tabela MyISAM é o tipo padrão do MySQL, se no momento da criação da tabela não for definido um tipo específico de tabela, essa ta-bela será criada com o tipo MyISAM. Essas tabelas são armazenadas em três arquivos: um que guarda

CARACTERÍSTICAS DO MYSQL

o formato da tabela, outro que guarda os dados da tabela e outro para guardar os índices da tabela.

Algumas de suas principais características são:

• Por ter uma estrutura mais simples, provê uma maior velocidade se comparado a tabela InnoDB;

• Não permite o uso de Foreign Keys;

• O número máximo de índices por tabela MyISAM é 64. Isso pode ser alterada recompilando. A partir do MySQL 5.1.4, é possível configurar a compilação, invocando com o configurar - with-max-índices opção = N, onde N é o número máximo de índices para permitir que por tabela MyISAM. N deve ser menor ou igual a 128. Antes do MySQL 5.1.4, deveria se alterar a fonte.;

• Tratamento interno de uma coluna AUTO_INCREMENT por tabela é suportado. MyI-SAM automaticamente atualiza esta coluna para as operações INSERT e UPDATE. Isso faz com que as colunas AUTO_INCREMENT mais rápidas (pelo menos 10%). Valores no topo da sequência não são

reutilizados depois de ter sido excluída;

• Campos Blob e text podem ser indexa-dos;

• Não são permitidos valores nulos em colunas indexadas, entre outros.

Um dos principais problemas das tabelas MyISAMN reside no fato de que elas possuem um mecanismo de lock por tabelas, fazendo com que todas as vezes que ocorre uma escrita o MySQL trava a tabela toda, bloqueando momoentanea-mente o acesso a mesma gerando assim uma fila de espera até que a tabela seja lberada e outro processoa possa ocorrer.

INNO DB

O tipo de tabela InnoDb foi desenvolvido visan-do o máximo da performance no processamento de volumes gigantescos de informações, por isso sua performance não é igualada por nenhum outro tipo de mecanismo de banco de dados baseados em disco.

julho 201010

As suas principais características são:

• Integridade Referencial;

• Níveis de Isolamento;

• Lock de Registro;

• Possibilidade de criação de Foreign Keys, entre outros;

O InnoDb Mantém sua própria área de buffer que armazena os dados e índices na memó-ria principal. Uma tabela do InnoDB pode consistir em vários arquivos diferente do MylSAM que ar-mazena cada tabela em um arquivo separado. As tabela InnoDB podem atingir qualquer tamanho, mesmo em Sistemas Operacionais que limitam o tamanho desses arquivos.

Por se tratar de um tipo de tabela que tem mais recursos o InnoDB ocupa mais espaço, tanto na memória quanto no disco, e dependendo da situação, pode ter um desempenho, no que diz respeito a velocidade, menor que o MylSAM, mas ainda assim é o tipo mais recomendado para projetos de grande porte e é usado em vários sites com grande banco de dados, alguns com mais de 1TB de dados e outros com carga média de 800 inserçoes ou atualizações por segundo.

InnoDB é publicado sob a mesma licença GNU GPL versão 2 (de Junho de 1991) como MySQL. Para obter mais informações sobre licenciamento do MySQL, consulte http://www.mysql.com/com-pany/legal/licensing/.

. HEAP

As tabelas HEAP são criadas e armazenadas na memória tornando-se assim extremamente rápidas. Elas usam índices hash por padrão o que as torna muito úteis quando se necessita criar tabelas temporárias, mas existe um porém, como são armazenadas na memória se ocorrer uma queda de energia ou o servidor for desligado to-dos os dados armazenados serão perdidos, mas a estrutura da tabela não se perderá, pois fica salva em um arquivo no disco.

Algumas características das tabelas HEAP são;

• Podem ter até 32 índices por tabela, 16 colunas por índice e um comprimento máximo da chave de 500 bytes;

• Colunas indexadas podem conter o valor null;

• Não suportam tipos BLOB ou Text;

• Tem suporte para Auto Incremento;

• O servidor tem capacidade de manter muitas tabelas temporárias em uso ao mesmo tempo;

• Uma tabela muito grande é automati-camente convertida em uma tabela de disco;

BLACKHOLE

Como o próprio nome já diz, as tabelas BlackHole funcionam como um buraco negro, o usuário pode alimentá-las, mas nenhum os dados desaparecerão e nada será gravado nela. Ela é muito útil em um ambiente com replicação de servidores MySQL, pois tira dos usuários a chance de ler ou alterar os dados do banco.

Inserções em uma tabela BlackHole não armazenam dados, mas se o log binário estiver habilitado as instruções SQL serão registradas e podem ser replicadas para outros servidores. Isso é muito útil para funcionar como um repetidor ou mecanismo de filtro.

O Balckhole também pode ser muito útil para:

• Testar a sintaxe de uma instrução, antes do envio;

• Medir a sobrecarga do log binário, comparando o desempenho do Blackhole com ou sem log binário.

MERGE

As tabelas MERGE ou MRG_MyISAM fun-cionam como uma coleção de tabelas MyISAM idênticas. E esse idênticas significa literalmente idênticas com colunas ou índices iguais. Não é possível unir tabelas em que as colunas ou índices

estão em ordem diferente.

É possível usar SELECT, DELETE, UPDATE e INSERT em tabela Merge. Um comando DROP em uma tabela Merge exclui apenas a tabela, não afetando as tabelas MyISAM que ela une.

Para criar uma tabela MERGE, você deve espe-cificar um UNION = (lista-de-tabelas) quais tabelas você quer usar como uma só. Você pode, opcio-nalmente, especificar a opção INSERT_METHOD uma opção se você quiser controlar inserções em tabelas MERGE para ocorrer na primeira ou última tabela da lista UNION.

Veja esse exemplo encontrado no manual do MySQL:

Veja a listagem 1.

As principais vantagens de uma tabela Merge são:

• Facilidade para gerenciar um conjunto de log de tabelas. Os dados podem ser separados em vários arquivos;

• Maior velocidade. Como uma grande tabela pode ser separada, o arquivo em que será feita uma busca é muito menor;

• Faz pesquisas mais eficientes;

• Facilidade de Manutenção;

• Pode exceder o limite de tamanho de arquivo do Sistema Operacional. Uma só tabela MyISAM tem um tamanho máximo, mas um con-junto de MERGE não.

Existem também algumas opções que pode-mos escolher quando definimos um campo, alguns deles são:

ZEROFILL e UNASIGNED

Quando criamos um campo em uma tabela, principalmente usando ferramentas gráficas, ve-mos dois checkbox a serem marcados o zerofill e o unasigned. As primeiras vezes que vi essas opções me perguntei o que significavam, aí vai uma simples explicação de cada um deles:

julho 2010 11

• Zerofill – preenche os espaços não uti-lizados de um campo com zeros, quando utilizado o zerofill o campo automaticamente também será unasigned;

• Unasigned – quando escolhido um tipo de dado numérico, o unasigned não permitirá que existam valores negativos na coluna. Quando um campo é definido com o Auto-Incremento ele automaticamente se torna unasigned.

AUTO-INCREMENTO

O auto-incremento é muito utilizado para se

CREATE TABLE t1 ( -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -> message CHAR(20)) ENGINE=MyISAM;

> CREATE TABLE t2 ( -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -> message CHAR(20)) ENGINE=MyISAM;

-> INSERT INTO t1 (message) VALUES (‘Testing’),(‘table’),(‘t1’); -> INSERT INTO t2 (message) VALUES (‘Testing’),(‘table’),(‘t2’);

-> CREATE TABLE total ( -> a INT NOT NULL AUTO_INCREMENT, -> message CHAR(20), INDEX(a)) -> ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;Se dado um SELECT da tabela total recém criada o resultado será:mysql> SELECT * FROM total;+---+---------+| a | message |+---+---------+| 1 | Testing || 2 | table || 3 | t1 || 1 | Testing || 2 | table || 3 | t2 |+---+---------+

gerar um sequência numérica, principalmente em campos que são chaves primárias. Para que o Auto- incremento seja criado corretamente devemos observar algumas diretrizes:

• O campo deve ser do tipo numérico ou inteiro;

• Uma tabela pode ter um único campo com o Auto-incremento;

• A coluna deverá ser obrigatoriamente indexada.

Conclusão

Espero ter passado nesse artigo uma visão geral sobre algumas características do MySQL, embora existam muitos outros aspectos que não foram abordados nesse artigo mas que são muito interessantes de serem estudados. As tabelas, durante o desenvolvimento do banco, podem ser criadas de diferentes tipos dependendo da sua necessidade e do tamanho que o banco de dados pode ter.

E isso é tudo pessoal, até outra hora.

Referências Bibliograficas

Manual do MySQL

Consultor Técnico The Club.

Sobre o autor

Bruno Alcarás

[email protected]

julho 201012

Por diversas razões e fucionalidades, podemos necessitar mostrar aos usuários da nossa aplicação, alguns objetos do banco de dados, seja por que nosso sistema manipula essas informações (ferramentas de adminis-tração de banco de dados, por exemplo), seja por que precisamos criar funcionalidades com esses objetos (permissões de usuários).

O que vou mostrar neste artigo é como “resgatar” esses objetos (metadados) do ban-co de dados e mostrá-los ao usuário. A parte principal aqui é como fazermos a seleção de dados e suas ligações de tabelas do sistema de um banco de dados.

Para facilitar, vamos colocar essa dica em um componente, assim, o desenvolvimento fica ainda mais simples. Usarei o dbExpress como tecnologia de acesso banco de dados, mas fique a vontade para escolher qualquer outra.

Usaremos Delphi 2010 e o novo driver de acesso ao Firebird, nesse primeiro artigo. No próximo, vamos adaptar o mesmo compo-nente para usarmos o SQL Server.

Extraindo metadadosCrie um componente para extrair metadados do seu banco de dados favorito

Criando o componente

O componente vai selecionar as informações referentes aos metadados de acordo com os parâ-metros informados (tabelas, visões, índices, Stored Procedures etc). No Delphi 2010, crie um novo pa-cote (File>New>Package), salve-o em um diretório a sua escolha, dando o nome de “pkExtract.bpl”.

Adicione uma unit e salve-a como “uEx-tractSQL.pas”. Veja na Figura 1, como esta nosso pacote.

Figura 1. Criando o pacote do componente

Na seção uses declare as seguintes units:

uses Classes, SqlExpr, SysUtils, Provider,

dbClient;

Declare um tipo (enumerador), chamado “TExtractType”, que vai definir os tipos de extração que teremos, assim vamos passar para um tipo qual o objeto que queremos extrair seus meta-dados. Crie a classe com a definição mostrada na Listagem 1 juntamente com o tipo mencionado anteriormente.

Listagem 1. Definição da classe para extrair metadados

type TExtractType = (teTable, teView, teGenerator, teFK, teIndex, teColumns, teProc, teTriggers, teDomain,

julho 2010 13

teException, teUDF);

TExtractSQL = class(TComponent) private ... end;

Vamos declarar uma propriedade do tipo SQLConnection (seção published), por que pre-cisamos da conexão com o servidor, então, para facilitar, vamos usar o componente do dbExpress “encarregado” disso.

Temos que declarar também dois campos na classe, que serão responsáveis pelas consultas SQL (SQLQuery) e pela inclusão dos campos, informações dos metadados que vamos extrair (TStrings):

FLista: TStrings;FQuery: TSQLQuery;

Qual a idéia aqui? O campo do tipo SQLQuery, será conectado ao SQLConnection e fará as consul-tas necessárias no banco. O resultado da consulta (campos, tabelas, índices etc) será adicionado no TStrings, assim, fica fácil de adicionarmos os meta-dados em componentes do tipo ComboBox, ListBox, Memos etc, bem como de mostrarmos os mesmos, usando um for para apresentar cada um.

Vamos criar um método que fará a parte de conexões com o banco, conforme a Listagem 2.

Listagem 2. Criando a conexão com o banco e configurando componentes

procedure TExtractSQL.CreateComponentes;begin { caso não tenha sido atribuído um componente SQLConnection emite uma mensagem de erro } if FSQLConnection = nil then raise Exception.

Create(‘Propriedade SQLConnection não configurada’);

FSQLConnection := SQLConnection;

if not Assigned(FQuery) then begin FQuery := TSQLQuery.Create(nil); FQuery.SQLConnection := FSQLConnection end;end;

Métodos e funções

O CreateComponentes, instância um SQLquery (responsável pelos comandos SQL) e configura a propriedade SQLConnection. Iremos declarar uma constante para cada comando SQL que executaremos. Vamos usar aqui um arquivo sepa-rado (unit) para que fique mais organizado nosso componente.

Crie uma nova unit, dando o nome de “uCo-mandosSQL.pas”. Na Listagem 3, temos alguns dos comandos e os tipos de objetos que vamos recuperar seus metadados (a listagem completa esta disponível nos fontes do artigo).

Listagem 3. Comandos SQL para retorno dos metadados

const TableFB = ‘SELECT RDB$RELATION_NAME ‘ + ‘FROM RDB$RELATIONS ‘ + ‘WHERE ‘ + ‘ (RDB$SYSTEM_FLAG <> 1 OR RDB$SYSTEM_FLAG IS NULL) AND ‘ + ‘ RDB$VIEW_BLR IS NULL ‘ + ‘ORDER BY

RDB$RELATION_NAME’;

ViewFB = ‘SELECT RDB$RELATION_NAME ‘ + ‘FROM RDB$RELATIONS ‘ + ‘WHERE ‘ + ‘ (RDB$SYSTEM_FLAG <> 1 OR RDB$SYSTEM_FLAG IS NULL) AND ‘ + ‘ NOT RDB$VIEW_BLR IS NULL AND ‘ + ‘ RDB$FLAGS = 1 ‘ + ‘ORDER BY RDB$RELATION_ID’;

GeneratorFB = ‘SELECT RDB$GENERATOR_NAME ‘ + ‘FROM RDB$GENERATORS ‘ + ‘WHERE ‘ + ‘ (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG <> 1) ‘ + ‘ORDER BY RDB$GENERATOR_NAME’;ForeignNameFB = ‘SELECT REFC.RDB$UPDATE_RULE REFC_UPDATE_RULE, REFC.RDB$DELETE_RULE REFC_DELETE_RULE, ‘ + ‘ RELC1.RDB$RELATION_NAME RELC1_RELATION_NAME, RELC2.RDB$RELATION_NAME RELC2_RELATION_NAME, ‘ + ‘ RELC1.RDB$INDEX_NAME RELC1_INDEX_NAME, RELC1.RDB$CONSTRAINT_NAME RELC1_CONSTRAINT_NAME, ‘ + ‘ RELC2.RDB$INDEX_NAME RELC2_INDEX_NAME ‘ + ‘FROM RDB$REF_CONSTRAINTS REFC, RDB$RELATION_CONSTRAINTS RELC1, ‘ + ‘ RDB$RELATION_CONSTRAINTS RELC2 ‘ + ‘WHERE ‘ + ‘ RELC1.RDB$RELATION_

julho 201014

NAME = :TableName AND ‘ + ‘ RELC1.RDB$CONSTRAINT_TYPE = ‘’FOREIGN KEY’’ AND ‘ + ‘ REFC.RDB$CONST_NAME_UQ = RELC2.RDB$CONSTRAINT_NAME AND ‘ + ‘ REFC.RDB$CONSTRAINT_NAME = RELC1.RDB$CONSTRAINT_NAME AND ‘ + ‘ (RELC2.RDB$CONSTRAINT_TYPE = ‘’UNIQUE’’ OR ‘ + ‘ RELC2.RDB$CONSTRAINT_TYPE = ‘’PRIMARY KEY’’) ‘ + ‘ORDER BY RELC1.RDB$RELATION_NAME, RELC1.RDB$CONSTRAINT_NAME’;

ColumnsFB = ‘SELECT RDB$FIELD_NAME ‘ + ‘FROM RDB$RELATION_FIELDS RFR ‘ + ‘WHERE ‘ + ‘ RFR.RDB$RELATION_NAME = :RELATIONNAME ‘ + ‘ORDER BY RFR.RDB$FIELD_POSITION ‘;…

Após, adicione a unit, na classe principal do nosso pacote. Vamos criar os métodos Create e Destroy do componente, por que precisamos ins-tanciar o campo do tipo TStrings e liberar o mesmo e o FSQLQuery da memória.

Na Listagem 4 temos o código necessário.

Listagem 4. Create e Destroy do componente

constructor TExtractSQL.Create(AOwner: TComponent);begin inherited; FLista := TStringList.

Create;end;

destructor TExtractSQL.Destroy;begin FQuery.Free; FLista.Free; inherited;end;

Poderíamos instanciar o FLista no método CreateComponentes, sem problemas. Como esta-mos vinculando um componente a outro, através de uma propriedade (SQLConnection), precisamos criar um método para que caso o SQLConnection vinculado, seja excluído, o vínculo do mesmo com o componente também o seja (a variável seja configurada como nil).

Sem esse código, podemos ter um erro no IDE, ao acesso o componente. Veja o código na Listagem 5.

Listagem 5. Método Notification

procedure TExtractSQL.Notification(aComponent: TComponent; Operation: TOperation);begin inherited; if (aComponent = FSQLConnection) and (Operation = opRemove) then FSQLConnection := nil;end;

Vamos implementar agora, uma função, que retorna o comando SQL para o tipo passado como parametro. Veja o código na Listagem 6 (não foi configurado todos os tipos, apenas por questão de espaço).

Listagem 6. Método para retorna o comando SQL correto

function TExtractSQL.GetComandoSQL(aType: TExtractType): string;begin { verifica qual o tipo de consulta e retorna o SQL correspondente } case aType of teTable: Result := TableFB; teView: Result := ViewFB; teGenerator: Result := GeneratorFB; teFK: Result := ForeignNameFB; teIndex: Result := IndexFB; teColumns: Result := ColumnsFB; teProc: Result := ProcFB; teTriggers: Result := TriggerFB; teDomain: Result := DomainFB; teException: Result := ExceptionFB; teUDF: Result := UDFFB; else raise Exception.Create(‘Tipo inválido para a função GetComandoSQL’); end;end;

Na função, simplesmentes retornamos os co-mandos SQL que estão no arquivo uComandosSQL.pas. Vamos agora implementar o método mais importante do componente, ele é responsável por executar o comando SQL, verificar seus parâmetros e preencher a lista (FLista) com os metadados re-tornados. Veja na Listagem 7 o código do mesmo.

Listagem 7. Principal código do componente

function TExtractSQL.Execute(aType:

julho 2010 15

TExtractType; sTable:

string): TStrings;

var

aSQL: string;

begin

{ Instancia campos }

CreateComponentes;

{ retorna o SQL de

acordo com o tipo }

aSQL :=

GetComandoSQL(aType);

FQuery.SQL.Clear;

FQuery.SQL.Add(aSQL);

{ se a tabela não

informada, não precisa de

parâmetro na consulta }

if (sTable <> ‘’) then

FQuery.Params[0].

AsString := Trim(sTable);

FQuery.Open;

FLista.Clear;

if not FQuery.IsEmpty

then

begin

{ adiciona os

metadados na Lista }

while not FQuery.Eof

do

begin

FLista.

Add(Trim(FQuery.Fields[0].

AsString));

FQuery.Next;

end;

end;

Result := FLista;

end;

Como ja comentado, o código anterior é o principal do componente, pois é nele que são exe-cutados os comandos SQL, onde passamos como parâmetro o tipo de extração que queremos e o nome da tabela, quando for o caso, pois podemos passar uma string vazia para a mesma.

Para finalizar a parte de métodos e funções, temos mais duas funções, adicionadas na seção public, que fazem as chamadas ao Execute. É com

essas funções que extrairemos os metadados com o componente.

As funções têm a diretiva overload, pois tem a mesma assinatura, mas com parâmetros diferentes. Utilizaremos essas duas funções, pois nem todas as extrações necessitam do nome do objeto, como por exemplo: tabelas, generators etc.

Veja na Listagem 8 o código das duas fun-ções.

Listagem 8. Código para extrair os metada-dos

function TExtractSQL.

ExtrairMetadados(aType:

TExtractType; sTable:

string): TStrings;

begin

{ verifica se os tipos e

parâmetros estão corretos

e extrai os metadados}

if (aType = teFK) or

(aType = teIndex) or

(aType = teColumns) then

begin

if (sTable <> ‘’) then

Result :=

ExecuteSQL(aType, sTable)

else

raise Exception.

Create(‘É necessário

informar um valor quando

escolher a extração de

índices, colunas ou chaves

estrangeiras’);

end

else

raise Exception.

Create(‘Valor de aType

é inválido para esse

método’);

end;

function TExtractSQL.

ExtrairMetadados(aType:

TExtractType): TStrings;

begin

{ extrai os metadados

sem parâmetros }

Result :=

ExecuteSQL(aType, ‘’);

end;

Note que verificamos o tipo de extração (aType) e se o parâmetro sTable estiver preenchido, chamamos o Execute. Caso contrário, levantamos uma exceção indicando que é necessário preencher esse parâmetro. O mesmo acontece se o valor de aType não estiver dentro das condições (teFk, teIndex ou teColumns).

Instalando o componente

Adicione o código da Listagem 9 onde registra-remos o componente na paleta dbExpress.

Listagem 9. Registrando o componente

procedure register;

implementation

procedure register;begin RegisterComponentsProc(‘dbExpress’, [TExtractSQL]);end;...

Não esqueça de adicionar no Library Path do Delphi o diretório onde estão os arquivos dcu.

Criando um exemplo

Vamos criar um exemplo para testar o compo-nente. Crie uma nova aplicação no Delphi, adicione o componente e alguns Combobox, Memos, Listbox no formulário.

Adicione um SQLConnection, faça a cone-xão com qualquer banco de dados que deseja

julho 201016

e ligue-o ao ExtractSQL, através da propriedade SQLConnection.

Veja na Figura 2 como ficam os componentes disponibilizados no formulário.

No evento OnCreate do formulário vamos

utilizar o código da Listagem 10 para preencher os componentes:

Listagem 10. Extraindo metadados nos com-ponente de tela

cboTabela.Items := ExtractSQL1. ExtrairMetadados (teTable);mmViews.Lines := ExtractSQL1. ExtrairMetadados (teView);mmGenerators.Lines := ExtractSQL1. ExtrairMetadados (teGenerator);mmTriggers.Lines := ExtractSQL1. ExtrairMetadados (teTriggers);mmSp.Lines := ExtractSQL1. ExtrairMetadados (teProc);mmDomains.Lines := ExtractSQL1. ExtrairMetadados (teDomain);mmeException.Lines := ExtractSQL1. ExtrairMetadados (teException);mmUdf.Lines := ExtractSQL1. ExtrairMetadados (teUdf);

Preenchemos os memos com os objetos que não necessitam de parâmetro para a seleção, como por exemplo: tabelas, views e generators. No evento OnChange do ComboBox digite o se-guinte código:

lstColunas.Items := ExtractSQL1.

ExtrairMetadados(teColumns, cboTabela.text);mmFk.Lines := ExtractSQL1.ExtrairMetadados(teFk, cboTabela.text);mmIndices.Lines := ExtractSQL1.ExtrairMetadados(teIndex, cboTabela.text);

O código mostra as chaves estrangeiras e índi-

Figura 3. Extraindo os dados dos objetos do banco

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

ces de acordo com a tabela selecionada no Com-boBox. Na Figura 3 veja o aplicativo em execução.

Veja a Figura 3.

Conclusão

Vimos neste artigo como é fácil criar um com-ponente para extrair metadados do Firebird. O importante é saber exatamente como retornar os respectivos metadados, ou seja, saber o comando SQL correto para retornar essas informações.

Figura 2. Componentes no formulário

julho 2010 17

julho 201018

Olá pessoal,

Vasculhando um assunto bacana para abordar esse mês, me deparei com uma fun-cionalidade dos bancos de dados InterBase/Firebird que existe a muito tempo, desde suas primeiras versões, mas que definitivamente é pouco explorados por seus usuários e admi-nistradores: o recurso de Shadowing. Mas não é qualquer comandinho ou rotinazinha. É uma ferramenta que pode salvar a vida da empresa em caso de pane ou falhas de ambiente.

Ao longo desse artigo, vamos abordar o que é e como funciona em detalhes o Shadowing de bancos de dados InterBase e Firebird.

SHADOWING - DEFINIÇÃO

Como o próprio nome já nos sugere, Shado-wing nada mais é do que uma “sombra” do nosso banco de dados. Funciona assim: quando ativamos o shadowing de um arquivo de banco de dados (um arquivo .gdb qualquer), especificamos um

T R A B A L H A N D O C O M SHADOWING EM BANCOS INTERBASE E FIREBIRD

local, um diretório para a criação de um arquivo-sombra ou mesmo de vários arquivos-sombra – também chamados de shadow file ou shadow set respectivamente. Uma vez ativado o shadow file ou shadow set, o gerenciador de banco de dados passa a tratar esses arquivos como uma extensão do nosso banco de dados principal. Assim, qualquer alteração realizada no banco principal será também realizada no arquivo shadow. Criou uma tabela nova? Inseriu registros? Atualizou uma tabela in-teira? Limpou dados? Não importa! Tudo isso será também gravado e atualizado no arquivo shadow. Em suma teremos uma estrutura exatamente igual ao nosso banco de produção. E isso para que? Bom, em caso de pane no banco de dados de produção, seja porque o arquivo foi apagado acidentalmente ou o disco onde ele estava sofreu uma pane ou mesmo qualquer outro problema físico, podemos rapidamente ativar o arquivo de shadow no lugar do banco perdido, recuperando integralmente nosso ambiente.

CONSIDERAÇÕES IMPORTANTES NO USO DO SHADOWING

O uso de shadowing é muito interessante. Além da segurança que esse recurso nos oferece,

ele tem a vantagem de utilizar o mesmo processo do banco de dados de produção, sem aumentar o consumo de recursos do SGDB. Além disso, shado-wing praticamente não necessita de manutenção e pode ser usado facilmente seja qual for o tama-nho do nosso banco de dados. Mas é importante considerar que o shadowing não chega a ser uma replicação de dados. Isso porque essa atualização do shadow é unidirecional e o shadow file não pode ser acessado diretamente pelos usuários, para garantir sua integridade. Ou seja, não podemos direcionar parte dos usuários usando o arquivo principal e parte usando o shadow file.

Outro ponto importante a considerar é que a criação do shadow file ou do shadow set só pode ser feita em discos físicos locais no servidor Inter-Base/Firebird. Não é possível o uso de shadowing em servidores de rede (locais e/ou remotas) ou estruturas de fitas. Mas é importante e extrema-mente recomendada a criação do shadowing em um disco diferente do disco onde o banco de dados de produção está sendo utilizado. E isso é claro: se der uma pane no disco e o arquivo shadow estava lá dentro também, perdemos todo o sentido de usar o recurso, certo?

Também vale lembrar que o shadowing nos

julho 2010 19

ajuda em caso de problemas relativos a hardware. Se a aplicação ou um usuário danificar o banco de dados em suas estruturas ou dados, essas altera-ções também são gravadas no shadow, pois são espelhos. Por isso o uso de shadowing não nos tira a responsabilidade de realizarmos nossos backups normalmente e diariamente.

OPÇÕES DE SHADOWING

Existem algumas opções de criação e uso do shadowing. A primeira é que podemos trabalhar com shadowing usando um único arquivo ou múltiplos arquivos. Se nosso banco de dados de produção não chega a ser tão grande (menor do que 2 Gbs) podemos usar um único arquivo (um único shadow file). Agora, se nosso banco de dados for muito grande (maior do que 2 Gbs aproximadamente) podemos utilizar vários arqui-vos shadow alocados opcionalmente cada um em um disco diferente, ajudados a melhor inclusive a performance do processo (o que chamamos de shadow set). E mesmo se optarmos por trabalhar com um shadow file, podemos posteriormente mudar e passarmos a usar um shadow set (como veremos na sequência).

Outra opção importante é a podemos traba-lhar com o shadowing em modo Manual ou Auto-mático. Em modo manual, quando, por qualquer razão, o shadow file/set ficar indisponível (pelas mesmas razões anteriores), o banco de dados de produção também ficará indisponível, até que haja uma intervenção que pode tanto desligar o shadow quanto criar um novo arquivo. Esse modo é inte-ressante no sentido de que garante que o banco de dados de produção está 100% atualizado no seu arquivo shadow e que, quando for necessária uma recuperação, o shadow estará completo.

No modo Automático, o banco de dados de produção não para de funcionar caso o shadow file/set fique indisponível. Esse modo é mais transpa-rente para os usuários, pois não depende de uma intervenção para seu funcionamento. Porém não garante que o arquivo shadow esteja exatamente fiel ao banco de dados principal em caso de uma eventual recuperação.

Particularmente prefiro trabalhar com o modo automático e monitorar como está o arquivo sha-dow. Se o mesmo for corrompido, basta recriar o shadow novamente.

CRIANDO O SHADOW

Criar o shadow é muito simples. Não é neces-sário que os usuários estejam desconectados. Basta utilizar uma interface ISQL de sua preferência. Veja-mos o exemplo para criação de um shadow file:

CREATE SHADOW 1 AUTO ‘D:\DADOS\BANCO.SHD’

Onde o número 1 identifica o shadow que está sendo criado e o caminho indica o arquivo shadow a ser criado. O ID serve para que, se precisarmos criar shadow para outros bancos de dados no mesmo servidor, então criaremos o shadow 2, 3, 4 e assim por diante, só para facilitar a identificação. Do lado do ID, podemos indicar com as palavras AUTO ou MANUAL se o shadow será criado em modo Auto-mático ou Manual.

Para criar um set de arquivos shadow temos duas opções. A primeira é definir um tamanho para cada arquivo shadow e a segunda é definir que um arquivo shadow irá se iniciar a partir de um determinado número de paginas de dados. Vejamos os dois exemplos:

CREATE SHADOW 1 AUTO ‘D:\DADOS\BANCO1.SHD’ LENGHT 100000 FILE ‘E:\DADOS\BANCO2.SHD’ LENGHT 100000 FILE ‘G:\DADOS\BANCO3.SHD’

Ou

CREATE SHADOW 1 AUTO ‘D:\DADOS\BANCO1.SHD’

FILE ‘E:\DADOS\BANCO2.SHD’ STARTING AT 100000 FILE ‘G:\DADOS\BANCO3.SHD’ STARTING AT 200000

No primeiro exemplo temos três shadow files, sendo o primeiro e o segundo definidos com um tamanho de 100000 páginas de dados. O tamanho de cada página será o mesmo definido no banco de dados principal. Assim, se o banco de produção utilizar páginas de 8Kb, então cada um dos arquivos terá aproximadamente 800 Mb. O tamanho do terceiro arquivo será de acordo com o necessário e isso é gerenciado automaticamente pelo serviço.

No segundo exemplo temos o primeiro arquivo crescendo até 99999 páginas, já que o segundo arquivo irá iniciar na página de número 100000. E o terceiro arquivo irá começar na página de número 200000, crescendo conforme a necessidade, da mesma forma que no primeiro exemplo.

Ao definir um shadow set iremos utilizar uma das duas formas de criação, não podendo mesclar os exemplos.

Vale reparar também que cada arquivo shadow foi criado em um disco diferente, justamente para melhorar a performance do processo quando em ambientes de grande porte.

É claro que a definição da quantidade e do tamanho de arquivo shadow file pode variar caso a caso e vai da escolha de cada um.

Para verificar se nosso banco de dados está uti-lizando shadow e como ele está definido, utilizamos o utilitário de linha de comando ISQL, rodando o comando SHOW DATABASE:

Veja a imagem 1.

Imagem 1 – Exemplo de execução do comando SHOW DATABASE

julho 201020

DESLIGANDO O SHADOW

Caso não se queira mais trabalhar com o sha-dow, podemos simplesmente desligar o recurso utilizando o comando:

DROP SHADOW 1

ATIVANDO O SHADOW

Se o banco de dados de produção ficar inativo por qualquer razão, podemos então ativar o arquivo shadow no lugar no arquivo principal.

Para fazer isso é necessário garantir que o banco de produção esteja realmente desligado, sem qualquer conexão ativa nele.

Isso posto, basta executar o comando GFIX, conforme abaixo:

Veja a imagem 2.

Depois de ativar o shadow, basta mover ele substituindo o banco de dados de produção, inclusive renomeando o arquivo para o nome do principal. Pronto. Os usuários terão uma base de dados idêntica ao banco de dados que se perdeu/corrompeu.

DICA PESSOAL: Recomendo muito que, antes de liberar para uso, seja feita uma va-lidação, um backup e um restore do arquivo shadow ativado, para garantir que o banco estará totalmente integro antes de entrar em produção.

Depois de reativar o shadow e liberar para uso, agora basta criar um novo shadow sobre o novo banco de produção. Assim vol-tamos a ter o ambiente de shadow pronto e a disposição.

BACKUP E RESTORE

Um ponto importante que precisamos notar é em relação ao nosso processo normal de backups e restores. Quando backupeamos um banco de dados que possui shadow, o mesmo leva a informação de que possui shadows files. Então, na hora de restau-

rar esse backup podemos definir se queremos ou não recriar os arquivos shadow relativos.

Recriar os shadows é uma prática recomen-dada, já que o banco de dados restaurado está totalmente reorganizado e reestruturado. É bom então recriar o shadow file novamente para que ele, como um espelho, “reflita” também ser um banco restaurado.

Mas se não desejarmos recriar, basta utilizar o comando sem a opção indicada:

Imagem 3 – Exemplo do parâmetro de recriar ou não os arquivos shadow no momento do restore, usando a ferramenta IBConsole

Veja a imagem 4.

CONCLUSÃO

Pessoal, espero novamente ter exemplificado um recurso importante de nossos bancos de dados

InterBase e Firebird. Muitas vezes dizemos que esses bancos de dados são muito simples e que não atendem nossas demandas. Mas se analisarmos, a quantidade de recursos que esses bancos dispo-nibilizam e que nós simplesmente não utilizamos é gigante. E em especial o recurso de shadowing. Simples de tudo de se implementar e mais simples ainda de manter. Deveria ser até mesmo colocado como uma rotina nossa em clientes. Chegou, criou um banco de dados? Já cria o shadow dele. E assim por diante. São pequenas ações como essa que salvam “nossas peles”. Sempre que um problema acontece, a culpa acaba caindo sobre o desenvol-vedor ou o fornecedor da tecnologia. Então não nos custo prevenir. Backups e restores constantes, backups diários, validação do banco, uso do Jour-naling System e backups incrementais no caso do InterBase. São assuntos que já abordamos aqui na The Club e que não custa lembrar.

E fica então mais essa dica: usem e abusem do Shadowing. Afinal, um seguro extra não faz mal a ninguém.

Referência:

InterBase 2009 Operations Guide – cap. 7.

Imagem 2 – Exemplo de execução do comando GFIX ativando o arquivo shadow

Imagem 4 – Exemplo da linha de comando GBAK com a opção –kill para não recriar os arquivos shadow files.

Felipe Santos é especialista em InterBase. Trabalha com o InterBase desde 2001. atuando como consultor e instrutor do produto em todo Brasil. Especialista em ambientes críticos. Atua e trabalha com os maiores clientes do InterBase no Brasil. Participante ativo na comunidade, com diversos artigos publicados. Participante do grupo de beta testers mundial do produto. Palestrante em eventos como IB Tour, Borcon Conference, CodeRage Latin América, Delphi Developers Day, Linux Day, entre outros. Atualmente trabalhando na área técnica do InterBase na Presence Tecnologia – agente oficial especializado do produto no Brasil.

Sobre o autor

Felipe Santos

[email protected]

julho 2010 21

Você sabe o que é LINQ? Se não sabe, desculpe, mas amigo você esta deixando o bonde das novidades tecnológicas passar . LINQ é uma linguagem para consultas orienta-das a objetos, desenvolvida pela Microsoft.

Agora vem a pergunta? Para que eu pre-ciso usar LINQ? Você já precisou pesquisar em uma lista, uma coleção? Com certeza, sua resposta será sim. Com LINQ, fica muito mais fácil. OK, vou usar LINQ apenas para isso?

Negativo, você pode usar LINQ para tudo que quiser, a fonte de dados é indiferente, basta ser uma coleção. Temos LINQ para SQL (independente do banco de dados), para usar em XML, LINQ to Entities que é um framework de persistência que utiliza muito o LINQ, entre outros.

Podemos usar LINQ para pesquisar em uma coleção de tipos, outra grande facilidade para o desenvolvimento do dia-a-dia. Bom, chega de conversa e vamos à prática.

LINQUMA NOVA MANEIRA DE PESQUISAR NO .NET

Conhecendo o LINQ

Crie uma aplicação ASP.NET ou Windows Forms no Visual Studio 2010 (pode usar a versão 2008 se quiser). Adicione um botão e um TextBox (com a propriedade MultiLine = true). Nesse primeiro exemplo, vamos usar uma lista simples, onde vamos criar a mesma em tempo de execução e fazer a pesquisa.

No evento Click do botão, use o código da Listagem 1.

Listagem1. Primeiro exemplo de LINQ

StringBuilder sb = new StringBuilder();string[] nomes = { “Luciano”, “Almeida”, “Pimenta”, “Alessandra”, “Castro” };

var pesquisa = from nome in nomes select nome;

foreach (var nome in pesquisa) sb.AppendLine(nome);

textBox1.Text = sb.ToString();

Estamos preenchendo a lista, após, selecio-namos todos os dados da mesma, usando LINQ. No primeiro momento, pode parecer estranho a essa sintaxe, mas ela tem semelhanças com a sintaxe do SQL.

Como não usamos uma cláusula where, todos os dados serão retornados. Precisamos realizar um laço (foreach), por que o retorno do LINQ é uma coleção e precisamos mostrar os itens no TextBox. Execute a aplicação e faça o teste (Figura 1).

Figura 1. Retornando os dados preenchidos na lista

julho 201022

Veja que temos um select nome, indicando que vamos retornar todos os dados contidos na lista. Vamos utilizar filtros nessa pesquisa para trazer os dados que queremos. Para isso, adicione um TextBox e um botão.

Vamos modificar a consulta para retornar apenas onome que for digitado no TextBox. Altere o código para o seguinte:

var pesquisa = from nome in nomes where nome.ToString() == textBox2.Text select nome;

Veja que temos uma cláusula where no código LINQ, onde fizemos o filtro necessário, usando o valor digitado no TextBox (Figura 2).

Figura 2. Filtrando dados com LINQ

Mais exemplos

Fizemos uma pesquisa pelo nome digitado, mas e se digitássemos apenas a inicial do nome? Como fazer? Podemos usar os métodos do C# para manipulação de strings, como o Contains, Subs-tring, Remove, EndsWith, StartsWith etc. Altere o trecho do código para o seguinte valor:

where nome.Contains(textBox2.Text)

Após, basta digitar no TextBox um valor parcial do nome para realizar a pesquisa (Figura 3).

Figura 3. Filtrando dados com LINQ

Note que não precisamos usar o caractere %, como coringa para que a pesquisa seja feita par-cialmente. Agora se precisarmos pesquisar por um valor que inicia ou termina uma string, podemos usar o código da Listagem 2.

Listagem 2. Pesquisando strings pelo inicio ou fim do texto

var pesquisa = from nome in nomes where nome.StartsWith(textBox2.Text) select nome;

var pesquisa = from nome in nomes where nome.EndsWith(textBox2.Text) select nome;

Novamente, a pesquisa é simples. Mas a pes-quisa não diferencia maiúsculas de minúsculas. Então, como resolvemos isso? Simples, igualamos os textos para maiúsculas ou minúsculas, usando o seguinte código:

where nome.ToUpper().Contains(textBox2.Text.ToUpper())where nome.ToLower().Contains(textBox2.Text.ToLower())

Usando tipos

Vamos criar uma classe com suas propriedades e percorrer uma lista desse tipo para mostrar como

é simples essa consulta com LINQ. No código da Listagem 3 temos a definição da classe Mes, com a definição do número do mês, nome e a estação que esta contida naquele mês.

Listagem 3. Classe de exemplo

public enum Estacao{ esVerao = 0, esOutono = 1, esInverno = 2, esPrimavera = 3}

public class Mes{ public int nNumero { get; set; } public string sNome { get; set; } public Estacao sEstacao { get; set; }

public void AddMes(int Numero, string Nome, Estacao estacao) { this.nNumero = Numero; this.sNome = Nome; this.sEstacao = estacao; }}

Temos também um enumerador (Estacao) para indicar as estações do ano. Na Listagem 4 temos a classes Meses que vai conter a lista de meses que vamos adicionar em sua lista (propriedade chamada meses do tipo List<Mes>).

Listagem 4. Classes Meses

public class Meses{ public List<Mes> meses { get; set; }

public Meses() { meses = new List<Mes>(); }

julho 2010 23

public void AddMes(int Numero, string Nome) { Mes mes = new Mes(); mes.nNumero = Numero; mes.sNome = Nome;

if (Numero >= 1 && Numero <= 3) mes.sEstacao = Estacao.esVerao; else if (Numero >= 4 && Numero <= 6) mes.sEstacao = Estacao.esOutono; else if (Numero >= 7 && Numero <= 9) mes.sEstacao = Estacao.esInverno; else mes.sEstacao = Estacao.esPrimavera;

meses.Add(mes); }}

Veja que o método AddMes, recebe como pa-râmetro duas propriedades do Mês. A propriedade Estacao é verificada usando o número do mês. Para testar, adicione em outro formulário um botão é um TexBox. Altere a propriedade TextMode para MultiLine.

No código do botão, teremos o da Listagem 5 onde criamos alguns valores e fizemos uma pesqui-sa na lista, retornando todos os dados.

Listagem 5. Pesquisando tipos com LINQ

StringBuilder sb = new StringBuilder();

Meses meses = new Meses();meses.AddMes(1, “Janeiro”);meses.AddMes(2, “Fevereiro”);meses.AddMes(3, “Março”);meses.AddMes(4, “Abril”);meses.AddMes(5, “Maio”);meses.AddMes(6, “Junho”);

meses.AddMes(7, “Julho”);meses.AddMes(8, “Agosto”);meses.AddMes(9, “Setembro”);meses.AddMes(10, “Outubro”);meses.AddMes(11, “Novembro”);meses.AddMes(12, “Dezembro”);

var pesquisa = from mes in meses.meses select new { sNmMes = mes.sNome, sNmEstacao = mes.sEstacao };

foreach (var mes in pesquisa) sb.AppendLine(mes.sNmMes + “ - “ + mes.sNmEstacao);

textBox1.Text = sb.ToString();

Veja que “tipamos” os campos que serão retor-nados, dando nomes diferentes para os mesmos. Assim, podemos referenciar pelo nome adicionado na consulta quando precisarmos mostrar os cam-pos. Veja na Figura 4 a aplicação em execução.

Figura 4. Pesquisando nos tipos da classe

Podemos agora “brincar” com os filtros do LINQ. Adicione o código a seguir, antes do select, para que possamos filtrar os meses de Janeiro a Maio:

where mes.nNumero >= 1 && mes.nNumero <= 5

Rode e teste a aplicação. Para escolher uma es-tação específica, podemos usar o seguinte código, que vai filtrar os meses da Primavera:

where (mes.sEstacao == Estacao.esPrimavera)

Se quiseremos filtrar pelo nome, basta usar as dicas já mencionadas nesse artigo para o sNome do mês. Veja que continuamos com a mesma sintaxe de pesquisa, com facilidades a mais, pois estamos usando tipos de classes.

Agrupamento, mínimo, máximo, contador

Temos ainda mais exemplos para mostrar, como a necessidade de agrupar determinados valores. Vamos fazer o exemplo, onde agruparemos os meses pela estação do ano, assim, teremos a estação e os meses que fazem parte dela.

Adicione outro formulário e faça a configura-ção, conforme já criamos (TextBox e botão). Para o agrupamento, use o código da Listagem 6.

Listagem 6. Agrupando dados com LINQ

var pesquisa = from mes in meses.meses group mes by mes.sEstacao into grupo select new { estacao = grupo.Key, dadosmes = grupo };

foreach (var estacaogrupo in pesquisa){ sb.AppendLine(“Estacao: “ + estacaogrupo.estacao); sb.AppendLine(“ ** Meses ** “);

foreach (var mesgrupo in estacaogrupo.dadosmes) sb.AppendLine(mesgrupo.

julho 201024

sNome);

sb.AppendLine(“”);}

textBox1.Text = sb.ToString();

Vamos entender como funciona esse código. Primeiro, a novidade fica por conta da cláusula group, onde indicamos qual o campo será agrupa-do. Após, temos a palavra-chave into que é o resul-tado do agrupamento, ou seja, trabalharemos com essa variável para os dados do agrupamento.

O LINQ cria uma chave interna com o resultado do grupo (nesse exemplo os valores são: esVerao, esInverno, esPrimavera, esOutono), chamada Key. Assim, para indicar o valor do grupo, basta chamar a chave interna. Para os campos da consulta, retor-namos o grupo e seus dados do grupo, usando a tipagem dadosmes.

Como o grupo é uma coleção, necessitamos percorrer a mesma para pegar cada resultado retornado. Assim, criamos um laço para percorrer o grupo e dentro desse, outro laço para percorrer os dados do grupo. Assim, podemos indicar o grupo e seus dados no TextBox, como podemos ver na Figura 5.

Figura 5. Agrupando dados com o LINQ

Em um primeiro momento pode parecer confuso, mas a prática leva ao entendimento da sintaxe do LINQ. Para outros comandos, a sintaxe é semelhante, pois fizemos um agrupamento e extraímos as informações, como podemos ver na Listagem 7.

Listagem 7. Usando Min e Max no LINQ

var pesquisa = from mes in meses.meses group mes by mes.sEstacao into grupo select new { estacao = grupo.Key, Min = grupo.Min(mes => mes.nNumero), Max = grupo.Max(mes => mes.nNumero) };

foreach (var estacaogrupo in pesquisa){ sb.AppendLine(“ Grupo: “ + estacaogrupo.estacao); sb.AppendLine(“ Nr Minimo: “ + estacaogrupo.Min); sb.AppendLine(“ Nr Maximo: “ + estacaogrupo.Max); sb.AppendLine(“”);}

textBox1.Text = sb.ToString();

Uma pequena diferença aqui fica por conta do método Min e Max da variável que armazena o gru-po. Precisamos indicar para os métodos o campo que queremos extrair a informação, usando uma expressão Lambda (mes => mes.nNumero).

Rode a aplicação e veja o resultado (Figura 6), onde temos o grupo e o número mínimo e maximo.

Figura 6. Usando mínimo e máximo com LINQ

Para usar o Count a técnica é muito semelhan-te. O único código diferente a ser usado, é esse:

select new{ estacao = grupo.Key, Quant = grupo.Count()};

O uso do método Count da variável do grupo é muito simples. Veja na Figura 7 o exemplo em execução.

Figura 7. Usando um contador do grupo com LINQ

LINQ to XML

Imagine a seguinte situação. No seu ERP é feito o pagamento via cartão de crédito ou débito, cada operadora, possui uma listagem de retorno com códigos de erro. Você pode cadastrar esses erros no banco ou em um arquivo XML para ficar fácil a sua manutenção.

Veja na Listagem 8 a estrutura do XML.

Listagem 8. Estrutura do XML de exemplo

<?xml version=”1.0” encoding=”utf-8” ?><Erros> <Erro> <Codigo>20</Codigo> <Descricao>Parâmetro obrigatório ausente</Descricao>

julho 2010 25

</Erro> <Erro> <Codigo>21</Codigo> <Descricao>Número de filiação em formato inválido</Descricao> </Erro> <Erro> <Codigo>22</Codigo> <Descricao>Número de parcelas incompatível com a transação</Descricao> </Erro> <Erro> <Codigo>23</Codigo> <Descricao>Problemas no cadastro do estabelecimento</Descricao> </Erro> <Erro> <Codigo>24</Codigo> <Descricao>Problemas no cadastro do estabelecimento.</Descricao> </Erro> <Erro> <Codigo>25</Codigo> <Descricao>Formatação incorreta da transação</Descricao> </Erro> <Erro> <Codigo>26</Codigo> <Descricao>Formatação incorreta da transação</Descricao> </Erro> <Erro> <Codigo>27</Codigo> <Descricao>Cartão inválido</Descricao> </Erro> <Erro> <Codigo>28</Codigo> <Descricao>CVC2 em formato inválido</Descricao> </Erro></Erros>

Note que temos um nó principal (Erros) e ou-tro (Erro), que seria uma coleção do nó principal. Dentro do nó <Erro> temos o código e a descrição do erro. Temos que atentar para a estrutura do XML para sabermos onde devemos pesquisar.

Quando retornar um erro na consulta do serviço da operadora, você precisa pesquisar no

XML a descrição do erro retornado. Você pensa: vou usar um DataSet e carregar esse XML e fazer a posterior pesquisa.

OK, não esta errado a sua idéia, apenas acho um desperdício de recursos, instanciar um Data-Set para uma pesquisa. Podemos usar LINQ para isso. Veja na Listagem 9 como pesquisar no XML, usando LINQ.

Listagem 9. Método de pesquisa no XML

using System.Xml.Linq;using System.IO;

...

public string RetornaMensagem(int nCdErro){ string arquivo = “xmlErros.xml”; string sDsMensagem = “”;

if (!File.Exists(arquivo)) throw new Exception(“Arquivo de erros não encontrado!”);

XDocument xml = XDocument.Load(arquivo); var erros = from erro in xml.Descendants(“Erro”) where (int)erro.Element(“Codigo”) == nCdErro select new {

sDsDescricao = erro.Element(“Descricao”).Value };

foreach (var erro in erros) sDsMensagem = erro.sDsDescricao;

if (sDsMensagem != “”) return sDsMensagem; else return “ERRO: Código de erro não cadastrado - Venda não autorizada!”;}

Veja que devemos indicar qual o nó que vamos pesquisar (nesse caso Erro) e qual o “campo” que queremos pesquisar. No caso do campo Codigo, devemos fazer um parse do seu tipo (int) para podermos comparar com o valor passado como parâmetro.

Fizemos um select new para tipar o campo que queremos retornar (sDsDescricao). Poderíamos incluir aqui o código do erro. Após, precisamos percorrer a consulta (mesmo que nesse caso, seja retornado apenas um item), para preencher a vari-ável auxiliar com a descrição encontrada.

Por fim, verificamos se a variável auxiliar possui valor e retornarmos a mensagem, ou indicamos que não foi encontrado o código de erro. Essa consulta com LINQ é muito semelhante as que já fizemos no artigo (Figura 8).

Figura 8. Pesquisando em um arquivo XML

julho 201026

A diferença fica por conta de como pesqui-samos no XML, utilizando um XDocument para carregar o XML e indicando que vamos pesquisar na coleção Descendants do XDocument. Apenas para fins de curiosidade, caso precisássemos pes-quisar uma string, a alteração da consulta, ficaria conforme a Listagem 10 (levando em conta que teremos um parâmetro do tipo string com o nome de sDescricao).

Listagem 10. Pesquisando string no XML

XDocument xml = XDocument.Load(arquivo);var erros = from erro in xml.Descendants(“Erro”) where ((string)erro.Element(“Descricao”)).Contains(sDescricao) select new { nCdCodigo = erro.Element(“Codigo”).Value, sDsDescricao = erro.Element(“Descricao”).Value };

Veja que para string, devemos fazer o mesmo parse, e podemos usar o Contains, visto em outros exemplos desse artigo. Ao percorrer a consulta, teremos agora duas propriedades nCdCodigo e sDsDescrição e poderíamos adicioná-las onde necessitarmos.

Conclusão

Vimos neste artigo, algumas dicas de como usar LINQ em suas aplicações com .NET. Como

já comentei, a primeira vista, para ser algo muito complicado, mas com a prática, temos muitas facilidades para usar LINQ no nosso desenvolvi-mento diário.

Apenas para lembrar que os exemplos mostra-dos aqui, podem ser usados tanto em aplicações ASP.NET, como em aplicações Windows Forms. Um grande abraço a todos e até a próxima!

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

julho 2010 27

Olá, amigos leitores da revista, nesse artigo irei mostrar como gravar o desktop, como colocar ele dentro do Encoder e como publicar o mesmo.

Instalando as ferramentas necessá-rias

Antes de iniciarmos a gravação dos nossos videos vamos precisar fazer download da versão tryal do Expression Encoder 4, a versão trial pode ser encontrada em: http://www.microsoft.com/Expression/try-it/default.aspx depois de realizar o download, execute o arquivo “Encorder_en.exe” e siga os pasos normais de instação.

Gravando

Agora que o Expression Encoder já esta instala-do em nossa máquina execute a ferramenta através do menu Iniciar > Todos os programas > Microsoft Expression > Microsoft Expression Encoder 3 Screen Capture essa ferramenta que vai capturar o nosso Desktop ( imagem 1 ).

Gravando vídeos com Expression Encorder

Imagem 1

Observe que temos 4 Botões, o primeiro é para configurar o Microfone o segundo para configurar a WebCam o terceiro de para Opções, e em fim o quarto botão de gravação, para capturarmos o microfone primeiro click no terceiro botão que é opções então deverá abrir a tela de Settings ( imagem 2 ) depois click em Audio e em seguida selecione o canal do Microfone, feito isso Click em Ok, se tudo ocorrer corretamente o botão do microfone ficará em vermelho indicando que o mesmo está selecionado.

Imagem 2

Ok, agora que temos o microfone configurado podemos iniciar a gravação, click sobre o botão de gravação ( Record ) em seguida irá aparecer uma caixa vermelha no sua tela ( imagem 3 ), essa caixa indica qual a janela que será capturada, indique a

área desejada selecionando com o mouse.

Imagem 3

Agora que a área já está delimitada irá apare-cer uma caixinha semelhante a imagem 4 no canto da tela, essa caixinha indica a altura e a largura do vídeo, lembre-se que isso influência na qualidade do vídeo, esta ferramenta também possibilita esco-lher no caixa de seleção alguns tipos pré-definidos, depois de delimitado a área do Video click no botão Record, nesse momento aparecerá uma tela informando as teclas de Atalho Ctrl + Shift + F11 para iniciar ou pusar a gravação, e Ctrl + Shift + F12 para dar parar a gravação, assim que essa tela for confirmada uma contagem regressiva irá aparecer na tela para dar início a captura.

Imagem 4Grave seu vídeo conforme sua necessidade, a

julho 201028

Trabalha a quase 7 anos com Delphi, trabalha na empresa Benner Sistemas (www.benner.com.br ) na área de tecnologia desenvolvendo fer-ramentas em Delphi e como hobby e visão de mercado está migrando seus conhecimentos para a plataforma .NET. Faz parte do grupo .NET Blumenau http://dotnetblumenau.ning.com/ . Possue certificação 70-536 (Microsoft .NET Framework 2.0 Application Development Foundation ) . Twitter: djonatastenfen - blog http://www.djonatastenfen.blogspot.com/

Sobre o autor

Djonatas Tenfen

[email protected]

partir deste momento tudo o que aparecer dentro da área determinada anteriormente irá aparecer no vídeo, quando desejar finalizar a gravação tecle Ctrl + Shift + F12 para parar a gravação.

Assim que a gravação finalizar ele irá fazer uma pré-compilação do Video e irá mostrar na tela dentro de um Player temporário ( imagem 5 ), que possui as opções de Play, barra de progres-so, Exclusão que elimina o video gravado, Salvar, Maximizar, e a mais importante transferir para o Expression Encorder, caso o video não tenha sai-do como esperado click na em excluir para que o vídeo seja eliminado e abrindo a possibilidade de gravar um novo vídeo, se estiver tudo Ok click no botão do Louch Expression Encorder, nesse ponto ele vai pedir para indicar um lugar para salvar o Video, indique um lugar de sua preferência em seu computador e aguarde a abertura do Expression Encorder.

Imagem 5

Renderizando

Ok, agora que já gravamos o video vamos ren-derizar o video no Expression Encorder, observe que o Expression Encorder possui uma interface muito semelhante aos outros editores de video como o Movie Maker, SonyVegas entre outros, a visão inicial é a da Imagem 6 ( sem as caixas de marcação)

Veja a Imagem 6.

Para compreender melhor irei fazer uma pré-apresentação do que tem disponível no Expression Encorder.

Marcação 1: tem a barra de menus aonde po-demos acessar as principais configurações e opções da ferramenta, configurações de TimeLine,etc.

Marcação 2: Possui a visualização do video que está sendo editado, podemos acompanhar através dessa marcação como o vídeo ficará quando renderizado.

Marcação 3: Essa marcação é uma das ou se não a mais importante, temos logo acima o player para controlar o a marcação 2 e logo a baixo tem a guia da Media Content que contém todas as Medias envolvidas no projeto.

Marcação 4: Propriedades e configurações, a guia que nos interessa neste artigo é o Output e Encode que será explicada no próximo tópico.

Marcação 5: Nesta marcação é um comple-mento da marcação 3,e possui o botão Encode que inicia a renderização do projeto.

Configurando Output

Na Marcação 4 da imagem 6 tem a opção “Output” e dentro da opção “Output” tem a barra denominada “Job Output” na opção “Template” é possível escolher o template do player, escolha o template de sua preferência na caixa de seleção, observe que logo abaixo irá aparecer uma caixinha do Preview apresentando como ficará ( vá com o mouse sobre o preview para aparecer o Player ), logo abaixo tem a opção Media File Name, deixe a opção padrão { Original File Name}.{Default extencion} e por ultimo selecione um diretório de sua escolha na opção Directory, agora que já configuramos o caminho e como queremos que fique o video vamos configurar o tamanho do video, na mesma marcação 4 ( imagem 6 ) click em “Encode”. Na opção de de Encode tem a opção de várias opções a que vamos alterar está na barra “Video”, tem as opções de Width e Height, altere conforme for de sua preferência, lembre-se que esse será o tamanho a ser apresentado, quando maior o tamanho maior o arquivo também.

Publicando

Ok, agora que já alteramos o output do proje-to, alteramos o tamanho de apresentação vamos publicar, para publicar é bem simples, basta clicar no botão Encode ( marcação 5 da imagem 6 ) nes-se momento o projeto será renderizado para um arquivo wmv e assim que finalizar a renderização, o Browser default irá abrir com a página do Video. Para publicar o video em na internet, basta copiar todo o conteudo da pasta definina na propriedade Directory do Output para o seu site na internet e pronto, seu vídeo estará na publicado.

Coclusão

Com esse artigo concluimos que Silverlight esta cada vez avançando mais nos recursos de Media oferecendo mais opções aos desenvolvedores e até mesmo publico em geral, nesse artigo vimos que é possível gravar vídeo aulas com a ferramenta Microsoft Expression Encorder de forma simples prática e rápida, muito menos de outra tecnologia. Espero que tenham gostado do artigo e até a próxi-ma, dúvidas, críticas e elogios são bem vindos.

Imagem 6

julho 2010 29

Dicas DELPHI

Anuncie

conosco

Solicite um orçamento:

Skype: theclub_cadastro

E-mail: [email protected]

Fone: (14) 3732-1529

Anuncie na revista e ganhe um

banner publicitário no site do The Club

3 – Validar IP

function ValidarIP(ip: string): Boolean;var z, i: byte; st: array[1..3] of byte;const ziff = [‘0’..’9’];begin st[1] := 0; st[2] := 0; st[3] := 0; z := 0; Result := False; for i := 1 to Length(ip) do if ip[i] in ziff then else begin if ip[i] = ‘.’ then begin Inc(z); if z < 4 then st[z] := i else begin ValidarIP := True; Exit; end; end else begin ValidarIP := True; Exit; end; end; if (z <> 3) or (st[1] < 2) or (st[3] = Length(ip)) or (st[1] + 2 > st[2]) or (st[2] + 2 > st[3]) or (st[1] > 4) or (st[2] > st[1] + 4) or (st[3] > st[2] + 4) then begin ValidarIP := True; Exit; end; z := StrToInt(Copy(ip, 1, st[1] - 1));

if (z > 255) or (ip[1] = ‘0’) then begin ValidarIP := True; Exit; end; z := StrToInt(Copy(ip, st[1] + 1, st[2] - st[1] - 1)); if (z > 255) or ((z <> 0) and (ip[st[1] + 1] = ‘0’)) then begin ValidarIP := True; Exit; end; z := StrToInt(Copy(ip, st[2] + 1, st[3] - st[2] - 1)); if (z > 255) or ((z <> 0) and (ip[st[2] + 1] = ‘0’)) then begin ValidarIP := True; Exit; end; z := StrToInt(Copy(ip, st[3] + 1, Length(ip) - st[3])); if (z > 255) or ((z <> 0) and (ip[st[3] + 1] = ‘0’)) then begin ValidarIP := True; Exit; end;end;

julho 201030

VerticalHorizontal

julho 2010

julho 2010