Skip to main content

Examples

Practical examples demonstrating common use cases for KeraDB.

Todo Application

A simple todo list application demonstrating CRUD operations.

const { KeraDB } = require('keradb');

class TodoApp {
constructor(dbPath) {
this.db = new KeraDB(dbPath);
this.todos = this.db.collection('todos');
this.init();
}

async init() {
// Create indexes for better performance
await this.todos.createIndex({ userId: 1 });
await this.todos.createIndex({ completed: 1 });
await this.todos.createIndex({ createdAt: -1 });
}

async addTodo(userId, title, description) {
const result = await this.todos.insertOne({
userId,
title,
description,
completed: false,
createdAt: new Date(),
updatedAt: new Date()
});
return result.insertedId;
}

async getTodosByUser(userId, showCompleted = false) {
const query = { userId };
if (!showCompleted) {
query.completed = false;
}
return await this.todos.find(query)
.sort({ createdAt: -1 })
.toArray();
}

async completeTodo(todoId) {
return await this.todos.updateOne(
{ _id: todoId },
{
$set: {
completed: true,
completedAt: new Date(),
updatedAt: new Date()
}
}
);
}

async updateTodo(todoId, updates) {
return await this.todos.updateOne(
{ _id: todoId },
{
$set: {
...updates,
updatedAt: new Date()
}
}
);
}

async deleteTodo(todoId) {
return await this.todos.deleteOne({ _id: todoId });
}

async getStats(userId) {
const allTodos = await this.todos.find({ userId }).toArray();
const completed = allTodos.filter(t => t.completed).length;

return {
total: allTodos.length,
completed,
pending: allTodos.length - completed
};
}

async close() {
await this.db.close();
}
}

// Usage example
async function main() {
const app = new TodoApp('./data/todos.db');

// Add todos
await app.addTodo('user1', 'Buy groceries', 'Milk, eggs, bread');
await app.addTodo('user1', 'Write documentation', 'Complete API docs');
await app.addTodo('user1', 'Review PRs', 'Check pending pull requests');

// Get user's todos
const todos = await app.getTodosByUser('user1');
console.log('Active todos:', todos);

// Complete a todo
if (todos.length > 0) {
await app.completeTodo(todos[0]._id);
}

// Get statistics
const stats = await app.getStats('user1');
console.log('Stats:', stats);

await app.close();
}

main();

User Management System

A user management system with authentication and role-based access.

const { KeraDB } = require('keradb');
const crypto = require('crypto');

class UserManager {
constructor(dbPath) {
this.db = new KeraDB(dbPath);
this.users = this.db.collection('users');
this.sessions = this.db.collection('sessions');
this.init();
}

async init() {
// Create unique index on email
await this.users.createIndex({ email: 1 }, { unique: true });
await this.users.createIndex({ role: 1 });
await this.sessions.createIndex({ userId: 1 });
await this.sessions.createIndex({ expiresAt: 1 });
}

hashPassword(password) {
return crypto.createHash('sha256').update(password).digest('hex');
}

async createUser(email, password, name, role = 'user') {
const hashedPassword = this.hashPassword(password);

try {
const result = await this.users.insertOne({
email,
password: hashedPassword,
name,
role,
active: true,
createdAt: new Date(),
lastLogin: null
});

return result.insertedId;
} catch (error) {
if (error.code === 'DUPLICATE_KEY') {
throw new Error('Email already exists');
}
throw error;
}
}

async authenticate(email, password) {
const hashedPassword = this.hashPassword(password);
const user = await this.users.findOne({
email,
password: hashedPassword,
active: true
});

if (!user) {
return null;
}

// Update last login
await this.users.updateOne(
{ _id: user._id },
{ $set: { lastLogin: new Date() } }
);

// Create session
const sessionId = crypto.randomBytes(32).toString('hex');
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours

await this.sessions.insertOne({
sessionId,
userId: user._id,
createdAt: new Date(),
expiresAt
});

return { user, sessionId };
}

async getUserBySession(sessionId) {
const session = await this.sessions.findOne({
sessionId,
expiresAt: { $gt: new Date() }
});

if (!session) {
return null;
}

return await this.users.findOne({ _id: session.userId });
}

async getUsersByRole(role) {
return await this.users.find({ role, active: true }).toArray();
}

async updateUserRole(userId, newRole) {
return await this.users.updateOne(
{ _id: userId },
{ $set: { role: newRole } }
);
}

async deactivateUser(userId) {
await this.users.updateOne(
{ _id: userId },
{ $set: { active: false } }
);

// Delete all sessions
await this.sessions.deleteMany({ userId });
}

async logout(sessionId) {
return await this.sessions.deleteOne({ sessionId });
}

async close() {
await this.db.close();
}
}

