terça-feira, 29 de maio de 2007

Arquiterura Cliente-Servidor: Back-end

O conceito de máquinas em níveis tem como proposta fazer com que o usuário final enxergue um sistema computacional somente através do aplicativo. Este conceito está tão incorporado em nossa cultura que, hoje, para uma pessoa utilizar um aplicativo, editor de texto por exemplo, e imprimir o resultado de um trabalho, não demanda da parte dela nenhum conhecimento sobre informática.

No modelo cliente servidor esse conceito também esta presente. Ou seja, concebemos uma aplicação de banco de dados como um único sistema. E devemos faze-lo de maneira que o usuário o enxergue desta forma. Entretanto, essa aplicação na verdade é um sistema composto por dois programas. Um aplicativo que é executado pela máquina que requisita o serviço, os chamados Cliente(Front-end), e o back-end que é a sua base de dados fica num servidor. Todavia, devemos entender, agora, “base de dados” não mais como um arquivo, passivo, mas como um sistema, programável, que gerencia o acesso, a manutenção, a atualização e a integridade da base de dados. Logo, podemos definir da seguinte forma:

  • Um banco de dados é uma coleção de tabelas relacionadas, onde cada tabela armazena um específico conjunto de dados. Ele também é um container para outros objetos que o auxiliam no gerenciamento destes dados.

A maior parte do esforço do desenvolvimento, cerca de 75%, fica no back-end. No SGBD são definidos e programados todos os processos que serão executados no servidor.
Para uma explicação mais clara, seria interessante comparamos e enfatizarmos a separação entre os Servidores de Banco de Dados(SGBDs) dos Servidores de Arquivo(banco de dados local).




SGBD x Servidor de Arquivos

Para uma rápida compreenção, podemos explicar os SGBDs a partir dos já conhecidos bancos de dados locais. Programas como Paradox, Visual dBase e Access que geralmente operam no modelo flle-server(Servidor de arquivos). Como isso funciona?
Em banco de dados flle-server, toda a inteligência do banco reside no software cliente. Embora que o banco de dados resida no servidor remoto, este servidor não tem inteligência para gerenciar o banco. Quais são as implicações que isso pode trazer?
Por exemplo: Quando você quiser realizar uma operação nas tabelas do banco, tudo é copiado para a memória do computador client que está requisitando tal operação. Vejamos, se você quiser executar uma query numa tabela de Clientes que conténha 2.000.000 de registros:

SELECT NOME
FROM CLIENTES
WHERE ID_CLIENTE =1;

Temos como objetivo que seja retornado apenas a coluna NOME do cliente 1, porém no modelo servidor de arquivos toda a tabela CLIENTES, ou seja, todas as colunas e todos os 2.000.000 registros serão transportados para a memória da máquina cliente, e, só então, lá será executada a filtragem.
No modelo client-server o banco de dados não é apenas um arquivo, ou melhor, não é uma pasta contendo vários arquivos(que seriam as tabelas e os índices). Mas sim um programa, um sistema que controla e gerencia o banco, onde reside toda a inteligência do banco de dados. Este programa prove um serviço de acesso, armazenamento e manipulação de dados. Como assim?
No modelo cliente servidor o mesmo exemplo mostrado anteriormente transportaria apenas a coluna NOME do cliente, cujo o código seja igual a 1, para o software cliente . É importante destacarmos que todo o processamento recorrente da nossa requisição acontece no servidor. Ora, podemos concluir então que: se existe processamento no banco agora, eu posso pegar os processos que antes estavam todos codificados no sotware cliente, e dividi-los com o programa de banco de dados.
O modelo client-server reduz significantemente o tráfego de rede. Isto provê uma melhor integridade no banco e o torna mais poderoso, já que todo o gerenciamento do software fica em único lugar. No modelo file-server cada máquina client precisará ser um tanto poderosa. Isto porque a parte inteligente(que gerencia e controla o banco) estará nos clients. Portanto, essas máquinas serão bastante exigidas no que tange a processamento e armazenamento temporário de informação. Em contrapartida no modelo client-server somente a máquina server precisará ser poderosa.
Objetos de DB

Domains (Domínios):
Tipo de dados, pode ser definido pelo programador. Subdividem-se em:
Domínios simples e Domínios compostos. Os Domínios quando bem aplicados funcionam
como uma forma de desacopalmento do seu modelo (físico) de dados em relação ao mundo real.
Ao fazer uso desse recurso, você centraliza regras sobre os dados, as quais deverão garantir
que não seja “inputado” lixo, de maneira que seu SGBD fique mais organizado, conseqüentemente
reduzindo drasticamente a possibilidade do seu banco de dados, com o decorrer do tempo, se tornar um “Bando de dados”.

Tables (Tabelas):
Objeto para armazenamento de dados. É uma estrutura homogênia, que armazena os
dados sob uma referência coluna/Linha.

Indexes (Índices):
Como o nome já indica, indexa os dados crescente ou decrescentemente. Basicamente
você pode entender índices como uma tabela, uma meta tabela, que armazena o
endereço físico do dado. Alguns definem como: Lista com ponteiros em tabela,
usado para prover performance.

Constraints:
A) Definem relacionamento entre as Tabelas. Verificador de integridade de dados.
B) Checks : Garantem que somente valores permitidos sejam armazenados (Regras de negócio).

Views (Visões):
Uma consulta que regularmente você precisa fazer, pode ser definida em forma de
uma View. A partir de então vc poderá consultar diretamente, referenciando em
código a View criada. Uma consulta cujo o código demande um número exagerado de
código pode ser fatorada em Views.

Stored Procedures (Procedimentos Armazenados):
Código armazenado no banco. São procedimentos que serão executados ad-hoc,
ou vinculados a uma Trigger.

Generators/Sequences: Contadores de auto-incremento.

Triggeers (Gatilhos):
Código executado em resposta a algum evento sobre uma tabela no banco.
Usado para manter integridade nos dados e segurança.

Role: Papéis contendo privilégios que serão atribuídos aos usuários. Segurança.


Artigo completo (View Full Post)

Data Pump : Migrando dados


Coisas antigas, podem estar esquecidas, podem ser desconhecidas para os mais novos ...
Encontrei um material antigão aqui, quase da época das cavernas .. hheheheh ... La vai

O Data Pump, um programa que é instalado na instalação do Delphi. Usamos o Data Pump para mover os registros de um banco de dados para outro. Onde, obviamente, um será a fonte e outro o destino. Esse processo pode ser feito independente do modelo de dados do seu sistema. Isso é muito conveniente quando precisamos migrar dados de um banco de dados local (file/server) para um Cliente/Servidor(SGBD). Todavia, nada impede que isso seja feito entre dois SGBDs de tecnologias diferentes (exemplo, SQL server para Oracle), ou não. Ou dois bancos locais, Paradox X Paradox, ou Access X Paradox.
Vamos simular uma situação, muito comum, de migração para que possamos apresentar a ferramenta DataPump. É preciso para isso que criemos uma base vazia, Interbase, ou Fire Bird, para a qual migraremos os dados contidos num banco Paradox. Portanto, No Ibconsole criaremos um banco de dados e o nome do arquivo será DbMigrante.gdb. Mas, antes crieuma um diretório para isso: Exemplo C:\ExemploDataPump\DbMigrante.gdb. Escolhi essas duas tecnologias de banco de dados porque as duas estão disponíveis no cd de instalação do Delphi.

Exemplo de como usar o DataPump


Ficou diodo amigo, vai falar sobre uma coisa ultrapassada? O Data Pump se conecta as bases de dados para a migração através da BDE. Ela foi a primeira middleware de acesso a dados da Borland. Hoje, esta descontinuada, mas o Delphi ainda suporta essa tecnologia de acesso a dado, por causa da compatibilidade com as versões anteriores. Você pode estar migrando um sistema desenvolvido em Delphi 4, ou D5, isso é um situação cada vez mais comum. Por conta disso, certamente será obrigado a trabalhar e conhecer a BDE. Portanto, no DBE administrator, ou no SQLexplorer, crie dois alias: um para o banco de dados fonte e o outro para o banco de dados de destino. Para isto vamos na barra de menu do Delphi e click em : Datadase ► Explore



