@cemiar/database-wrapper
v1.0.20
Published
Cemiar package to handle database wrapper
Downloads
1,003
Keywords
Readme
Cemiar Database Wrapper
Small, typed wrappers for MongoDB, Azure Redis Cache, and Azure Blob Storage. Focused on safe connection handling, timeouts, and simple APIs.
This package replaces the following legacy library:
| Legacy Package | Replaced By |
|----------------|-------------|
| cemiar-mongo | MongoDbClient (via DatabaseService) |
Install
npm install @cemiar/database-wrapperMongoDB usage
import { DatabaseService } from '@cemiar/database-wrapper';
const mongo = DatabaseService.setInstance(process.env.MONGO_URI as string);
await mongo.connect();
const id = await mongo.saveElement({ name: 'alpha' }, 'CemiarTest', 'WrapperTest');
const doc = await mongo.getElementById(id, 'CemiarTest', 'WrapperTest');Redis usage (Azure)
import { RedisWrapper } from '@cemiar/database-wrapper';
await RedisWrapper.setInstance(process.env.REDIS_URL as string);
const redis = RedisWrapper.getInstance();
await redis.connect();
await redis.setValue('key', 'value');
const value = await redis.getValue('key');
await redis.deleteKey('key');Environment variables
MongoDB:
MONGO_URI- Optional:
MONGO_DB,MONGO_COLLECTION
Redis (pick one):
REDIS_URL- Or:
REDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_TLS
Build
npm run buildIntegration tests
Tests use .env.local for credentials and skip suites if env vars are missing.
npm testNotes
- Mongo wrapper uses a singleton via
DatabaseService.setInstance(). - Redis wrapper uses a singleton via
RedisWrapper.getInstance().
Migration Guide
From cemiar-mongo
Update package.json
{
"dependencies": {
- "cemiar-mongo": "^1.0.19",
+ "@cemiar/database-wrapper": "^1.0.0"
}
}Update imports
- import { MongoDbClient, MongoClient, ObjectId } from "cemiar-mongo";
+ import { MongoDbClient, ObjectId } from "@cemiar/database-wrapper";
+ // Or use the alias:
+ import { DatabaseService, ObjectId } from "@cemiar/database-wrapper";Note:
MongoDbClientandDatabaseServiceare aliases for the same class.
Constructor changes
The new wrapper supports additional configuration options:
// Before (cemiar-mongo)
- const mongo = MongoDbClient.setInstance(process.env.MONGO_URI);
// After (@cemiar/database-wrapper) - simple
+ const mongo = MongoDbClient.setInstance(process.env.MONGO_URI);
// After (@cemiar/database-wrapper) - with options
+ const mongo = MongoDbClient.setInstance(
+ process.env.MONGO_URI,
+ { /* MongoClientOptions */ }, // MongoDB driver options
+ 30000, // Timeout in ms (default: 30000)
+ "DefaultDatabase", // Default database name (optional)
+ (event, error) => { // Event handler (optional)
+ console.log(`Mongo event: ${event}`, error);
+ }
+ );Method mapping
All methods from cemiar-mongo are available with the same signatures:
| cemiar-mongo | @cemiar/database-wrapper | Notes |
|--------------|--------------------------|-------|
| connect() | connect() | ✅ Same, now with timeout |
| getMongoClient() | getClient() | ⚠️ Renamed |
| saveElement(data, db, collection) | saveElement(data, db, collection) | ✅ Same |
| updateElement(id, set, db, collection) | updateElement(id, update, db, collection) | ✅ Enhanced (supports $set, $unset, $push, $pull) |
| getElementById(id, db, collection) | getElementById(id, db, collection) | ✅ Same |
| getOneElement(query, db, collection) | getOneElement(query, db, collection) | ✅ Same |
| searchElement(query, db, collection, sort) | searchElement(query, db, collection, sort) | ✅ Same |
| getAllElements(db, collection, sort) | getAllElements(db, collection, sort) | ✅ Same |
| deleteElement(id, db, collection) | deleteElement(id, db, collection) | ✅ Same |
New methods in @cemiar/database-wrapper
// Close connection
await mongo.close();
// Health check
const isConnected = mongo.isHealthy();
// Update with query (single document)
await mongo.updateOneElementByQuery(
{ status: "pending" },
{ $set: { status: "completed" } },
"MyDatabase",
"MyCollection"
);
// Update with query (multiple documents)
await mongo.updateElementsByQuery(
{ status: "pending" },
{ $set: { status: "completed" } },
"MyDatabase",
"MyCollection"
);
// Aggregation pipeline
const results = await mongo.aggregate(
[{ $match: { status: "active" } }, { $group: { _id: "$type", count: { $sum: 1 } } }],
"MyDatabase",
"MyCollection"
);
// Count documents
const count = await mongo.countDocuments(
{ status: "active" },
"MyDatabase",
"MyCollection"
);
// Bulk write operations
await mongo.bulkWrite(
[
{ insertOne: { document: { name: "test" } } },
{ updateOne: { filter: { _id: id }, update: { $set: { name: "updated" } } } }
],
"MyDatabase",
"MyCollection"
);Default database support
The new wrapper supports a default database, reducing boilerplate:
// Before: must specify database every time
await mongo.getElementById(id, "MyDatabase", "MyCollection");
await mongo.saveElement(data, "MyDatabase", "MyCollection");
// After: set default database once
const mongo = MongoDbClient.setInstance(
process.env.MONGO_URI,
{},
30000,
"MyDatabase" // Default database
);
// Now you can omit the database name
await mongo.getElementById(id, undefined, "MyCollection");
await mongo.saveElement(data, undefined, "MyCollection");Enhanced updateElement
The updateElement method now intelligently handles MongoDB operators:
// Simple update (auto-wraps in $set)
await mongo.updateElement(id, { name: "New Name" }, "DB", "Collection");
// Equivalent to: { $set: { name: "New Name" } }
// With operators (used as-is)
await mongo.updateElement(
id,
{
$set: { name: "New Name" },
$unset: { oldField: "" },
$push: { tags: "new-tag" }
},
"DB",
"Collection"
);Timeout handling
All operations now have automatic timeout protection:
// Default 30-second timeout
const mongo = MongoDbClient.setInstance(process.env.MONGO_URI);
// Custom timeout (60 seconds)
const mongo = MongoDbClient.setInstance(
process.env.MONGO_URI,
{},
60000
);Event handling
Monitor connection events:
const mongo = MongoDbClient.setInstance(
process.env.MONGO_URI,
{},
30000,
undefined,
(event, error) => {
switch (event) {
case 'close':
console.log('MongoDB connection closed');
break;
case 'error':
console.error('MongoDB error:', error);
break;
case 'reconnect':
console.log('MongoDB reconnected');
break;
case 'timeout':
console.warn('MongoDB timeout');
break;
}
}
);Quick migration example
- import { MongoDbClient } from "cemiar-mongo";
+ import { MongoDbClient } from "@cemiar/database-wrapper";
const mongo = MongoDbClient.setInstance(process.env.MONGO_URI);
await mongo.connect();
// These calls remain unchanged:
const id = await mongo.saveElement({ name: "test" }, "MyDB", "MyCollection");
const doc = await mongo.getElementById(id, "MyDB", "MyCollection");
const docs = await mongo.searchElement({ status: "active" }, "MyDB", "MyCollection");
await mongo.updateElement(id, { name: "updated" }, "MyDB", "MyCollection");
await mongo.deleteElement(id, "MyDB", "MyCollection");
// Only rename required:
- const client = mongo.getMongoClient();
+ const client = mongo.getClient();Install and test
npm install
npm run build
npm test