Este tutorial tem como objetivo apresentar o módulo de
persistência do TDK utilizado para o acessar e manipular elementos de um
banco de dados TerraLib.
|
Aguarde. Em construção !!! Abaixo uma idéia do que estamos preparando ...
|
|
Introdução
|
|
O módulo de persistência disponibiliza funcionalidades de alto nível que
permitem persistir, consultar e atualizar informações em um banco de dados
Terralib.
Este módulo faz acesso ao banco de dados através de drivers pertencente aos
repositório de conexões, que oferecem duas funcionalidades básicas: criar um
banco de dados novo e estabelecer conexão com algum banco de dados existente.
Para seguir o tutorial do módulo de persistência precisamos que você conheça
alguns conceitos dos objetos que existem na Terralib. Para começar vamos
apresentar estes conceitos de forma bem resumida, visando apenas que você
consiga entender e fazer os exemplos deste módulo.
Primeiro, na Terralib, pontos, linhas e polígonos são tipos de geometrias.
Um objeto geográfico na Terralib está associado a uma ou mais geometrias e a um
conjunto de atributos convencionais. Por exemplo, um município está associado a
n polígonos (imagine que ele pode ter várias ilhas) e a n atributos (como nome
e população).
Um layer é um conjunto de objetos geográficos. Por
exemplo, um conjunto de municípios de um estado é um layer.
Um tema é uma apresentação de um layer. Ele possui
restrições e informações de visualização do layer. Por exemplo, um tema pode
definir que os municípios serão pintados de verde e as bordas em amarelo ou os
municípios com população acima de uma faixa serão pintados de vermelho e os
restantes de azul.
Uma view é um conjunto de temas.
No TDK a classe TdkObject é uma abstração de qualquer
objeto da Terralib, tendo como objetivo prover uma interface simples de acesso
a elementos de um banco de dados de modo que não seja necessário o entendimento
detalhado do modelo de dados da TerraLib. Através desta classe é possível
tratar de maneira uniforme objetos simples e coleções.
Durante o decorrer deste tutorial veremos vários exemplos utilizando
TdkObject’s, com isso a idéia irá fixar melhor e o leitor notará a grande
vantagem na utilização desta técnica.
A idéia de tratar todos os elementos de uma base de dados geográfica da mesma
forma sugere fortemente a criação de um identificador único para cada
TdkObject. O Global ID (GID) foi criado com esse propósito.
A idéia do GID é representar TkdObjects da mesma forma que o sistema de DNS
representa URL’s, dessa forma podemos ter um GID único para cada TdkObject de
todo um sistema (inclusive sistemas que englobam vários bancos de dados).
O GID é composto de: [Database Descriptor].[Object Type].[Object ID].
Com o Database Descriptor é possível obter um handler para o driver desse
banco através do serviço de persistência. o Object Type é um identificador do
tipo do TdkObject e o Object ID é um identificador do TdkObject dentro do
banco. O Object ID de um objeto é definido pelo ID do layer TerraLib ao qual
ele pertence (-1, por omissão) com o object_id (do TerraLib). Isso é necessário
para identificar um objeto univocamente em um banco TerraLib.
|
Dentre todas as funcionalidades que o módulo de persistência nos fornece, vamos
estudar as principais:
-
criação de um banco de dados
-
consulta de um objeto
-
atualização de um objeto
-
cadastro de um objeto
|
Instruções Iniciais
|
Em construção !
|
1) Criação de um Banco de Dados
|
Criamos um novo banco de dados e o inicializamos segundo o modelo Terralib
utilizando a classe createDatabaseModel. Esta classe insere um novo
driver no repositório de conexões, que ficará “disponível” no repositório para
futuros acessos.
Apesar de parecer pouco, o código abaixo ilustra tudo o que necessário para
criar uma base de dados completa utilizando TDK. Modificar o código para
receber outro banco de dados – como Oracle, por exemplo – seria um trabalho
muito simples. Bastando trocar o include para TdkOracleConDescriptor.h,
a classe e os parâmetros de construção da classe.
Para fazer um exemplo, siga os seguintes passos:
1.1) Crie um novo projeto como ensinado na seção
"Primeiros Passos"(Passos: 3 e 4) com o nome
TDK_PersistenceServ .
1.2) Ao criar o seu projeto, foi criado automaticamente o arquivo
TDK_PersistenceServ.cpp. Edite o código fonte deste arquivo para deixá-lo da
seguinte forma:
|
#include "stdafx.h"
#include "TdkException.h"
#include "TdkAccessConDescriptor.h"
#include "TdkPersistenceService.h"
void main(int argc, char* argv[])
{
try {
//Instancia um descritor da base Access a ser aberta.
TdkAccessConDescriptor desc("teste.mdb");
//Cria um novo banco de dados segundo o modelo Terralib.
TdkPersistenceService::createDatabaseModel(desc);
std::cout << "Banco TDK "<< desc.getDbKeyOut()<<" foi criado com sucesso.\n\n";
getchar();
} catch ( TdkException& ex ) {
std::cout << ex.trace();
}
}
|
|
|
|
|
1.3) Para executar a aplicação copie
todas as DLL's do diretório SVN_ROOT\bin\mtdebug\vc71\iupvipe\*.dll para
o PRJ_DIR/TDK_DBModel/TDK_DBModel/Debug/ onde encontra-se o executável
do aplicativo. (As siglas SVN_ROOT e PRJ_DIR são referentes ao
tutorial do HelloWorld)
1.4) Execute então o processo de build no seu projeto, pelo menu Build ->
Build Solution, e então execute seu projeto, usando o menu Debug -> Start
Without Debugging.
1.5) Se o TDK estiver devidamente configurado, a aplicação será construída
e iniciada corretamente, aparecendo como na tela abaixo.