O BDE Administrator fica em Painel de controle. Como o nome já diz, ele é um programa aonde vc configura conexões a bancos de dados a través da BDE. Semelhante ao Fonte de Dados ODBC.

Em nosso exemplo de migração utilizaremos como banco de dados, de onde importaremos, o DbDemos(exemplo do Delphi), já deverá existir um alias para ele pré-configurado. Logo, será necessário configurar apenas um alias para um banco SGDB (Dbmigrante.gdb) que criamos, no interbase, especialmente para este exemplo.


Para criar o alias:

No SQLExplore click com o botão direito do mouse sobre database, no frame esquerdo da tela, como no exemplo abaixo.



No menu poupup click em new, surgirá um janela para escolhermos o dirver do banco de daddos. Defina o driver para o banco de dados ao qual você deseja se conectar, em nosso caso “INTERBASE”.



No frame a esquerda nomeie esse alias como MigranteSGDB. Veja na figura abaixo.


Ainda precisamos definir o usuário para o login no interbase, o SYSDBA é o login de administrador default. No frame da direita, em USER NAME, digite como na figura abaixo.




Em seguida na propriedade SERVER NAME o path do banco de dados DbMigrante.gdb. click no botão com três pontinhos e mapeie o seu arquivo de banco de dados criado anteriormente no Interbase. Em seguida, salve as configurações feitas. No menu Object Apply, ou “Ctrl+A”.




No meni Iniciar do Windows, programas, Borland Delphi x.., DataPump, selecione o alias do banco de dados fonte, ou seja aquele do qual você deseja migrar. Pode se optar pelo alias ou pelo endereço(diretório) do banco. Atente para fato de que um sevidor SQL de bancos de dados sempre requerem um alias e podem requerer um login.



Escolha o alias DBDEMOS e click em NEXT.




Escolha o alias que criamos para o arquivo SGDB, MIgranteGDB. Será pedido o login. SYSDBA e a senha masterkey são o login do administrador default do Interbase.



selecione as Tabelas que você quer mover do banco de dados de fonte. Ou seja, selecione as tabelas que deseja migrar do banco Paradox(DBDEMOS) para o Interbase(DbMigrante.gdb)...



...clickando no primeiro botão (>) entre as listBox. Se deseja mover todas as tabelas click no segundo botão (>>).




Na próxima tela você tem a visão de um relatório preliminar para determinar como os dados serão definidos quando você mover para o banco de dados designado. Nesta tela você pode fazer algumas alterações a respeito de cada tabela como: nome da tabela tipo de dado a coluna e etc.



é possível modificar qualquer tipo de dados, índices, ou integridade referente antes de migrar para no banco de dados destino.

Click em Upsize, as tabelas e os dados serão transportados.



OK a migração foi feita com sucesso.

Artigo completo (View Full Post)

segunda-feira, 28 de maio de 2007

O irmão de Darth Vader

Olá a todos.

Vocês sabiam que o Lord Vader tinha um irmão? Pois é... ele é o Chad Vader. Só que ele não teve tanto sucesso quanto o irmão e acabou trabalhando num supermercado.

Hilário, não perca esse xD.

Abraços a todos.

Artigo completo (View Full Post)

Não seja presunçoso - Não escreva código presunçoso

Um olá especial a todos.

Se o título pareceu arrogante, peço desculpas. Como será mostrado ao longo do post a idéia é exatamente o contrário.

Vamos começar com uma frase forte: não escreva código presunçoso.

O que é um código presunçoso? Quando o código presume alguma coisa ele é presunçoso xD.

Vamos mostrar na prática:


class Exemplo {

public double divisao(int numerador, int denominador) {
return (numerador / denominador);
}

}


Uma classe normal, com um método normal. Agora vamos responder ao evento click de um botão:


private void btnDividir_Click(object sender, EventArgs e) {
Exemplo exemplo = new Exemplo();
int numerador = (int) txtNumerador.Text;
int denominador = (int) txtDenominador.Text;
double resultado = exemplo.divisao(numerador, denominador);
}



Se fizermos alguns testes eles vão funcionar com certeza. É só não ...
- Preenchermos o denominador como zero
- Preenchermos qualquer campo com valor não numérico

Ah Felipe, aí é só fazer uma lo-gi-ca-zi-nha de validação. Exatamente! Nem é tão difícil assim. É só uma questão de condicionamento.

Às vezes dá muito trabalho fazer aquela validação aqui, aquele teste ali, e o que a gente tem no final é divisão por zero, acesso a registros quando o recordset está vazio, access violation, etc, etc, etc...

Quem trabalha com linguagens de script na web então... que trabalho... Imagina fazer validações no cliente (javascript) e no servidor (PHP, ASP.NET, Delphi, etc)...

Dá trabalho mas tem que ser feito. E, se não for feito antes vai ter que ser feito depois (de um banco cheio de inconsistências hehe).

Novamente digo que a minha idéia não é nem ser arrogante nem dar uma de 'perfeito'. Eu também escrevo esta recomendação para mim mesmo e acho que, exatamente por isso, é legal ter este lembrete para todos nós. Boa semana a todos e até a próxima!

Artigo completo (View Full Post)

Carvão: Composição: Ana Carolina

Minha tia fez um pedido ... Aqui está, prontamente atendido, com todo carinho.

a hamonia da música inteira se rezume a repetição dos 12 compassos da introdução. Uma fraze executada pelo violão, na metade do 5º compasso, que é um arpejo de mi diminuto, partindo do mi solto 6º corda (Veja na partitura ....)


Carvão


Intro: | Eadd9| F#m7(b5)9| D6/F#| F#m6(11)| | Bm7| Bm7/A| Gadd9|
Gadd9 D/F#
| Emadd9 F#7(b13)| Bm9 Bm9(11)| Bm9 Bm9(11)|




Eadd9
Surgiu como um clarão
F#m7(b5)9

Um raio me cortando a escuridão
D6/F#
E veio me puxando pela mão
F#m6(11)
Por onde não imaginei seguir

Me fez sentir tão bem, como ninguém
Bm7 Bm7/A
E eu fui me enganando sem sentir
Gadd9
E fui abrindo portas sem sair
D/F# Emadd9 F#7(b13)
Sonhando às cegas, sem dormir
Bm9
Não sei quem é você

Eadd9
O amor em seu carvão
F#m7(b5)9
Foi me queimando em brasa num colchão
D6/F#
E me partiu em tantas pelo chão
F#m6(11)
Me colocou diante de um leão

O amor me consumiu, depois sumiu
Bm7 Bm7/A
E eu até perguntei, mas ninguém viu
Gadd9
E fui fechando o rosto sem sentir
D/F# Emadd9
E mesmo atenta, sem me distrair
F#7(b13) Bm9 Bm911
Não sei quem é você

Eadd9
No espelho da ilusão
F#m7(b5)9
Se retocou pra outra traição
D6/F#
Tentou abrir as flores do perdão
F#m6(11)
Mas bati minha raiva no portão

E não mais me procure sem razão
Bm7 Bm7/A
Me deixa aqui e solta a minha mão
Gadd9
Eu fui fechando o tempo, sem chover
D/F# Emadd9 F#7(b13)
Fui fechando os meus olhos, pra esquecer
Bm9
Quem é você?
Bm9(11)
Quem é você?
Bm9
Quem é você?

Você...

Harmonia bem legal da Ana Carolina. Uma excelente composição, sem dúvida. O arranjo de cordas está mto bonito.
Uhm!!! faltou o último acorde ... as vezes eu fico sem saco ... depois eu coloco ..

Artigo completo (View Full Post)

terça-feira, 22 de maio de 2007

Erwin: Modelagem de Dados - Complete Compare


