Pitch: SecureDB, um pacote de banco de dados local

Mais ou menos uns 2 anos atrás eu precisava usar um banco de dados pra um projeto pequeno meu, só que como eu estava inciando na programação, não sabia nada sobre banco de dados. Por necessidade, resolvi criar o meu pacote banco de dados que seja de uso simples e prático. Então criei o SecureDB que é um banco de dados local que armazena os dados em JSON e conta com um sistema de criptografia segura.

Esse pacote, inicialmente foi criado apenas para projetos pequenos mas nada impede de ser usado em um projeto com escala maior.

Possibilidades

  1. Com esse pacote, os dados podem ser armazenados em arquivos-de-dados diferentes aumentando assim a organização e a performance da aplicação.
  2. É possivel criar infinitas "seções" de bancos de dados, ou seja, em um sistema de chats por exemplo, é possível organizar separadamente a seção de contas de usuários, uma seção de mensagens globais (se for um sistema igual o Discord), uma seção mensagens privadas e assim por diante...
  3. A criptografia implementada nesse pacote requer obrigatoriamente uma chave-de-segurança inserida pelo usuário e cada seção (citada acima) pode (por escolha do desenvolvedor) ter a sua própria chave-de-segurança tornando assim cada seção de banco de dados segura individualmente.
  4. Esse pacote é extremamente competente em ambiente de desenvolvimente, performance e tempo de busca e resposta é o ponto forte.
  5. Como o banco de dados é local, não é preciso aplicar Promises nas funções do pacote.

Requisitos

A ultima versão desse pacote foi desenvolvida especialmente para versão 16.x e acima do NodeJS. Pode ocorrer erros de compatibilidade se usar em versões anteriores a essa.

Instalação

npm install secure-db
# ou com yarn
yarn add secure-db
const { Database } = require('secure-db');
const db = new Database('my-database');

Modo de uso básico

// Salvar um objeto padrão
db.set('Felipe', { age: 30 }); // Felipe: { age: 30 }

// Adicionando um elemento à uma array
db.push('Felipe.books', 'Harry Potter'); // Felipe: { books: ['Harry Potter'] }

// Somando em um número
db.sum('Felipe.age', 3); // Felipe: { age: 33 }

// Subtraindo um número
db.sub('Felipe.age', 2); // Felipe: { age: 31 }

// Retorna os dados salvos
db.get('Felipe'); // Felipe: { age: 31, books: ['Harry Potter'] }
db.get('Felipe.books'); // Felipe: { books: ['Harry Potter'] }

Como dito acima, é possível criar vários bancos de dados separados

/* exemplo criando uma lista de usuários */
const { Database } = require('secure-db');
const user1 = new Database('users', 'user1');
const user2 = new Database('users', 'user2');
const user3 = new Database('users', 'user3');

user1.set({ name: 'Mark', age: 32 });
user3.set('name', 'Joana');

user1.get('name'); // 'Mark'
user2.get('name'); // undefined

user1.get('name'); // 'Mark'

Seguindo o exemplo anterior, é possível pegar uma lista de todos os bancos de dados existentes na seção criada

/* 
    Como no nosso exemplo criamos uma lista de usuários, 
    aqui vai retornar uma lista com o nome dos bancos de dados
    que são os nomes dos usuários que definimos
*/
const { getDatabases } = require('secure-db');

getDatabases('users', (user_list) => {
    user_list // ['user1', 'user2', 'user3']
});

Criptografia

Antes de habilitar a criptografia no nosso banco de dados, precisamos definir a nossa chave de segurança e o melhor lugar pra isso é usando o dotenv.

Em um arquivo chamado .env, escreva o seguinte:

SECURE_DB=sua_chave_de_segurança_aqui

Com a chave criada, para habilitar a criptografia é muito simples:

const db = require('secure-db');

db.security(process.env.SECURE_DB);

Agora todos os dados que forem gerenciados a partir dessa linha de codigo serão codificados com a sua chave de segurança.

Tabela de conteúdos


Conclusão

Se tiver alguma dúvida ou quiser reportar algum bug, sinta-se livre para comentar aqui nesse post ou abrir uma issue no repositório oficial desse pacote.

Esse pacote só está disponível ainda para CommonJS, em breve vou lançar uma versão para Module também.

Fiquei com uma dúvida:

Este banco de dados me parece "apenas" um key/value object storage. Ele não permite queries ou filtros etc... Certo?

Não estou querendo minimizar o trabalho feito. Me pareceu bom, útil e de fácil uso. E a funcionalidade de criptografia integrada me parece bem interessante. Mas para eu considerar um banco de dados, preciso de algumas funcionalidades que eu não vejo.

De qualquer forma, parabéns pelo projeto e pelo post muito bem construído

> Este banco de dados me parece "apenas" um key/value object storage. Ele não permite queries ou filtros etc... Certo? Sim sim, na verdade ele é bem direcionado à objetos JSON. É um sistema não muito profissional que inicialmente era só pra sanar as minhas necessidades. > Não estou querendo minimizar o trabalho feito. Me pareceu bom, útil e de fácil uso. E a funcionalidade de criptografia integrada me parece bem interessante. Mas para eu considerar um banco de dados, preciso de algumas funcionalidades que eu não vejo. Eu nunca estudei nada sobre bancos de dados pelo fato de nunca precisar nos meus projetos então realmente não sei de nada sobre. Sobre essas funcionalidades que você sente falta nesse pacote, quais seriam elas? Você poderia dar algum exemplo por favor? Ou se achar melhor, pode me dar uma direção para aprender sobre esse assunto e futuramente dar um upgrade no pacote.
Claro :) Parabéns pela vontade de aprender. Este projeto acaba sendo parecido com um memcached, que é essencialmente um cache em memória RAM (mas com um propósito é uma utilização bem diferente). Cada objeto é referenciado por uma chave única. Para ser um "banco de dados" (minha opinião) precisa ter funcionalidades de query, ou seja, filtro de dados. O standard de mercado para um banco de dados com objetos é o mongoDB (banco não relacional). Há também um standard que vale mencionar, que é um banco relacional que guarda tudo em um único arquivo: sqlite (é o banco usado nas apps Android, por exemplo) Mas não estou sugerindo implementar coisas só para se aproximar de ferramentas já existentes. O projeto como está já agrega valor, e a adição de novas funcionalidades pode aumentar a complexidade a um nível que tira o valor do projeto (ou não, depende em cada caso). Mas se quiser aprender: olhar para os exemplos que citei e implementar algumas daquelas features é uma boa ideia.