// Usage example
async function main() {
const userMgr = new UserManager('./data/users.db');

// Create users
await userMgr.createUser('admin@example.com', 'password123', 'Admin User', 'admin');
await userMgr.createUser('john@example.com', 'password123', 'John Doe', 'user');

// Authenticate
const auth = await userMgr.authenticate('john@example.com', 'password123');
console.log('Authenticated:', auth.user.name);

// Get user by session
const user = await userMgr.getUserBySession(auth.sessionId);
console.log('Session user:', user.name);

// Get all admins
const admins = await userMgr.getUsersByRole('admin');
console.log('Admins:', admins);

await userMgr.close();
}

main();

Configuration Store

A flexible configuration management system with versioning.

const { KeraDB } = require('keradb');

class ConfigStore {
constructor(dbPath) {
this.db = new KeraDB(dbPath);
this.configs = this.db.collection('configs');
this.history = this.db.collection('config_history');
this.init();
}

async init() {
await this.configs.createIndex({ key: 1 }, { unique: true });
await this.configs.createIndex({ category: 1 });
await this.history.createIndex({ key: 1 });
await this.history.createIndex({ timestamp: -1 });
}

async set(key, value, category = 'default', description = '') {
const now = new Date();

// Get current value for history
const current = await this.configs.findOne({ key });
if (current) {
// Save to history
await this.history.insertOne({
key,
value: current.value,
category: current.category,
description: current.description,
timestamp: current.updatedAt
});
}

// Update or insert config
await this.configs.updateOne(
{ key },
{
$set: {
key,
value,
category,
description,
updatedAt: now,
createdAt: current ? current.createdAt : now
}
},
{ upsert: true }
);
}

async get(key, defaultValue = null) {
const config = await this.configs.findOne({ key });
return config ? config.value : defaultValue;
}

async getByCategory(category) {
const configs = await this.configs.find({ category }).toArray();
return configs.reduce((acc, cfg) => {
acc[cfg.key] = cfg.value;
return acc;
}, {});
}

async getAll() {
const configs = await this.configs.find().toArray();
return configs.reduce((acc, cfg) => {
acc[cfg.key] = cfg.value;
return acc;
}, {});
}

async delete(key) {
const current = await this.configs.findOne({ key });
if (current) {
// Save to history before deleting
await this.history.insertOne({
key,
value: current.value,
category: current.category,
description: current.description,
timestamp: new Date(),
deleted: true
});
}

return await this.configs.deleteOne({ key });
}

async getHistory(key, limit = 10) {
return await this.history.find({ key })
.sort({ timestamp: -1 })
.limit(limit)
.toArray();
}

async restore(key, timestamp) {
const historical = await this.history.findOne({ key, timestamp });
if (!historical) {
throw new Error('Historical version not found');
}

await this.set(
key,
historical.value,
historical.category,
historical.description
);
}

async close() {
await this.db.close();
}
}

// Usage example
async function main() {
const config = new ConfigStore('./data/config.db');

// Set configurations
await config.set('app.name', 'My Application', 'app', 'Application name');
await config.set('app.version', '1.0.0', 'app', 'Application version');
await config.set('db.host', 'localhost', 'database', 'Database host');
await config.set('db.port', 5432, 'database', 'Database port');

// Get single value
const appName = await config.get('app.name');
console.log('App name:', appName);

// Get by category
const dbConfig = await config.getByCategory('database');
console.log('Database config:', dbConfig);

// Update value
await config.set('app.version', '1.1.0', 'app', 'Updated version');

// Get history
const history = await config.getHistory('app.version');
console.log('Version history:', history);

// Get all configs
const allConfig = await config.getAll();
console.log('All config:', allConfig);

await config.close();
}

main();

Next Steps