Os sistemas de informação são as principais engrenagens que propulsionam o mundo de forma generalizada. Seja na área dos negócios, entidades governamentais, órgãos militares, ou na vida privada de cada um, progressivamente, mais e mais, eles são presentes e influentes. Ao ponto das relações humanas, sofrem transformações significativas. Eles são um meio, uma ferramenta e não um fim. A informação é o principal protagonista neste cenário. O que estou querendo dizer é que um sistema pode funcionar perfeitamente sem bug nenhum, entretanto, não produzir informações pertinentes para as pessoas que o utilizam. A informação é o recurso mais importante na vida de qualquer pessoa, na vida de uma corporação. Pense o seguinte, com a informação certa eu posso salvar a vida de uma pessoa, eu posso ficar milionário de uma hora pra outra. Eu posso conseguir o que eu quiser. Mas findando a viagem, voltemos ao ponto. Somos profissionais da Tecnologia da Informação, é ponto pacifico, todo mundo sabe que com dados construímos uma informação. Mas o que é a informação? A informação é um conjunto de fatos, organizados de tal forma que adquirem valor adicional além do valor do fato em si. Concluindo, é totalmente em vão o investimento num sistema que não é capaz de gerar informações relevantes, valiosas.
Como posso me certificar que o sistema que desenvolvo gera informações de qualidade?
Uma informação para alcançar o status de VALIOSA deve atender aos seguintes requisitos:

  • Ser precisa – Não possuir erros.
  • Ser Completa – Conter todos os fatos importantes.
  • Ser Econômica – O custo da geração dessa informação deve ser compatível com a relação posse/demanda do interessado nela.
  • Ser Flexível – Poder ser usada para várias finalidades.
  • Ser Confiável – Se a fonte não for idônea, você vai utilizar a informação? A confiabilidade da informação pode depender da confiabilidade do método de colheita de dados.
  • Ser Relevante – Alto grau de importância para o interessado.
  • Ser Simples – Fácil entendimento.
  • Em Tempo – Qual a importância de eu saber os números ganhadores da megasena após eles serem sorteados? Considerando que eu não tenha apostado. Entretanto, tudo muda de figura se eu souber disso pelo menos algumas horas ates de serem encerradas as apostas.
  • Ser Verificável – Essa característica aumenta consideravelmente a confiabilidade. Se não for possível checar, verificar a informação você já estará entrando no mundo da análise mística de sistemas.

Para a informação alcançar todas essas características vai depender, fundamentalmente, de como eu organizo e relaciono os fatos. Ou seja, os dados.
Neste artigo vamos apresentar alguns exemplos, onde usaremos uma ferramenta apropriada no desenvolvimento de sistemas para relacionarmos, organizarmos os dados. Veremos um pouco sobre modelagem de dados sob um enfoque prático.
Para começar um novo modelo no Erwin basta em menu “File”, clickar sobre “New”.





Selecione uma das opções “Logical”, “Physical”, “Logical/Physical”. Estas opções são correspondentes as duas últimas derivações do Modelo Relacional de Dados de Dados (Edgard codd) que define três níveis de modelos derivação dos modelos:

  1. Modelo Conceitual
  2. Modelo Lógico
  3. Modelo Físico

Neste caso devemos considerar que o modelo conceitual deverá ser feito fora da ferramenta, nela partimos direto para o modelo lógico. Pelo menos o habito me fez proceder desta forma, eu prefiro assim. A prática permite que vc imagine o modelo conceitual, mas ao passar para o papel, já o faça no modelo lógico. Não [e atoa eu as ferramenas case suprimam esta etapa. Portanto, assim faremos no decorrer deste artigo.
Vamos, inicialmente a partir do modelo conceitual, trabalhar com três entidades: Cliente, Pedido e Produto. A entidade Item surge na derivação para o modelo lógico, nosso ponto de partida no software Erwin, do relacionamento “N” para “M” entre as entidades Pedido e Produto. Portanto, no modelo que vamos desenvolver no Erwin contaremos com quatro entidades: Cliente, Pedido, Item e Produto.



O depois de definirmos os atributos e o relacionamento com a seta correspondente a cardinalidade, o próximo passo é partirmos para a derivação física do modelo. Só que o Erwin só habilitará essa opção no menu assim que você salvar seu modelo. O meu eu vou salvar com o nome ZnModeloBase.



Agora, na opção de menu “Tools”, click em “Derive New Model”.



Novamente, a mesma tela onde você escolheu o nível de derivação desejado. Nela você já vai definir que tecnologia de banco de dados vai usar. Visto que, é chegado o momento das definições físicas do seu modelo de dado. Agora você vai ter que definir os domínios, o tipo de dado, as validações (checkes e contrains) e etc..



Vou escolher Oracle, supondo que estarei criando um banco de dados que usará esta tecnologia. 9x é a versão do Oracle que eu tenho na máquina. Defina a derivação que você deseja (Física ou Logoca/Física) e a tecnologia de banco de dados, em seguida click em “Avançar”.
Na tela seguinte você pode definir ainda se aplica derivação dos relacionamentos muitos para muitos e generalização especialização. Bem como, na treeview a esquerda vc pode definir que objetos do seu modelo lógico será portado para o novo modelo físico derivado dele. Veja minhas escolhas na imagem abaixo:



Em seguida click em avançar novamente.



Agora vamos definir alguns domínios que serão usados para os campos da nossa tabela.



Para configurar a propriedades do domínio “IdentificadorZn”, click com o botão direito do mouse sobre ele e selecione “Properties”.



Vou escolher para esse domínio que seja do tipo Integer e Not Nul. Você pode alem disso definir volres default e constrains para o domínio nesta tela.
Além desse vamos definir um para tipos strings, também not null, cujo o tamanho máximo é 20 caracteres. O nome do domínio será “Texto20Zn”



Agora vamos definir os domínios de cada campo de cada tabela do nosso modelo físico. Click sobre a tabela Clientes.




Dê um duplo click sobre cada campo para configura-los. Primeiro vamos no “ID_CLIENTE”.



Click “Ok”, repita esse passo para cada campo, sendo que o campo Nome será do domínio “Texto20Zn”. Seria interessante criar um domínio para o CPF (Char de 11 not null), o qual, logicamente, seria relacionado ao campo CPF. Faça o mesmo para cada Tabela.
Para simularmos um erro, o qual será motivo para provocarmos uma alteração na base, deixe os campos da tabela Item, QTDE e VALOR_UNIT, configurados como “DATE”. No mesmo propósito o campo Dado1 de Clientes fica como “Blob”. Repito, isso é uma erro que estamos forçando para mais tarde alterarmos a base, a fim de corrigi-la, a través do complete compare do Erwin. Portanto seu modelo deverá estar agora igual a figura abaixo:



Para criar as tabelas no banco de dados através do Erwin, no menu “Tools”, click em “Forward Engineer/Schema Generation ...”



Neste diálogo, você escolhe o que vai ser criado e como vai ser criado. A princípio você deve selecionar somente o que é estritamente especifico ao que você pretende gerar. Exemplo, não pretendo criar nenhuma view, portanto, vou desmarcar todas as opções referentes a views. O mesmo para triggers.




Após selecionar as opções desejadas click em “Preview” ...






O Erwin vai gerar automaticamente um script SQL para criar as tabelas de acordo com o seu modelo. Veja o script gerado abaixo:


CREATE TABLE Clientes (
ID_CLIENTE INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
CPF CHAR(11) NULL,
DADO1 BLOB NULL
);


ALTER TABLE Clientes
ADD PRIMARY KEY (ID_CLIENTE);


CREATE TABLE Itens (
ID_PEDIDO INTEGER NOT NULL,
ID_PRODUTO INTEGER NOT NULL,
QTDE DATE NULL,
VALOR_UNIT DATE NULL
);


ALTER TABLE Itens
ADD PRIMARY KEY (ID_PEDIDO, ID_PRODUTO);


CREATE TABLE Pedidos (
ID_PEDIDO INTEGER NOT NULL,
DT_PEDIDO DATE NULL,
ID_CLIENTE INTEGER NULL
);


ALTER TABLE Pedidos
ADD PRIMARY KEY (ID_PEDIDO);


CREATE TABLE Produtos (
ID_PRODUTO INTEGER NOT NULL,
DESCRICAO VARCHAR2(20) NULL
);


ALTER TABLE Produtos
ADD PRIMARY KEY (ID_PRODUTO);


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PEDIDO)
REFERENCES Pedidos (ID_PEDIDO);


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PRODUTO)
REFERENCES Produtos (ID_PRODUTO);


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_CLIENTE)
REFERENCES Clientes (ID_CLIENTE);





Para efetuar a execução e, conseqüentemente, a criação das tabelas click em “Generate...”



No prompt de login digite usuário e senha do Owner no banco de dados e o servidor do banco de dados.



Veja o relatório abaixo ...