1.6) O banco criado se encontra no diretório PRJ_DIR/TDK_DBModel/TDK_DBModel/teste.mdb
e possui a seguinte estrutura.

|
|
2) Consulta de Objeto
|
Agora que você aprendeu a criar um banco de dados, vamos te mostrar como acessar
e manipular os objetos armazenados. O método loadObject carrega um determinado
objeto armazenado no banco de dados para a memória. Assim conseguimos
manipulá-lo da forma desejada.
Siga os passos abaixo para fazer um exemplo com o método loadObject
para apresentar um atributo de um município na tela.
2.1) Crie um novo arquivo .cpp, chamado de TDK_loadObj.cpp, no
projeto atual como mostra a figura abaixo:


2.2) A seguir, clique em propriedades do TDK_PersistenceSer.cpp e desabilite-o
do projeto, como mostramos na figura abaixo.

2.3) Edite o código fonte do arquivo TDK_loadObj.cpp para deixá-lo da
seguinte forma:
|
#include "stdafx.h"
#include "TdkException.h"
#include "TdkAccessConDescriptor.h"
#include "TdkPersistenceService.h"
#include "TeDBConnectionsPool.h"
#include "TeDbConnection.h"
void main(int argc, char* argv[])
{
try {
//Instancia um descritor da base Access a ser aberta.
TdkAccessConDescriptor desc( "teste.mdb" );
//Connect the database and insert the driver int the pool
std::string sDbDesc = desc.getDbKey();
TeDBConnectionsPool::instance().getDatabase( sDbDesc );
int dbPoolIndx = TeDBConnectionsPool::instance().getDBConnectionIndx( sDbDesc );
//Registering default factories
TdkObjectFactory::defaultFactoriesRegistration();
//Define o identificador global do objeto que eu desejo carregar.(ID do Objeto, ID do Layer, Driver Index)
TdkObjectGID tdkObjGID;
tdkObjGID.setObjectId("1100");
tdkObjGID.setDbIndx(dbPoolIndx);
tdkObjGID.setTypeId(_TDK_GEOGRAPHIC_OBJECT);
tdkObjGID.setLayerId(2);
//Define o objeto geográfico através do seu Identificador Global
TdkGeographicObject tdkGeoObj(tdkObjGID);
//Carrega para a memória o Objeto
TdkLoadParams params;
params.inCache_ = false;
params.loadAllAttributes_ = true;
bool ret = TdkPersistenceService::loadObject(&tdkGeoObj, params);
//Pega o valor do atributo
std::string nome = tdkGeoObj.getAttributeValue("CITY_NAME");
std::cout << "Nome da Cidade: " << nome;
getchar();
}
catch ( TdkException& ex ) {
std::cout << ex.trace();
}
}
|
|
|
|
|
2.4) Execute então o processo de
build no seu projeto, pelo menu Build -> Build Solution, e então execute seu
projeto, usando o menu Debug -> Start Without Debugging.
|
|
3) Cadastro de Objeto
|
Agora vamos te mostrar como criamos um objeto no banco de dados. Isto é
feito utilizando o método InsertObject. Siga os passos seguintes:
3.1) Crie um novo arquivo .cpp no projeto atual com o nome de
TDK_InsertObj como ensinado no passo 2.1.
3.2) Clique em propriedades do TDK_LoadObj.cpp e desabilite-o do projeto
como no passo 2.2.
3.3) A seguir, edite o código fonte do arquivo TDK_InsertObj.cpp para deixá-lo
da seguinte forma:
|
#include "stdafx.h"
#include "stdafx.h"
#include "TdkException.h"
#include "TdkAccessConDescriptor.h"
#include "TdkPersistenceService.h"
#include "TeDBConnectionsPool.h"
void main(int argc, char* argv[])
{
try {
//Instancia um descritor da base Access a ser aberta.
TdkAccessConDescriptor desc( "teste.mdb" );
//Connect the database and insert the driver int the pool
std::string sDbDesc = desc.getDbKey();
TeDBConnectionsPool::instance().getDatabase( sDbDesc );
int dbPoolIndx = TeDBConnectionsPool::instance().getDBConnectionIndx( sDbDesc );
TdkObjectFactory::defaultFactoriesRegistration();
std::string themeName = "Cities";
TdkTheme* theme = (TdkTheme*) TdkPersistenceService::getObject(themeName, _TDK_THEME, desc.getDbKey());
if (theme == NULL)
{
cout << "Não existe tema de nome: "<< themeName <<"\n";
return;
}
//Define o identificador global do objeto que eu desejo carregar.
//(ID do Objeto, ID do Layer, Driver Index)
TdkObjectGID tdkObjGID("2000", 2, dbPoolIndx);
//Define o objeto geográfico através do seu Identificador Global
TdkGeographicObject tdkGeoObj(tdkObjGID);
//Define o valor do atributo
tdkGeoObj.setAttributeValue("NAME_CITY","Mondovi");
theme->addChild(&tdkGeoObj);
//Insere no Banco
TdkPersistenceService::insertObject(theme);
}
catch ( TdkException& ex ) {
std::cout << ex.trace();
}
}
|
|
|
|
3.4) Execute então o processo de
build no seu projeto, pelo menu Build -> Build Solution, e então execute seu
projeto, usando o menu Debug -> Start Without Debugging.
|
|
4) Atualização de Objeto
|
Atualizamos um objeto do banco de dados com o método UpdateObject. Nos
passos seguintes vamos atualizar o nome de um município.
4.1) Crie um novo arquivo .cpp no projeto atual com o nome de
TDK_UpdateObj como ensinado no passo 2.1.
4.2) Clique em propriedades do TDK_InsertObj.cpp e desabilite-o do projeto
como ensinado no passo 2.2.
4.3) Edite o código fonte do arquivo TDK_UpdateObj.cpp para
deixá-lo da seguinte forma:
|
#include "stdafx.h"
#include "stdafx.h"
#include "TdkException.h"
#include "TdkAccessConDescriptor.h"
#include "TdkPersistenceService.h"
#include "TeDBConnectionsPool.h"
void main(int argc, char* argv[])
{
try {
//Instancia um descritor da base Access a ser aberta.
TdkAccessConDescriptor desc( "teste.mdb" );
//Connect the database and insert the driver int the pool
std::string sDbDesc = desc.getDbKey();
TeDBConnectionsPool::instance().getDatabase( sDbDesc );
int dbPoolIndx = TeDBConnectionsPool::instance().getDBConnectionIndx( sDbDesc );
//Define o identificador global do objeto que eu desejo carregar.
//(ID do Objeto, ID do Layer, Driver Index)
TdkObjectGID tdkObjGID("1100", 2, dbPoolIndx);
//Define o objeto geográfico através do seu Identificador Global
TdkGeographicObject tdkGeoObj(tdkObjGID);
//Carrega para a memória o Objeto
bool ret = TdkPersistenceService::loadObject(&tdkGeoObj);
if(ret)
{
//Define o valor do atributo
tdkGeoObj.setAttributeValue("NAME_CITY","Cidade Nova");
TdkPersistenceService::updateObject(&tdkGeoObj);
}
}
catch ( TdkException& ex ) {
std::cout << ex.trace();
}
}
|
|
|
|
4.4) Execute então o processo de
build no seu projeto, pelo menu Build -> Build Solution, e então execute seu
projeto, usando o menu Debug -> Start Without Debugging.
|
|
Topo ^
|