A Node.js module for Oracle Database access from JavaScript and TypeScript
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Simple Oracle Document Access (SODA) for JSON document storage and querying capabilities.
Get SODA database interface for document operations.
/**
* Gets SODA database interface
* @returns SodaDatabase instance
*/
getSodaDatabase(): SodaDatabase;
interface SodaDatabase {
createCollection(name: string, options?: SodaCollectionOptions): Promise<SodaCollection>;
createDocument(content: any, options?: SodaDocumentOptions): SodaDocument;
getCollectionNames(options?: GetCollectionNamesOptions): Promise<string[]>;
openCollection(name: string): Promise<SodaCollection>;
}
interface SodaCollectionOptions {
metaData?: any;
mode?: number;
}
interface SodaDocumentOptions {
key?: string;
mediaType?: string;
}
interface GetCollectionNamesOptions {
startsWith?: string;
limit?: number;
}Usage Examples:
const oracledb = require('oracledb');
// Get SODA database
const soda = connection.getSodaDatabase();
// Create a collection
const collection = await soda.createCollection('products');
// List collections
const collectionNames = await soda.getCollectionNames();
console.log('Collections:', collectionNames);
// Open existing collection
const existingCollection = await soda.openCollection('products');Manage JSON document collections with full CRUD operations.
interface SodaCollection {
// Document operations
insertOne(document: SodaDocument | any): Promise<SodaWriteResult>;
insertOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
insertMany(documents: (SodaDocument | any)[]): Promise<SodaWriteResult>;
insertManyAndGet(documents: (SodaDocument | any)[]): Promise<SodaDocument[]>;
save(document: SodaDocument): Promise<SodaWriteResult>;
saveAndGet(document: SodaDocument): Promise<SodaDocument>;
// Query operations
find(): SodaOperation;
count(): Promise<number>;
// Collection management
drop(): Promise<boolean>;
truncate(): Promise<void>;
// Index management
createIndex(spec: any): Promise<void>;
dropIndex(name: string, options?: DropIndexOptions): Promise<boolean>;
listIndexes(): Promise<any[]>;
// Schema operations
getDataGuide(): Promise<SodaDocument>;
// Collection properties
metaData: any;
name: string;
}
interface SodaWriteResult {
inserted?: boolean;
replaced?: boolean;
}
interface DropIndexOptions {
force?: boolean;
}Usage Examples:
// Create and work with a collection
const collection = await soda.createCollection('employees');
// Insert a single document
const doc = {
name: 'John Doe',
department: 'Engineering',
salary: 75000,
skills: ['JavaScript', 'Oracle', 'Node.js']
};
const result = await collection.insertOne(doc);
console.log('Document inserted:', result.inserted);
// Insert and get the document back
const insertedDoc = await collection.insertOneAndGet(doc);
console.log('Document key:', insertedDoc.key);
console.log('Document content:', insertedDoc.getContent());
// Insert multiple documents
const employees = [
{ name: 'Alice Smith', department: 'Marketing', salary: 65000 },
{ name: 'Bob Johnson', department: 'Sales', salary: 70000 },
{ name: 'Carol Brown', department: 'Engineering', salary: 80000 }
];
const bulkResult = await collection.insertMany(employees);
console.log('Documents inserted:', bulkResult.inserted);
// Count documents
const count = await collection.count();
console.log('Total documents:', count);
// Get collection info
console.log('Collection name:', collection.name);
console.log('Collection metadata:', collection.metaData);Work with individual JSON documents.
interface SodaDocument {
// Document content
getContent(): any;
getContentAsBuffer(): Buffer;
getContentAsString(): string;
// Document metadata
key: string;
lastModified: string;
mediaType: string;
version: string;
// Document creation
createdOn: string;
}
class SodaDocument {
constructor();
getContent(): any;
getContentAsBuffer(): Buffer;
getContentAsString(): string;
key: string;
lastModified: string;
mediaType: string;
version: string;
createdOn: string;
}Usage Examples:
// Create document with specific key
const doc = soda.createDocument({
productId: 'PROD001',
name: 'Laptop',
price: 999.99
}, { key: 'PROD001' });
await collection.insertOne(doc);
// Retrieve and examine document
const operation = collection.find().key('PROD001');
const foundDoc = await operation.getOne();
if (foundDoc) {
console.log('Document key:', foundDoc.key);
console.log('Last modified:', foundDoc.lastModified);
console.log('Content:', foundDoc.getContent());
console.log('Content as string:', foundDoc.getContentAsString());
}Advanced querying capabilities with fluent API.
interface SodaOperation {
// Filtering
key(value: string): SodaOperation;
keys(values: string[]): SodaOperation;
filter(spec: any): SodaOperation;
// Pagination and ordering
skip(value: number): SodaOperation;
limit(value: number): SodaOperation;
// Execution
count(): Promise<number>;
getCursor(): Promise<SodaDocCursor>;
getDocuments(): Promise<SodaDocument[]>;
getOne(): Promise<SodaDocument>;
// Modification
remove(): Promise<SodaWriteResult>;
replaceOne(document: SodaDocument | any): Promise<SodaWriteResult>;
replaceOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
}
interface SodaDocCursor {
close(): Promise<void>;
getNext(): Promise<SodaDocument>;
}Usage Examples:
// Find documents by key
const doc = await collection.find().key('PROD001').getOne();
// Find multiple documents by keys
const docs = await collection.find().keys(['PROD001', 'PROD002']).getDocuments();
// Filter documents with JSON queries
const highSalaryEmployees = await collection
.find()
.filter({ salary: { $gt: 70000 } })
.getDocuments();
// Complex filtering
const engineeringDocs = await collection
.find()
.filter({
department: 'Engineering',
skills: { $in: ['JavaScript', 'Python'] }
})
.limit(10)
.getDocuments();
// Using cursor for large result sets
const cursor = await collection.find().getCursor();
let doc;
while ((doc = await cursor.getNext())) {
console.log('Processing document:', doc.key);
// Process document
}
await cursor.close();
// Count with filter
const count = await collection
.find()
.filter({ department: 'Engineering' })
.count();
console.log('Engineering employees:', count);Update and replace documents in collections.
// Replace operations
replaceOne(document: SodaDocument | any): Promise<SodaWriteResult>;
replaceOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
// Remove operations
remove(): Promise<SodaWriteResult>;
// Save operations (upsert)
save(document: SodaDocument): Promise<SodaWriteResult>;
saveAndGet(document: SodaDocument): Promise<SodaDocument>;Usage Examples:
// Replace a document
const updatedEmployee = {
name: 'John Doe',
department: 'Engineering',
salary: 85000, // Increased salary
skills: ['JavaScript', 'Oracle', 'Node.js', 'React']
};
const replaceResult = await collection
.find()
.key('EMP001')
.replaceOne(updatedEmployee);
console.log('Document replaced:', replaceResult.replaced);
// Replace and get back the new document
const newDoc = await collection
.find()
.key('EMP001')
.replaceOneAndGet(updatedEmployee);
console.log('New version:', newDoc.version);
// Remove documents
const removeResult = await collection
.find()
.filter({ department: 'Discontinued' })
.remove();
console.log('Documents removed:', removeResult);
// Save (upsert) with specific key
const productDoc = soda.createDocument({
productId: 'PROD999',
name: 'New Product',
price: 199.99
}, { key: 'PROD999' });
const saveResult = await collection.save(productDoc);
console.log('Document saved:', saveResult.inserted || saveResult.replaced);Create and manage indexes for optimal query performance.
/**
* Creates an index on the collection
* @param spec - Index specification
* @returns Promise that resolves when index is created
*/
createIndex(spec: any): Promise<void>;
/**
* Drops an index from the collection
* @param name - Index name
* @param options - Optional drop options
* @returns Promise resolving to boolean indicating success
*/
dropIndex(name: string, options?: DropIndexOptions): Promise<boolean>;
/**
* Lists all indexes on the collection
* @returns Promise resolving to array of index specifications
*/
listIndexes(): Promise<any[]>;Usage Examples:
// Create a simple index
await collection.createIndex({
name: 'salaryIndex',
fields: [
{
path: 'salary',
datatype: 'number'
}
]
});
// Create a composite index
await collection.createIndex({
name: 'deptSalaryIndex',
fields: [
{
path: 'department',
datatype: 'string'
},
{
path: 'salary',
datatype: 'number'
}
]
});
// Create a functional index
await collection.createIndex({
name: 'upperNameIndex',
fields: [
{
path: 'name',
datatype: 'string',
order: 'asc'
}
]
});
// List all indexes
const indexes = await collection.listIndexes();
console.log('Collection indexes:', indexes);
// Drop an index
const dropped = await collection.dropIndex('salaryIndex');
console.log('Index dropped:', dropped);Advanced collection operations and configuration.
/**
* Gets data guide for the collection
* @returns Promise resolving to SodaDocument containing schema information
*/
getDataGuide(): Promise<SodaDocument>;
/**
* Truncates the collection (removes all documents)
* @returns Promise that resolves when truncation is complete
*/
truncate(): Promise<void>;
/**
* Drops the collection
* @returns Promise resolving to boolean indicating success
*/
drop(): Promise<boolean>;Usage Examples:
// Get data guide (schema information)
const dataGuide = await collection.getDataGuide();
console.log('Collection schema:', dataGuide.getContent());
// Truncate collection (remove all documents)
await collection.truncate();
console.log('Collection truncated');
// Verify truncation
const count = await collection.count();
console.log('Document count after truncate:', count); // Should be 0
// Drop collection entirely
const dropped = await collection.drop();
console.log('Collection dropped:', dropped);
// Verify collection no longer exists
const collections = await soda.getCollectionNames();
console.log('Remaining collections:', collections);// Collection creation modes
const SODA_COLL_MAP_MODE = 1;Usage Examples:
// Create collection with specific mapping mode
const collection = await soda.createCollection('mappedCollection', {
mode: oracledb.SODA_COLL_MAP_MODE,
metaData: {
keyColumn: { name: 'ID' },
contentColumn: { name: 'JSON_DOCUMENT', jsonFormat: 'OSON' },
versionColumn: { name: 'VERSION' },
lastModifiedColumn: { name: 'LAST_MODIFIED' }
}
});Install with Tessl CLI
npx tessl i tessl/npm-oracledb