CREATE TABLE Clientes (
ID_CLIENTE INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
CPF CHAR(11) NULL,
DADO1 BLOB NULL
)

Execution Successful


ALTER TABLE Clientes
ADD PRIMARY KEY (ID_CLIENTE)

Execution Successful


CREATE TABLE Itens (
ID_PEDIDO INTEGER NOT NULL,
ID_PRODUTO INTEGER NOT NULL,
QTDE DATE NULL,
VALOR_UNIT DATE NULL
)

Execution Successful


ALTER TABLE Itens
ADD PRIMARY KEY (ID_PEDIDO, ID_PRODUTO)

Execution Successful


CREATE TABLE Pedidos (
ID_PEDIDO INTEGER NOT NULL,
DT_PEDIDO DATE NULL,
ID_CLIENTE INTEGER NULL
)

Execution Successful


ALTER TABLE Pedidos
ADD PRIMARY KEY (ID_PEDIDO)

Execution Successful


CREATE TABLE Produtos (
ID_PRODUTO INTEGER NOT NULL,
DESCRICAO VARCHAR2(20) NULL
)

Execution Successful


ALTER TABLE Produtos
ADD PRIMARY KEY (ID_PRODUTO)

Execution Successful


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PEDIDO)
REFERENCES Pedidos (ID_PEDIDO)

Execution Successful


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PRODUTO)
REFERENCES Produtos (ID_PRODUTO)

Execution Successful


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_CLIENTE)
REFERENCES Clientes (ID_CLIENTE)

Execution Successful

Schema Generation Complete
11 query succeeded.


Pronto!!!! Suas tabelas foram criadas com sucesso!!!!

Complete Compare

Essa funcionalidade permite você compara bases com modelos, modelos com modelos ou bases com bases. Alem disso provê um gerenciados para sincronização dos elementos comparados. Na opção de menu, “Tools”, subitem, “Complete Compare ...”, você poderá fazer isso.
Essa funcionalidade é mto útil para quem trabalha com modelagem de desenvolvimento de banco de dados. Normalmente durante a fase de análise o banco de dados sofre muitas alterações o Erwin facilita muito o trabalho de manutenção e atualização num projeto.
Logo, seguindo nessa idéia, simulando uma situação real, vamos fazer algumas alterações no nosso modelo e executar a sincronização com as tabelas geradas através do “complete Compare”.
Na tabela Clientes o campo “Dado1” será alterado para Varchar2(200). Para fazer isso, duplo click na tabela Clientes que eseta no seu modelo. Vai aparecer a janela de diálogo para edição da Tabela, selecione o campo Dado1 e no lado direito, na aba Oracle, em "Oracle datatype" altere o data type para Varchar2(200).



Adicione um campo “Dado2”, cujo datatype será: Date, Not Null.



Crie a tabela Vendedores, com os seguintes canpos: ID_VENDEDOR, NOME E COD. Em seguida altere os campos da tabela Itens, QTDE, para Integer e Valor_unit para Number(10,2), ambos “Not Null”. Relacione Vendedores com Pedidos, de acordo com o modelo abaixo.



Agora podemos sincronizar a base com o modelo. Click em “complete compare” e a seguir aparecerão os diálogos onde você determinará que tipo de comparação será feita e que tipo de sincronização. Bem como quais objetos do banco serão sincronizados.



Click em next ....



Dependendo da situação, pode ser interessante desmarcar o Prefix Owner. Ou seja ele vai desconsiderar o prefixo do Owner. Considerando que qause nenhum modelo se preocupa com quem é o Owner do objeto.
De acordo com o que você selecionou na treeview a esquerda o próximo diálogo listará todos os objetos por você selecionados. O mesmo para Tables/Views Ownered By, visto que no nosso modelo não definimos Owner para nossas tabelas, portanto ....



Aqui é apresentado uma listagem (treeview) com as opções por você seleciandas no diálogo anterior. Click next para a o dialogo referente as opção do próximo modelo, ou seja, no nosso caso a base de dados Oracle.



Neste diálogo, quase sempre é conveniente definir o Owner, primeiro pq isso restringe o número de objetos que serão comparados. Segundo, pq pode haver tabelas sinônimas para Owners diferentes. Marque “current Model Objects Only”, e na opção Match, desmarque “Using Owner”, visto que no modelo não existe tal referência.



Click Sim. Em seguida Ele apresenta a litagem das diferenças.



Ele compara de forma esperada as tabelas, desconsiderando o Owner, e lista as diferenças entre elas. Note que algumas diferenças não precisam ser consideradas, pois são restritas a particularidades do banco, tais quais: “PCTFREE10”. Portanto, essas deverão ser desconsideradas.
Na tabela de Clientes a alteração pertinente que precisamos fazer, por exemplo, é concernente ao campo Dado1, que será alterado de Blob para Varchar(200). Click sobre a linha que lista essa diferença, veja que em reflexo a essa operação os botões de importação e exportação serão habilitados. Em seguida click sobre “Import”. Repita a mesma operação para o campo Dado2.
Na tabela Itens, os campos QTDE e Valor_Unit, selecione os dois e click em “Import”.
Em Pedidos somente o Campo ID_VENDEDOR. Na tabela Produtos nenhuma alteração. Não se esqueça de selecionar a tabela Vendedores.
Ele gera um script das alterações que ele pretende fazer. Se “Generate ALTER statements for all new table columns” estiver marcado, click sobre “Preview”.



Segue o código ....



/*
CHANGE REPORT for Table CLIENTES
- change datatype from BLOB to VARCHAR2(200) of column DADO1
WARNING : Load data statement for table CLIENTES may fail or data in column DADO1 may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype).
- Adding column Dado2
WARNING : Recreating Table CLIENTES based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table CLIENTES
- Data will be copied to table CLIENTESR5MG3815000 ,or table will be renamed CLIENTESR5MG3815000..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table CLIENTES
- referencing foreign key SYS_C009967 of table PEDIDOS will be dropped as a side effect.
*/

ALTER TABLE PEDIDOS DROP CONSTRAINT SYS_C009967;


ALTER TABLE CLIENTES RENAME TO CLIENTESR5MG3815000;


/*
CHANGE REPORT for Table ITENS
- change datatype from DATE to INTEGER, change null constraint from NULL to NOT NULL of column QTDE
WARNING : Load data statement for table ITENS may fail or data in column QTDE may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype). and Load data or ALTER statement for table ITENS may fail (existing data may violate the new column rules: changing column QTDE to NOT NULL without DEFAULT).
- change datatype from DATE to NUMBER(10,2), change null constraint from NULL to NOT NULL of column VALOR_UNIT
WARNING : Load data statement for table ITENS may fail or data in column VALOR_UNIT may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype). and Load data or ALTER statement for table ITENS may fail (existing data may violate the new column rules: changing column VALOR_UNIT to NOT NULL without DEFAULT).
WARNING : Recreating Table ITENS based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table ITENS
- Data will be copied to table ITENSR5MG3815001 ,or table will be renamed ITENSR5MG3815001..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table ITENS
- foreign key SYS_C009965 of table ITENS will be dropped as a side effect.
- foreign key SYS_C009966 of table ITENS will be dropped as a side effect.
*/

ALTER TABLE ITENS DROP CONSTRAINT SYS_C009965;


ALTER TABLE ITENS DROP CONSTRAINT SYS_C009966;


ALTER TABLE ITENS RENAME TO ITENSR5MG3815001;


/*
CHANGE REPORT for Table PEDIDOS
- Adding column ID_VENDEDOR
WARNING : Modify or load data statement for table PEDIDOS may fail (existing data may violate the new column rules: adding a NOT NULL without DEFAULT to column ID_VENDEDOR).
WARNING : Recreating Table PEDIDOS based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table PEDIDOS
- Data will be copied to table PEDIDOSR5MG3815002 ,or table will be renamed PEDIDOSR5MG3815002..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table PEDIDOS
- foreign key SYS_C009967 of table PEDIDOS will be dropped as a side effect.
- referencing foreign key SYS_C009965 of table ITENS will be dropped as a side effect.
*/

ALTER TABLE PEDIDOS RENAME TO PEDIDOSR5MG3815002;


/*
ACTION is CREATE Table Vendores
*/

CREATE TABLE Vendores (
ID_VENDEDOR INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
COD CHAR(2) NULL
);


