HTML5  - Armazenamento de dados no Cliente - IndexedDB


 No artigo de hoje eu vou abordar o novo recurso do HTML5 para armazenamento de dados no cliente usando o IndexedDB.

 

Armazenar dados localmente no cliente sempre foi uma necessidade e um problema em aplicações web.

 

Até alguns tempos atrás a única forma de armazenamento local de dados no cliente oferecido pelas aplicações web eram os cookies com toda a problemática envolvida na sua utilização.

 

O HTML5 veio para mudar esse quadro oferecendo uma alternativa aos cookies para armazenar dados localmente no cliente.
 

O HTML5 fornece quatro tipos diferentes de armazenamento de dados localmente nas máquinas do cliente. Eles são:

  1. Local Storage - armazena dados sem data de expiração;
  2. Web SQL Storage
  3. Session Storage - armazena dados apenas para a sessão atual;
  4. Indexed DB

O Local Storage e o Web SQL Storage são conhecidos como Web storage, a interface comum de programação para páginas web. Eles são uma evolução dos cookies e são limitados em tamanho, variando entre 5 MB e 10 MB. Eles não enviam os dados para o servidor, mas os armazenam localmente nas máquinas cliente. (O Local Storage é um armazenamento persistente enquanto o Session Storage é transitório. )

 

Ocorre que o consórcio W3C descontinuou o desenvolvimento do Web SQL Storage. Confira neste link: http://www.w3.org/TR/webdatabase/

 

Dessa forma o Web SQL Storage ainda é oferecido e pode ser usado, mas no futuro o suporte a este recurso deve desaparecer dos navegadores e você deve estar atento a esse detalhe.

 

O IndexedDB foi a alternativa que sobrou e, é a que tende a se consolidar como o engine de banco de dados no HTML5. O problema é que o suporte a este recurso é mais limitado, estando restrito aos navegadores Internet Explorer, FireFox, Chrome e BlackBerry.

 

O IndexedDB armazena dados em forma de objetos, juntamente com uma chave de índice. Tudo o que acontece no IndexedDB acontece por meio de transações e os objetos são agrupados em lojas de objetos. Assim ele contém armazenamentos de objetos e essas lojas de objetos contêm objetos juntamente com uma única keyPath.

 

Portanto, o IndexedDB é uma API para o armazenamento do lado do cliente de quantidades significativas de dados estruturados, o que permite também pesquisas de alto desempenho destes dados utilizando índices.

 

Atenção :  Como a maioria das soluções de armazenamento web, o IndexedDB segue uma política de mesma origem. Então, enquanto você pode acessar os dados armazenados dentro de um domínio, você não pode acessar dados em diferentes domínios.

 

No artigo de hoje eu vou mostrar como podemos usar os recursos do IndexedDB para armazenar dados localmente com Html5.

 

Você pode consultar a documentação do IndexedDB no Mozilla Developer Network- MDN neste link: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API

Recursos usados:

Armazenando dados localmente com IndexedDB : Conceitos Básicos

O IndexedDB é um sistema de banco de dados transacional, como um RDBMS baseado em SQL; No entanto, enquanto o último segunda tabelas com colunas fixas, o IndexedDB é um banco de dados orientado a objetos baseado em JavaScript que permite armazenar e recuperar objetos que são indexados com uma chave; quaisquer objetos suportados pelo algoritmo clone estruturado pode ser armazenado.

Você precisa especificar o esquema de banco de dados, abrir uma conexão com o banco de dados e, em seguida, recuperar e atualizar dados em uma série de operações.

1- Verificando o suporte ao IndexedDB e ao HTML5 Storage   

A primeira coisa a fazer é verificar se o seu navegador suporta o IndexedDB para isso você pode usar o código abaixo:

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(!window.indexedDB)
{
      console.log("Seu navegador não suporta o recurso IndexedDB");
}

Você também pode usar a biblioteca Modernizr para detectar o suporte ao armazenamento local :

if (Modernizr.localstorage) 
{
       // esse navegador suporta HTML5 Storage 
} 
else 
{
       // esse navegador NÃO suporta HTML5 Storage
}

