CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-oracledb

A Node.js module for Oracle Database access from JavaScript and TypeScript

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

soda-operations.mddocs/

SODA Operations

Simple Oracle Document Access (SODA) for JSON document storage and querying capabilities.

Capabilities

SODA Database

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');

SODA Collections

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);

SODA Documents

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());
}

SODA Queries

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);

Document Modification

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);

Index Management

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);

Collection Management

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);

SODA Constants

// 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

docs

advanced-queuing.md

configuration-settings.md

connection-management.md

connection-pools.md

data-types-lobs.md

index.md

soda-operations.md

sql-execution.md

transaction-management.md

tile.json