ALTER TABLE Vendores
ADD PRIMARY KEY (ID_VENDEDOR);


CREATE TABLE Clientes (
ID_CLIENTE INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
CPF CHAR(11) NULL,
DADO1 VARCHAR2(200) NULL,
Dado2 CHAR(2) NULL
);


ALTER TABLE Clientes
ADD PRIMARY KEY (ID_CLIENTE);


CREATE TABLE Itens (
ID_PEDIDO INTEGER NOT NULL,
ID_PRODUTO INTEGER NOT NULL,
QTDE INTEGER NOT NULL,
VALOR_UNIT NUMBER(10,2) NOT NULL
);


ALTER TABLE Itens
ADD PRIMARY KEY (ID_PEDIDO, ID_PRODUTO);


CREATE TABLE Pedidos (
ID_PEDIDO INTEGER NOT NULL,
DT_PEDIDO CHAR(2) NULL,
ID_CLIENTE INTEGER NULL,
ID_VENDEDOR INTEGER NOT NULL
);


ALTER TABLE Pedidos
ADD PRIMARY KEY (ID_PEDIDO);


INSERT INTO Clientes (ID_CLIENTE, NOME, CPF) SELECT ID_CLIENTE, NOME, CPF FROM
CLIENTESR5MG3815000;


DROP TABLE CLIENTESR5MG3815000 CASCADE CONSTRAINTS;


INSERT INTO Itens (ID_PEDIDO, ID_PRODUTO, QTDE, VALOR_UNIT) SELECT ID_PEDIDO,
ID_PRODUTO, TO_CHAR(QTDE,'J'), TO_CHAR(VALOR_UNIT,'J') FROM
ITENSR5MG3815001;


DROP TABLE ITENSR5MG3815001 CASCADE CONSTRAINTS;


INSERT INTO Pedidos (ID_PEDIDO, DT_PEDIDO, ID_CLIENTE) SELECT ID_PEDIDO,
TO_CHAR(DT_PEDIDO), ID_CLIENTE FROM PEDIDOSR5MG3815002;


DROP TABLE PEDIDOSR5MG3815002 CASCADE CONSTRAINTS;


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PEDIDO)
REFERENCES Pedidos (ID_PEDIDO);


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PRODUTO)
REFERENCES Produtos (ID_PRODUTO);


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_VENDEDOR)
REFERENCES Vendores (ID_VENDEDOR)
ON DELETE SET NULL;


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_CLIENTE)
REFERENCES Clientes (ID_CLIENTE);




Um relatório sobre a comparação também pode ser visualizado, click em “Report ...”.



Para prossegui na intenção de efetuar as alterações click em “Next”. Mais um diálogo lista os possíveis problemas que ele vai encontrar ao processar as alterações.



Click em close para o próximo passo. No diálogo seguinte, no botão acima, click em “Start Export”.




Será apresentado mais um relatório durante a operação, também em forma de caixa de diálogo semelhante as anteriores. Onde haverá botões para impressão, salvar e etc...
Segue o relatório gerado pela exportação que acabamos de processar.



/*
CHANGE REPORT for Table CLIENTES
- change datatype from BLOB to VARCHAR2(200) of column DADO1
WARNING : Load data statement for table CLIENTES may fail or data in column DADO1 may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype).
- Adding column Dado2
WARNING : Recreating Table CLIENTES based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table CLIENTES
- Data will be copied to table CLIENTESR5MG4020000 ,or table will be renamed CLIENTESR5MG4020000..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table CLIENTES
- referencing foreign key SYS_C009967 of table PEDIDOS will be dropped as a side effect.
*/

ALTER TABLE PEDIDOS DROP CONSTRAINT SYS_C009967

Execution Successful


ALTER TABLE CLIENTES RENAME TO CLIENTESR5MG4020000

Execution Successful


/*
CHANGE REPORT for Table ITENS
- change datatype from DATE to INTEGER, change null constraint from NULL to NOT NULL of column QTDE
WARNING : Load data statement for table ITENS may fail or data in column QTDE may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype). and Load data or ALTER statement for table ITENS may fail (existing data may violate the new column rules: changing column QTDE to NOT NULL without DEFAULT).
- change datatype from DATE to NUMBER(10,2), change null constraint from NULL to NOT NULL of column VALOR_UNIT
WARNING : Load data statement for table ITENS may fail or data in column VALOR_UNIT may be lost (existing data may violate the new datatype rules: converting to a shorter or incompatible datatype). and Load data or ALTER statement for table ITENS may fail (existing data may violate the new column rules: changing column VALOR_UNIT to NOT NULL without DEFAULT).
WARNING : Recreating Table ITENS based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table ITENS
- Data will be copied to table ITENSR5MG4020001 ,or table will be renamed ITENSR5MG4020001..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table ITENS
- foreign key SYS_C009965 of table ITENS will be dropped as a side effect.
- foreign key SYS_C009966 of table ITENS will be dropped as a side effect.
*/

ALTER TABLE ITENS DROP CONSTRAINT SYS_C009965

Execution Successful


ALTER TABLE ITENS DROP CONSTRAINT SYS_C009966

Execution Successful


ALTER TABLE ITENS RENAME TO ITENSR5MG4020001

Execution Successful


/*
CHANGE REPORT for Table PEDIDOS
- Adding column ID_VENDEDOR
WARNING : Modify or load data statement for table PEDIDOS may fail (existing data may violate the new column rules: adding a NOT NULL without DEFAULT to column ID_VENDEDOR).
WARNING : Recreating Table PEDIDOS based on the ERwin source model. Any differences marked 'Ignore' in the compare list will be recreated based on the ERwin source model.
ACTION is DROP and CREATE Table PEDIDOS
- Data will be copied to table PEDIDOSR5MG4020002 ,or table will be renamed PEDIDOSR5MG4020002..
- Temp table will be dropped if load data statement is successful.
IMPACT ANALYSIS REPORT for DROP and CREATE Table PEDIDOS
- foreign key SYS_C009967 of table PEDIDOS will be dropped as a side effect.
- referencing foreign key SYS_C009965 of table ITENS will be dropped as a side effect.
*/

ALTER TABLE PEDIDOS RENAME TO PEDIDOSR5MG4020002

Execution Successful


/*
ACTION is CREATE Table Vendores
*/

CREATE TABLE Vendores (
ID_VENDEDOR INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
COD CHAR(2) NULL
)

Execution Successful


ALTER TABLE Vendores
ADD PRIMARY KEY (ID_VENDEDOR)

Execution Successful


CREATE TABLE Clientes (
ID_CLIENTE INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
CPF CHAR(11) NULL,
DADO1 VARCHAR2(200) NULL,
Dado2 CHAR(2) NULL
)

Execution Successful


ALTER TABLE Clientes
ADD PRIMARY KEY (ID_CLIENTE)

Execution Successful


CREATE TABLE Itens (
ID_PEDIDO INTEGER NOT NULL,
ID_PRODUTO INTEGER NOT NULL,
QTDE INTEGER NOT NULL,
VALOR_UNIT NUMBER(10,2) NOT NULL
)

Execution Successful


ALTER TABLE Itens
ADD PRIMARY KEY (ID_PEDIDO, ID_PRODUTO)

Execution Successful


CREATE TABLE Pedidos (
ID_PEDIDO INTEGER NOT NULL,
DT_PEDIDO CHAR(2) NULL,
ID_CLIENTE INTEGER NULL,
ID_VENDEDOR INTEGER NOT NULL
)

Execution Successful


ALTER TABLE Pedidos
ADD PRIMARY KEY (ID_PEDIDO)

Execution Successful


INSERT INTO Clientes (ID_CLIENTE, NOME, CPF) SELECT ID_CLIENTE, NOME, CPF FROM
CLIENTESR5MG4020000

Execution Successful


DROP TABLE CLIENTESR5MG4020000 CASCADE CONSTRAINTS

Execution Successful


INSERT INTO Itens (ID_PEDIDO, ID_PRODUTO, QTDE, VALOR_UNIT) SELECT ID_PEDIDO,
ID_PRODUTO, TO_CHAR(QTDE,'J'), TO_CHAR(VALOR_UNIT,'J') FROM
ITENSR5MG4020001

Execution Successful


DROP TABLE ITENSR5MG4020001 CASCADE CONSTRAINTS

Execution Successful


INSERT INTO Pedidos (ID_PEDIDO, DT_PEDIDO, ID_CLIENTE) SELECT ID_PEDIDO,
TO_CHAR(DT_PEDIDO), ID_CLIENTE FROM PEDIDOSR5MG4020002

Execution Successful


DROP TABLE PEDIDOSR5MG4020002 CASCADE CONSTRAINTS

Execution Successful


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PEDIDO)
REFERENCES Pedidos (ID_PEDIDO)

Execution Successful


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PRODUTO)
REFERENCES Produtos (ID_PRODUTO)

Execution Successful


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_VENDEDOR)
REFERENCES Vendores (ID_VENDEDOR)
ON DELETE SET NULL

Execution Successful


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_CLIENTE)
REFERENCES Clientes (ID_CLIENTE)

Execution Successful

Schema Generation Complete
24 query succeeded.


OBS: O Banco usado nesse exemplo possui a única finalidade de recurso didático, não possuído nenhuma pretensão se ser compatível com qualquer lógica de negócio que possa ser usada para um sistema profissional. Segue o Script final do banco ....


CREATE TABLE Clientes (
ID_CLIENTE INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
CPF CHAR(11) NULL,
DADO1 VARCHAR2(200) NULL,
Dado2 CHAR(2) NULL
);


ALTER TABLE Clientes
ADD PRIMARY KEY (ID_CLIENTE);


CREATE TABLE Itens (
ID_PEDIDO INTEGER NOT NULL,
ID_PRODUTO INTEGER NOT NULL,
QTDE INTEGER NULL,
VALOR_UNIT NUMBER(8,2) NOT NULL,
Promocao CHAR(1) NOT NULL
);


ALTER TABLE Itens
ADD PRIMARY KEY (ID_PEDIDO, ID_PRODUTO);


CREATE TABLE Pedidos (
ID_PEDIDO INTEGER NOT NULL,
DT_PEDIDO CHAR(2) NULL,
ID_CLIENTE INTEGER NULL,
ID_VENDEDOR INTEGER NOT NULL
);


ALTER TABLE Pedidos
ADD PRIMARY KEY (ID_PEDIDO);


CREATE TABLE Produtos (
ID_PRODUTO INTEGER NOT NULL,
DESCRICAO VARCHAR2(20) NULL,
CODprod VARCHAR2(20) NULL
);


ALTER TABLE Produtos
ADD PRIMARY KEY (ID_PRODUTO);


CREATE TABLE Vendores (
ID_VENDEDOR INTEGER NOT NULL,
NOME VARCHAR2(20) NULL,
COD VARCHAR2(2) NOT NULL
);


ALTER TABLE Vendores
ADD PRIMARY KEY (ID_VENDEDOR);


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PEDIDO)
REFERENCES Pedidos (ID_PEDIDO);


ALTER TABLE Itens
ADD FOREIGN KEY (ID_PRODUTO)
REFERENCES Produtos (ID_PRODUTO);


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_VENDEDOR)
REFERENCES Vendores (ID_VENDEDOR)
ON DELETE SET NULL;


ALTER TABLE Pedidos
ADD FOREIGN KEY (ID_CLIENTE)
REFERENCES Clientes (ID_CLIENTE);





Pronto!!!! Aeeee...oi!!! A base está sincronizada com o modelo.
A vida é boa!!! É fácil trabalhar assim!!!
Então, foi bom pra você?
Qualquer ponto que não tenha ficado claro, por favor registre como comentário que responderemos prontamente.


Artigo completo (View Full Post)

segunda-feira, 21 de maio de 2007

Apresentando dados tabulares com estilo

Olá a todos mais uma vez.

Você costuma usar tabelas HTML? Você já precisou usar uma tabela HTML para mostrar dados de um banco de dados? Você (ou seu usuário) alguma vez já se confundiu com as linhas nos dados tabulares?

Bem, acho que a resposta da maioria a todas as perguntas é sim. Vamos abordar a última pergunta.

Para não haver confusões entre as linhas nós temos diversas soluções:

- Bordas na tabela: Esta é a mais fácil de se implementar e o mais básico: É só colocar o atributo border="1" na tag <Table>. Com os estilos CSS podemos colocar até bordas mais bonitas. É legal, é fácil, mas não é muito sofisticado - porém não subestime - às vezes menos é mais.


- Estilo "zebra": Cada linha de uma cor diferente, alternando entre duas cores. Uma solução bem bacana. Quando a tabela é dinâmica é bem fácil de fazer:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
$cor = ($cor == "#ffffff" ? "#eaeaea" : "#ffffff");
echo "<tr style='background: $cor'>";
..
..
echo "</tr>";
}
?>
</table>



- DHTML: Todas as linhas têm o mesmo fundo, mas a linha atual muda de cor quando o usuário passa o mouse sobre ela. Exemplo:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
?>
<tr onmouseover="this.style.background = '#eaeaea'"
onmouseout="this.style.background = 'none'">
...
...
...
</tr>
<?
}
?>
</table>


Assim também fica muito legal.

Este assunto pode parecer bobo, mas às vezes são coisas pequenas assim que definem a identidade de um site ou de uma aplicação web, levando ao seu sucesso.

Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

terça-feira, 15 de maio de 2007

Windows - Chick Corea

Vou tocar com amigos!!!! O Outro Windows na minha vida .... hehhehh





Windows, com certeza não é o tema dos mais freqüentes nas raras e remanescentes Jam Sessions que nos dias de hoje poucos privilegiados têm acesso. Também não é uma obra nova, nem desconhecida dos jazzistas. Muito pelo contrário, tenho observado que é uma composição que agrada a maioria dos músicos.
Não é um exagero de complexidade, mas também não é um blues em 12. É uma música que lava o instrumentista para além da fronteira do trivial oferecendo uma gama soluções não convencionais. Seu aspecto rítmico contribui nesse sentido, visto que a sub-divisão em três favorece e fortalece a predominância de uma riqueza de detalhes analogicamente variantes. Bem, pra mim esta entre os top 20 melhores temas de todos os tempos (hehehehe ...).

Artigo completo (View Full Post)

segunda-feira, 14 de maio de 2007

Tela Azul - STOP:C0000218{Falha no arquivo do Registro}

Tive uma surpresinha quando fui ligar o micro hoje, ao iniciar o windows entrava numa tela azul com a singela mensagem:

STOP:C0000218{Falha no arquivo do Registro}
O registro não pode carregar a ramificação (arquivo):
\systemroot\system32\config\software
Ele está corrompido, ausente ou não pode ser gravado.

O HD onde está instalado esse SO está barulhento demais, é muito provável que o arquivo tenha corrompido. A tradicional e rápida busca na Web ... de cara encontrei uma dica para usar um verificador de disco, tipo DiskDoctor, ou o do próprio Windows. Como eu tenho mais de um SO nesta máq, assim o fiz. Inicializei pelo pelo SO bom, em ferramentas administrativas ▶ Gerenciamento do Computador ▶ Gerenciamento de Disco:



Botão direito sobre o HD com problemas (em caso de duvidada repita em todos), selecione propriedades ....


Em verificação de erros, click no botão “Verificar Agora”. Marque as duas opções (Corrigir erros e procurar setores defeituosos), em seguida click em “iniciar”.


No meu caso isso foi suficiente, problema resolvido! Agora, caso você não tenha um outro SO de opção pode ser que seja necessário usar o CD de instalação do Windows. A busca que fiz no Google retornou muitas ocorrências desse problema no XP, ao que parece esse problema é bem comum.

Segue o procedimento para reparação do SO via CD de instalação:

