Um micro ORM em JavaScript ES6 inspirado no CodeIgniter 3 Query Builder com suporte para MySQL/MariaDB e PostgreSQL
npm install @04l3x4ndr3/microbase-ormUm micro ORM em JavaScript puro ES6 inspirado no Query Builder do CodeIgniter 3, com suporte completo para MySQL/MariaDB e PostgreSQL.
- ✅ Interface Fluente: Sintaxe limpa e intuitiva para construção de queries
- âś… Multi-Database: Suporte nativo para MySQL/MariaDB e PostgreSQL
- ✅ Segurança: Proteção contra SQL Injection com prepared statements
- âś… ES6 Moderno: CĂłdigo JavaScript moderno com async/await
- âś… Zero DependĂŞncias Externas: Apenas drivers nativos do Node.js
- ✅ Inspirado no CodeIgniter: Métodos familiares para desenvolvedores PHP
shell
npm install 04l3x4ndr3/microbase-orm
`Instalar dependĂŞncias para MySQL (Opcional)
`shell
npm install mysql2
`
Instalar dependĂŞncias para MariaDB (Opcional)
`shell
npm install mariadb
`Instalar dependĂŞncias para PostgreSQL (Opcional)
`shell
npm install pg
`nota : Embora sejam opcionais, pelo menos uma das dependĂŞncias acima devem ser instalada.
Ou instalar ambos
`shell
npm install mysql2 pg mariadb
`🚀 Uso Rápido
`javascript
import Database from './Database.js';
// Configuração
const db = new Database({
driver: 'mysql', // ou 'postgres' ou 'mariadb'
host: 'localhost',
username: 'usuario',
password: 'senha',
database: 'meu_banco',
port: 3306 // ou 5432 para PostgreSQL
});// Conectar
await db.connect();
// SELECT simples
const usuarios = await db.select('*').from('usuarios').get();
// Desconectar
await db.disconnect();
`
🔧 Configuração
$3
`javascript
const config = {
driver: 'mysql',
host: 'localhost',
username: 'root',
password: 'senha',
database: 'meu_banco',
port: 3306
};
`$3
`javascript
const config = {
driver: 'postgres',
host: 'localhost',
username: 'postgres',
password: 'senha',
database: 'meu_banco',
port: 5432
};
`📖 Documentação da API
$3
#### select(campos)
`javascript
// Selecionar todos os campos
await db.select('*').from('usuarios').get();// Selecionar campos especĂficos
await db.select(['nome', 'email']).from('usuarios').get();
// Selecionar com string
await db.select('nome, email').from('usuarios').get();
`#### Funções de Agregação
`javascript
// Máximo
await db.selectMax('idade').from('usuarios').get();
await db.selectMax('idade', 'idade_maxima').from('usuarios').get();// MĂnimo
await db.selectMin('idade').from('usuarios').get();
// Média
await db.selectAvg('salario').from('usuarios').get();
// Soma
await db.selectSum('vendas').from('usuarios').get();
`#### distinct()
`javascript
await db.select('cidade').distinct().from('usuarios').get();
`$3
#### where(campo, valor, operador)
`javascript
// Igualdade simples
await db.select('*').from('usuarios').where('ativo', 1).get();// Com operador
await db.select('*').from('usuarios').where('idade', 18, '>').get();
// Objeto de condições
await db.select('*').from('usuarios').where({ ativo: 1, cidade: 'SĂŁo Paulo' }).get();
`#### orWhere()
`javascript
await db.select('*') .from('usuarios') .where('cidade', 'SĂŁo Paulo') .orWhere('cidade', 'Rio de Janeiro') .get();
`#### whereIn() / whereNotIn()
`javascript await db.select('*') .from('usuarios') .whereIn('id', [1, 2, 3, 4, 5]) .get();
await db.select('*') .from('usuarios') .whereNotIn('status', ['bloqueado', 'suspenso']) .get();
`#### whereLike()
`javascript await db.select('*') .from('usuarios') .whereLike('nome', '%JoĂŁo%') .get();
await db.select('*') .from('usuarios') .whereNotLike('email', '%spam%') .get();
`$3
`javascript
// INNER JOIN
await db.select('u.nome, p.descricao')
.from('usuarios u')
.join('perfis p', 'u.perfil_id = p.id') .get();// LEFT JOIN
await db.select('u.nome, p.descricao')
.from('usuarios u')
.leftJoin('perfis p', 'u.perfil_id = p.id')
.get();
// RIGHT JOIN
await db.select('u.nome, p.descricao')
.from('usuarios u')
.rightJoin('perfis p', 'u.perfil_id = p.id')
.get();
`$3
`javascript
await db.select(['cidade', 'COUNT(*) as total'])
.from('usuarios')
.groupBy('cidade').having('total', 10, '>')
.get();// MĂşltiplos campos
await db.select(['cidade', 'estado', 'COUNT(*) as total'])
.from('usuarios')
.groupBy(['cidade', 'estado'])
.get();
`$3
`javascript
// Ordenação simples
await db.select('*')
.from('usuarios')
.orderBy('nome', 'ASC')
.get();// Múltiplas ordenações
await db.select('*')
.from('usuarios')
.orderBy('cidade', 'ASC')
.orderBy('nome', 'DESC')
.get();
// Ordenação aleatória
await db.select('*')
.from('usuarios')
.orderByRandom() .limit(5)
.get();
`
$3
`javascript
// Limit simples
await db.select('*')
.from('usuarios')
.limit(10)
.get();// Limit com offset
await db.select('*')
.from('usuarios')
.limit(10, 20)
.get();
// Ou usando offset separadamente
await db.select('*')
.from('usuarios')
.limit(10)
.offset(20)
.get();
`$3
#### get()
`javascript
const resultados = await db.select('*').from('usuarios').get();
`#### first()
`javascript
const usuario = await db.select('*').from('usuarios').where('id', 1).first();
`#### count()
`javascript
const total = await db.select('*').from('usuarios').where('ativo', 1).count();
`#### getWhere()
`javascript
const usuarios = await db.getWhere('usuarios', { ativo: 1, cidade: 'SĂŁo Paulo' });
`$3
#### insert()
`javascript
// Insert simples
await db.insert('usuarios', { nome: 'JoĂŁo Silva', email: 'joao@email.com', ativo: 1 });// Insert em lote
await db.insert('usuarios', [
{ nome: 'JoĂŁo', email: 'joao@email.com' },
{ nome: 'Maria', email: 'maria@email.com' },
{ nome: 'Pedro', email: 'pedro@email.com' }
]);
`
#### replace() (apenas MySQL)
`javascript
await db.replace('usuarios', { id: 1, nome: 'JoĂŁo Santos', email: 'joao.santos@email.com' });
`$3
#### update()
`javascript
// Update com WHERE
await db.update('usuarios', { nome: 'JoĂŁo Santos' }, { id: 1 } );// Update usando query builder
await db.from('usuarios')
.where('ativo', 0)
.update('usuarios', { status: 'inativo' });
// Usando set()
await db.from('usuarios')
.set('nome', 'JoĂŁo Santos')
.set('email', 'joao.santos@email.com')
.where('id', 1)
.update('usuarios');
`$3
#### delete()
`javascript
// Delete simples
await db.delete('usuarios', { id: 1 });// Delete com query builder
await db.from('usuarios')
.where('ativo', 0)
.where('ultimo_login', '2023-01-01', '<')
.delete();
`#### emptyTable()
`javascript
await db.emptyTable('logs'); // TRUNCATE TABLE
`$3
#### query()
`javascript
// Query SQL direta
const resultado = await db.query('SELECT * FROM usuarios WHERE id = ?', [1]);
`#### getCompiledSelect()
`javascript
const sql = db.select('*')
.from('usuarios')
.where('ativo', 1)
.getCompiledSelect();console.log(sql); // SELECT * FROM
usuarios WHERE ativo = ?
`💡 Exemplos Avançados
$3
`javascript
const relatorio = await db.select([
'u.nome',
'u.email',
'p.descricao as perfil',
'COUNT(v.id) as total_vendas',
'SUM(v.valor) as valor_total'
])
.from('usuarios u')
.leftJoin('perfis p', 'u.perfil_id = p.id')
.leftJoin('vendas v', 'u.id = v.usuario_id')
.where('u.ativo', 1)
.whereIn('u.cidade', ['SĂŁo Paulo', 'Rio de Janeiro', 'Belo Horizonte'])
.groupBy(['u.id', 'u.nome', 'u.email', 'p.descricao'])
.having('total_vendas', 0, '>')
.orderBy('valor_total', 'DESC')
.limit(50)
.get();
`
$3
`javascript
await db.connect();
const connection = db.connection;// Para MySQL
await connection.beginTransaction();
try {
await db.insert('usuarios', { nome: 'JoĂŁo' });
await db.insert('perfis', { usuario_id: 1, tipo: 'admin' });
await connection.commit();
} catch (error) {
await connection.rollback(); throw error;
}
`$3
`javascript
// Criar um builder base
const usuariosAtivos = db.builder()
.from('usuarios')
.where('ativo', 1);// Usar o builder base para diferentes consultas
const administradores = await usuariosAtivos
.where('perfil', 'admin')
.get();
const vendedores = await db.builder()
.from('usuarios')
.where('ativo', 1)
.where('perfil', 'vendedor')
.get();
`🗂️ Estrutura de Pastas
`
projeto/
├── Database.js # Classe principal
├── QueryBuilder.js # Construtor de queries
├── database/
│ └── Connection.js # Gerenciador de conexões
├── drivers/
│ ├── MySQLDriver.js # Driver MySQL/MariaDB
│ └── PostgreSQLDriver.js # Driver PostgreSQL
└── examples/
└── usage.js # Exemplos de uso
`🔒 Segurança
- Prepared Statements: Todas as queries usam prepared statements
- Escape de Identificadores: Nomes de tabelas e campos sĂŁo automaticamente escapados
- Validação de Tipos: Validação automática de tipos de dados
- Sanitização: Valores são sanitizados antes da execução🧪 Testando
`javascript
// Teste de conexĂŁo
import Database from './Database.js';async function testarConexao() {
const db = new Database({
driver: 'mysql',
host: 'localhost',
username: 'root',
password: 'senha',
database: 'teste'
});
try {
await db.connect();
console.log('âś… ConexĂŁo estabelecida com sucesso!');
const resultado = await db.query('SELECT 1 as teste');
console.log('âś… Query executada:', resultado);
} catch (error) {
console.error('❌ Erro:', error.message);
} finally {
await db.disconnect();
}
}
testarConexao();
`
🤝 Contribuindo
1. Faça um fork do projeto
2. Crie uma branch para sua feature (git checkout -b feature/nova-feature)
3. Commit suas mudanças (git commit -am 'Adiciona nova feature')
4. Push para a branch (git push origin feature/nova-feature`)Nota: Este é um projeto educacional/experimental. Para uso em produção, considere ORMs estabelecidos como Sequelize, TypeORM ou Prisma.