2- Abrindo e acessando um banco de dados

Uma vez que sabemos que o IndexedDB é suportado, temos que abrir um banco de dados, mas você não pode simplesmente abrir um banco de dados, em vez disso o IndexedDB exige que você crie um pedido para abrir um banco de dados:

    var request = window.indexedDB.open("Macoratti", 2);

Para ter acesso a um banco de dados, chame open() no atributo IndexedDB de um objeto de window. (Este método retorna um objeto IDBRequest; operações assíncronas se comunicam com o aplicativo chamado disparando eventos em objetos IDBRequest.)

No código o primeiro parâmetro de Open() é o nome do banco de dados - Macoratti -  e segundo parâmetro é a versão da base de dados.

A versão permite que você represente o esquema atual do seu DB ou seja, as lojas de objetos armazenadas nele e suas estruturas. Se você atualizar seu banco de dados você só vai precisar de criar/excluir algumas lojas de objetos ao invés de criar/apagar todas as lojas de objetos.

Quando você vai aumentar a versão do seu banco de dados, o evento onupgradeneeded será acionado. Juntamente com onupgradeneeded, existem os eventos success, err e blocked:

    var db;

    request.onerror = function(event)
    {
         console.log("Erro ao abrir o banco de dados", event);
    }

    request.onupgradeneeded   = function(event)
    {
        console.log("Atualizando...");
        db = event.target.result;
        var objectStore = db.createObjectStore("Estudantes", { keyPath : "Codigo" });
    };

    request.onsuccess  = function(event)
    {
        console.log("Banco de dados aberto com sucesso.");
        db = event.target.result;
    }

O evento onupgradeneeded será chamado sempre que a página for acessada pela primeira vez no navegador do usuário ou se houver uma atualização na versão do banco de dados.

Assim, você terá que criar suas lojas de objetos apenas no evento onupgradeneeded.

Se não há nenhuma atualização na versão e a página foi aberta anteriormente, você receberá o evento onsuccess.

O evento onerror ocorre se houver algum erro e o evento onblocked ocorre se a conexão anterior nunca foi fechada.

No trecho de código acima, estamos criando uma loja objeto chamada "Estudantes" com chave de índice "Codigo".

3- Adicionando dados ao seu banco de dados

Para adicionar dados em nosso banco de dados, precisamos primeiro criar uma transação com permissão de leitura/escrita na nossa loja objeto.

Para executar qualquer ação no armazenamento de objetos precisamos criar uma transação. Após isso, acesse nossa loja objeto e adicione os dados a ela.

var transaction = db.transaction(["Estudantes"],"readwrite");
   transaction.oncomplete = function(event) 
   {
         console.log("Sucesso");
   };

   transaction.onerror = function(event) 
   {
         console.log("Error");
   };  
   
   var objectStore = transaction.objectStore("Estudantes");
   objectStore.add({Codigo: codigo, nome : nome});

4- Removendo dados

Para remover dados você também precisa criar uma transação e chamar a função delete() com a chave do objeto a ser removido:

db.transaction(["Estudantes"],"readwrite").objectStore("Estudantes").delete(Codigo);

5- Acessando um objeto pela sua chave

Para acessar um objeto pelo sua chave use a função get() passando a chave do objeto a ser retornado:

var request = db.transaction(["Estudantes"],"readwrite").objectStore("Estudantes").get(Codigo);
request.onsuccess = function(event)
{
      console.log("Nome : "+request.result.nome);    
};

6- Atualizando dados

Para atualizar um objeto primeiro obtenha o objeto com get(), e, depois de realizar a alteração nos dados, ponha o objeto de volta na loja usando a função put():

  var transaction = db.transaction(["Estudantes"],"readwrite");
  var objectStore = transaction.objectStore("Estudantes");
  var request = objectStore.get(Codigo);

  request.onsuccess = function(event)
  {
       console.log("Atualizado : "+request.result.name + " para " + nome);
       request.result.nome = nome;
       objectStore.put(request.result);
  };

IndexedDB : Código fonte do exemplo