Antes de partir para a FORMATAÇÃO, vc pode tentar usar o console de restauração do WINDOWS. Com ele você poderá usar linhas de comando para iniciar ferramentas de recuperação, iniciar e parar serviços, acessar arquivos no HD, substituir arquivos corrompidos do sistema, etc. O Console de Recuperação é acessado através do CD de instalação do Windows.
Para ter acesso a ele você deve dar boot no sistema com o CD do Windows. Se o setup do computador estiver configurado para dar boot inicialmente pelo drive de CD-Rom, basta inserir o CD e reiniciar o computador. Após o boot pelo CD, pressione alguma tecla para iniciar a instalação do Windows. Em seguida a tela de “Bem-vindo”, pressione a tecla R para reparar uma instalação do Windows XP. Um menu listará uma, ou mais instalações do Windows no HD, digite o número relativo ao Windows que você deseja recuperar e
pressione “Enter”. Caso exista senha, surgirá o prompt para que você entre com o login de Administrador. Em seguida, aparece o console de recuperação. Siga os passos:
1º digite o número correpondente ao HD que será recuperado
2º senha, se houver
3º digite - cd system32
4º digite - cd config
5º digite - ren system system.old
6º digite - copy c:\windows\repair\system
7º digite - exit

Após a reinicialização o windows deverá estar recuperado.
Para quem quiser pesquisar mais, veja em: Suporte MS.
Pode ser útil tb um tutorial.

Artigo completo (View Full Post)

domingo, 13 de maio de 2007

Private, Public, Published ... Escopo de visibilidade

Um conceito muito importante do paradigma OO é o encapsulamento. Ele define a visibilidade dos membros de uma classe. Cabe lembrar que esse conceito não é exclusivo da orientação a objetos. A preocupação com o escopo e visibilidade, já na estruturação era uma questão extremamente relevante. Na verdade, uma das razões de ser da estruturação é justamente uma adequação melhor da questão da visibilidade. Que tinha na organização modular, conjugada com os conceitos de coesão e acoplamento, a representação lógica dos seus princípios.
Eu costumo “dramatizar” para meus alunos, como recurso didático, que a orientação a objetos, com relação ao encapsulamento, não propôs nada de novo. Não menos importante por isso, o que ela faz é simplesmente pegar esse conceito e leva-lo as últimas conseqüências. Aperfeiçoando, na minha opinião, o que já havia sido proposto pela Teoria Geral de Sistemas. Um sistema é sempre um subsistema de um outro em nível hierárquico mais alto (isso me lembra o final do filme MIB... hehehe ... mas sem cao, isso é importante). Amigo, isso era vanguarda no império do Cobol! Se liga!!!! Entretanto, ainda hoje, parece, e não sou eu o único a falar sobre isso, que a ficha ainda não caiu. Eu estou cansado de ver programas em Java que começam com um “public static void main(String args[])”, dentro dele vc pode encontrar de tudo, parece até a bolsa do “gato felix”. Na mesma e única classe você encontra desde

public static Connection getConnection()
throws ClassNotFoundException, SQLException {
String connectStr = "jdbc:odbc:BancoDoido ";

String username = "";
String password = "";
if (c == null) {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
c = DriverManager.getConnection(connectStr);
}
return c;
}


até comando SQL .... creeedooo!!!!

public void cadastar(dado1, dado2, ... dadoN)
{
‘Insert into ......’
}

public void alterar(dado1, dado2, ... dadoN)
{
‘Update tabela set......’
}

public void excluir(dado)
{
‘Delete from tabela where ....’
}


Isso não é um problema RESTRITO a uma tecnologia específica, seja em Delphi, VB, ASP, passando pelo PHP ao C++, observamos recorrentemente essa falha. Com um agravante, hoje é grande a parcela dos programadores, que a pesar de freqüentarem, desde a graduação as pós e MBAs da vida, aulas de AOO e POO, justificarem (com a maior cara de pau) a modularização digamos pouco ortodoxa, para não dizer porca, de seus sistemas, que por uma questão de produtividade assim o fazem. Respaldados por um reducionismo digno da mais pura filosofia de botequim, cujo o genial objeto de argumentação é sustentado pela cínica pergunta retórica: “Até que ponto não perderemos produtividade ... nos abstendo do “rococó Bizonho”?”. Os açougueiros de toga com seu objetos perfurocortantes assassinam Yourdon, Page Jones, Chris Gane, Pressman e est ... até o Tanenbaum sai decepado nesse cenário Tarantiniano patético.
Então ... voltando ao assunto ... Por isso, justamente para possibilitar ao programador/analista uma opção dele não ser lembrado como exímio representante do estilo rococó bizonho D’Mono Neurônio, existe o encapsulamento. Que, por sua vez, para ser feito de forma adequada deve seguir harmoniosamente o conceito de escopo de visibilidade.
Entretanto, existe um porém, infelizmente você não tem uma fórmula para se construir classes, ou módulos, que equacionem esse conceito perfeitamente, sob um ponto de vista absoluto. Nenhuma heurística de encpasulamento vai ser garantida de nada, porque em última análise quem vai definir o que vai ficar visível, ou não, é você. Portanto, alcançar um grau satisfatório de coesão dos seus módulos depende, em parte (uma boa parte, na minha opnião), de bom senso. Em contrapartida, a boa notícia é que a outra parte depende de você entender bem as definições que veremos a seguir:

Primeiro, leia o artigo que o Felipe escreveu sobre isso, em seguida volte.
Uma regra básica, que ajuda bastante: A interface de cada módulo, ou para cada módulo, deve ser definida de forma que não revele nada sobre o funcionamento do mesmo. A velha idéia de caixa preta. O Exemplo que o Felipe colocou sobre a televisão foi show!

Quando estamos especificamente definindo uma classe, podemos entender encapsulamento como a forma de se harmonizar os membros dessa classe, ou seja, os atributos, dados da classe, e as funções, operações que serão feitas sobre esses dados. Sobre uma definição que oculte, eficientemente, os detalhes dessa implementação. Lembre-se da “caixa preta”.

Em Delphi language, as palavras chaves que definem o escopo de visibilidade dos membros da classe, na seção delimitada por elas. Vejamos:

  • Private – Visibilidade exclusiva a própria classe. Tudo que estiver declarado na seção private da classe o escopo de visibilidade estará restrito a própria classe. Nem mesmo a instância enxerga.
  • Protected – Tudo que estiver declarado em protected o escopo de visibilidade estará restrito somente a própria classe e aos seus descendentes. Ou seja, somente a própria classe e as que estenderem dela conseguem acessar o que esta definido em protected.
  • Public – Nenhuma restrição de visibilidade. Conforme o próprio significado da palvra chave, público, indica que todos tem acesso ao que estiver definido ali.
  • Published – Visibilidade idêntica ao escopo definido pela public. Ou seja visibilidade irrestrita. O que difere uma da outra é que o Delphi gera RTTI para os membros definidos dentro do escopo dessa seção. Por isso esses membros podem ser listados pelo Object Inpector e serem acessados em design-time.
  • Automated – Mesma visibilidade dos membros public, com uma característica: Informação se automação é gerada para os membros nela declarados. É mantida por questões de compatibilidade com versões anteriores. Infromações de automação é pertinente a API OLE Automation.

Até aqui tudo bem? Quase! Seria perfeito se não fosse um probleminha. Existe um conceito em OO sobre classes amigas, que cada linguagem de programação deu suporte a ele de forma diferente. No Delphi, a Borland, na época, implementou da seguinte forma: Não há restrição se visibilidade para classes definidas na mesma unit. Na prática isso joga todo o discurso sobre encapsulamento por água abaixo.
Só que o homem evolui, o mundo evolui e a Borland também evoluiu. Por conta do frame work .Net, a Borland teve que, para manter compatibilidade com a CLS (Common Language Specification) da .Net, introduzir dois escopos novos: Strict private e Strict protected. Eles podem ser usados também em aplicações win32 e fazem rigorosamente o que o private e o protected não fazem. Eles acabam com a visibilidade das classes amigas. Os membros declarados dentro do escopo de strict private possuem visibilidade restrita a classe mesmo para as classes definidas na mesma unit. O mesmo para strict protected, os membros declarados nela somente são acessíveis a própria classe e aos seus descendentes.

O objetivo do encapsulamento é o ocultamento de informações específicas. De que forma podemos fazer isso? Restringindo o escopo, restringindo a visibilidade. Qual o objetivo disso? Conseguir um isolamento das funcionalidades de um determinado módulo, de maneira que o entendimento (legibilidade) seja fácil, a manutenção também seja pouco custosa (não reflita para outros módulos). Atingindo esse grau de isolamento esse módulo poderá ser reutilizado. Portanto, concluindo, o encapsulamento traz, imediatamente, para o desenvolvedor três vantagens ao ser empregado: Fácil entendimento, maior manutenibilidade e reuso. Voltando ao exemplo da Tv, quando vc for comprar um aparelho novo, pouco vai importar a tecnologia empregada no produto. Seja plasma, LCD, ou sei lá o que, o usabilidade dos controles remotos são quase que padronizadas. Por isso você vai confiante comprar o produto sabendo que sem o menor problema, em poucos minutos você estará assistido seu programa favorito.

Pra finalizar, a maior e mais aprazível vantagem de você dedicar o devido cuidado com encapsulamento nos seus programas é, por exemplo: num conturbado dia 23 de dezembro, às 15:00, às margens do dead line, terminar o módulo previsto e de repente, involuntariamente, escapar em voz alta: “Pronto!!! Está funcionando!! Eu amo isso!!!!”. Duvido, e faço pouco, se o adepto do rococó bizonho D’Mono Neurônio é capaz da mesma coisa.


Artigo completo (View Full Post)

quarta-feira, 9 de maio de 2007

Estendendo a funcionalidade do tipo String

Olá a todos.

Vamos falar um pouco sobre javascript.

Conhece o tipo String. Já sentiu falta alguma vez de algum recurso que o tipo não dispõe? Eu já; e um exemplo na cara é o trim (aquele que retira os espaços das extremidades).

Incrível o javascript não ter, não é... Mas tem uma coisa incrível que o javascript tem, que é a possibilidade de estender a funcionalidade de qualquer classe e tipo de dados.

Cada elemento tem uma propriedade chamada prototype, que nos permite a definição de novos métodos da classe.

Vou mostrar como eu fiz minha extensão da classe String:


primeiro vamos criar o trimLeft - que retira todos os espaços à esquerda da string:

String.prototype.trimLeft = function() { return this.replace(/\s*((\S+\s*)*)/, "$1"); };


Agora o trimRight - retira os espaços à direita:

String.prototype.trimRight = function() { return this.replace(/((\s*\S+)*)\s*/, "$1"); };


Por fim, usando os dois, o método trim, que 'capa' a string:

String.prototype.trim = function() { return this.trimLeft().trimRight(); };


Legal! Legal! Legal! Eh..... como é que usa? Eu tentei trim(variavel) mas não funcionou...

Agora vamos à parte mais legal da parada: como o método foi definido para o tipo String, todas as instâncias de String possuem estes três novos métodos:

var variavel = " Olá ";
var var1 = variavel.trimLeft(); // var1 é "Olá "
var var2 = variavel.trimRight(); // var2 é " Olá"
var var3 = variavel.trim(); // var3 é "Olá"

Maneeeeeeeeiro...

Assim como o tipo string é possível estender qualquer tipo de dados em javascript adicionando funcionalidades através do membro prototype. Solte a imaginação e faça bom uso!

Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

domingo, 6 de maio de 2007

Comentando linhas de código

Saber fazer uso de comentários em seus programas pode trazer um ganho de produtividade significativo nos seus projetos. Definir um POP (procedimento operacional padrão) que formalize a utilização de comentários para auto-documentação dos módulos implementados é uma prática fundamental adotada pelas equipes de desenvolvimento, fabricas, houses, de software sérias.
Em contra partida, usar comentários para manutenção de lixo, código de teste, código errado, e desatualizado, nos seus fontes é totalmente condenável. Alias, é exatamente isso que acontece quando não se adota uma pratica formalizada para o emprego de comentários.

No Delphi existem alguns tipos de comentários, vejamos:

“//” Barra – barra: comenta uma linha apenas. Exemplo:

procedure TForm1.Edit1Click(Sender: TObject);
begin
// esse código será executado se vc clickar no Edit1

Form1.Caption := (Sender as TEdit).Text;
// A linha de código abaixo está comentada
//Form1.Color := (Sender as TEdit).Color;
end;

Continua ....

“{}” Chaves: Comenta um bloco de código. Ou seja, comentário de várias linhas. Exemplo:

procedure TForm1.FormClick(Sender: TObject);
begin
{Esse código será executado se o Form1 for clickado.
Observe que neste exemplo eu posso comentar mais de uma linha
usando as chaves. }
if Form1.Height > 100 then
Form1.Height := Form1.Height - 20;
ShowMessage('Vc clickou no Form1!! BHUAHAUHA ...');
end;

“(**)” Parêntese + asterístico: Comenta um bloco de código. Ou seja, comentário de várias linhas. Exemplo:

procedure TForm1.FormResize(Sender: TObject);
const
msgZn = 'O %s foi redimencionado: Altura - %d; Largura - %d';
begin
(*Esse código será executado cada vêz que
o Form1 for dimencionado. Observe que neste
exemplo eu posso comentar mais de uma linha
usando Parêntese + asterístico. *)
ShowMessage(Format(msgZn, [Form1.Name, Form1.Height, Form1.Width]));
end;


Qual a diferença entre os comentários de bloco, de mais de uma linha (várias linhas)? Por que eu preciso ter dois tipos diferentes de comentários diferentes que fazem exatamente a mesma coisa? Para que vc possa aninhar comentários. Não é possível aninhar comentários do mesmo tipo. Exemplo:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
{ Esse exemplo mostra como comentários podem ser aninhados
A := B; Creeeeeedddooooooo
// comentei uma linha ...
}

(*
{ eu ai fazer este código assim...
Form1.Caption := Key;
Mas, mudei de idéia ...
}
Mais comentários ... *)

Form1.Caption := Form1.Caption + Key;
end;


OBS: Lembrando, qualquer coisa que pareça um comentário, mas começa com o caracter “$” (dollar), não é um comentário. É uma diretiva de compilação.

Novidade importante e interessante

O BDS possui suporte aos comentários para documentação “XML”. O Delphi extrai esses comentários da sua unit e salva como XML. A mesma lógica vigente para os comentários anteriormente exemplificados, vale para os seus respectivos comentário para documentação XML.

/// - Comentário de uma única linha.
(*! *) - Comenta um bloco de código. Ou seja, comentário de várias linhas.
{!} - Comenta um bloco de código. Ou seja, comentário de várias linhas.


type
/// Esse é o Form1 - este é um comentário para documentação XML.
TForm1 = class(TForm)
Edit1: TEdit;
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure FormResize(Sender: TObject);
procedure FormClick(Sender: TObject);
(*! Neste artigo estamos abordando comentários na unit de código.
Estamos testando também a nova funcionalidade de documentação do BDS.
!*)
procedure Edit1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

O BDS possui uma funcionalidade de documentação das units. Essa funcionalidade é ativada nas opções de projeto: Menu Projetc ► Options ► No item da treeview ► Compiler, em documentation, marque a checkbox “Generate XML documentation”.



Agora, faça um rebuild da aplicação: Menu Projetc ► Build Project (Shift +F9). Veja no diretório onde você salvou o exemplo, dois arquivos novos: “Unit1.xml” e “project1.xml”.



Esse XML pode ser processado por ferramentas que geram documentação nos mais diversos formatos. Além disso, o conteúdo desse arquivo pode ser consumido pelo help do Delphi.



O Doc-O-Matic, por exemplo, é uma excelente ferramenta para gerar documentação a qual poderia ser usada para consumir o XML gerado pelo Delphi para ducumetação.


Ah! Falando em Doc-O-Matic, lembrei de um lance: O comentário para documentação tem que ser feito em áreas específicas da unit. Lembrei disso porque no Doc-O-Matic também funciona dessa forma. Durante a composição dos exemplos para esse artigo percebi que o Delphi não considerou o comentário que fiz dentro do procedimento. Após um breve momento de indignação, lembrei que no Doc-O-Matic os comentários a respeito de métodos, funções e procedimentos deveriam ficar exatamente na linha superior ao corpo do procedimento. Exemplo:

{! Comentário para documentação XML deve ficar aqui! Este é o evento OnClick do Form1}
procedure TForm1.FormClick(Sender: TObject);
begin
{Esse código será executado se o Form1 for clickado.
Observe que neste exemplo eu posso comentar mais de uma linha
usando as chaves. Ess comentário não vai para o XML ...}
if Form1.Height > 100 then
Form1.Height := Form1.Height - 20;
ShowMessage('Vc clickou no Form1!! BHUAHAUHA ...');
end;



Artigo completo (View Full Post)

 
BlogBlogs.Com.Br