Abaixo esta o código completo representando pelo arquivo Html5_IndexedDB.html : (Eu usei o editor de textos NotePad++ para criar o arquivo)

<!DOCTYPE html>
<html>
<head>
<title>IndexedDB</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
	var request, db;
	if(!window.indexedDB)
	{
		console.log("Seu navegador não suporta o recurso HTML5 IndexedDB");
	}
	else
	{
		request = window.indexedDB.open("Teste", 2);
		request.onerror = function(event){
			console.log("Erro ao abrir o banco de dados", event);
		}
	
		request.onupgradeneeded = function(event){
			console.log("Atualizando");
			db = event.target.result;
			var objectStore = db.createObjectStore("estudantes", { keyPath : "codigo" });
		};
		request.onsuccess = function(event){
			console.log("Banco de dados aberto com sucesso");
			db = event.target.result;
		}
	}
	$("#addBtn").click(function(){
		var nome = $("#nome").val();
		var codigo = $("#codigo").val();
		var transaction = db.transaction(["estudantes"],"readwrite");
		transaction.oncomplete = function(event) {
			console.log("Sucesso :)");
			$("#result").html("Adicionado com Sucesso");
		};
		transaction.onerror = function(event) {
			console.log("Erro :(");
			$("#result").html("Erro ao Adicionar");
		};
		var objectStore = transaction.objectStore("estudantes");
		objectStore.add({codigo: codigo, nome: nome});
	});
	
	$("#removeBtn").click(function(){
		var codigo = $("#codigo").val();
		db.transaction(["estudantes"],"readwrite").objectStore("estudantes").delete(codigo);
                          transaction.oncomplete = function(event){
			$("#result").html("Removido");
		};	
	});s
	
	$("#getBtn").click(function(){
		var codigo = $("#codigo").val();
		var request = db.transaction(["estudantes"],"readwrite").objectStore("estudantes").get(codigo);
		request.onsuccess = function(event){
			$("#result").html("Nome : "+request.result.nome);
		};
	});
	$("#updateBtn").click(function(){
		var codigo = $("#codigo").val();
		var nome = $("#nome").val();
		var transaction = db.transaction(["estudantes"],"readwrite");
		var objectStore = transaction.objectStore("estudantes");
		var request = objectStore.get(codigo);
		request.onsuccess = function(event){
			$("#result").html("Atualizando : "+request.result.nome + " para " + nome);
			request.result.nome = nome;
			objectStore.put(request.result);
		};
	});
});
</script>
</head>
<body>
<form>
<table border="0" width="100%">
	<tr>
		<td colspan="3"><b><font size="5" color="#0000FF">Macoratti .net</font></b></td>
	</tr>
	<tr>
		<td colspan="3"><hr></td>
	</tr>
	<tr>
		<td width="12%">Codigo</td>
		<td colspan="2"> <input type="text" name="codigo" id="codigo"/></td>
	</tr>
	<tr>
		<td width="12%">Nome</td>
		<td colspan="2">  <input type="text" name="nome" id="nome" /></td>
	</tr>
	<tr>
		<td width="12%">&nbsp;</td>
		<td>
			<input type="button" name="addBtn" value="Adicionar" id="addBtn"/>
			<input type="button" name="removeBtn" value="Remover" id="removeBtn"/>
			<input type="button" name="getBtn" value="Localizar" id="getBtn"/>
			<input type="button" name="updateBtn" value="Atualizar" id="updateBtn"/>
			</td>
		<td width="3%">&nbsp;</td>
	</tr>
</table>
</form>
<div id="result"></div>
</body>
</html>

Executando o arquivo no navegador Chrome teremos os seguintes resultados:

1- Incluindo dados

2- Localizando dados

3- Atualizando dados

4- Removendo dados

Pegue o projeto completo aqui:  Html5_IndexedDB.zip

Porque os judeus pedem sinal, e os gregos buscam sabedoria;
Mas nós pregamos a Cristo crucificado, que é escândalo para os judeus, e loucura para os gregos.
Mas para os que são chamados, tanto judeus como gregos, lhes pregamos a Cristo, poder de Deus, e sabedoria de Deus.
1 Coríntios 1:22-24

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti