A comprehensive Node.js database access framework providing robust abstractions for database connection management, SQL execution, transaction handling, pagination, and dynamic query building.
npm install @ticatec/node-common-libraryδΈζζζ‘£ | English
A comprehensive Node.js database access framework providing robust abstractions for database connection management, SQL execution, transaction handling, pagination, and dynamic query building.


- Multi-database Support: Easily adaptable to different database types via DBConnection implementations
- Transaction Management: Supports beginTransaction(), commit(), and rollback() for reliable operations
- Paginated Queries: Built-in support for pagination with PaginationList
- Dynamic Query Building: Flexible query construction with CommonSearchCriteria
- SQL File Execution: Execute SQL scripts with comment handling and error logging
- Field Transformation: Automatic underscore-to-camelCase conversion and nested object support
- Dependency Injection: Bean factory for managing singleton/prototype instances
- Optimistic Locking: Built-in support for concurrent update conflict handling
``bash`
npm install @ticatec/node-common-library
`typescript
import { DBManager, BeanFactory, CommonService, CommonDAO } from '@ticatec/node-common-library';
import { Scope } from '@ticatec/node-common-library';
// Initialize database manager with your database factory
const dbManager = DBManager.init(yourDBFactory);
// Register DAOs and Services
const beanFactory = BeanFactory.getInstance();
beanFactory.register('UserDAO', UserDAO, Scope.Singleton);
beanFactory.register('UserService', UserService, Scope.Singleton);
`
`typescript
import { CommonDAO } from '@ticatec/node-common-library';
import DBConnection from '@ticatec/node-common-library/lib/db/DBConnection';
class UserDAO extends CommonDAO {
async createUser(conn: DBConnection, user: User): Promise
const sql = 'INSERT INTO users (name, email) VALUES ($1, $2)';
return await conn.insertRecord(sql, [user.name, user.email]);
}
async findUserById(conn: DBConnection, id: number): Promise
const sql = 'SELECT * FROM users WHERE id = $1';
return await conn.find(sql, [id]);
}
async updateUser(conn: DBConnection, user: User): Promise
const sql = 'UPDATE users SET name = $1, email = $2 WHERE id = $3';
return await conn.updateRecord(sql, [user.name, user.email, user.id]);
}
}
`
`typescript
import { CommonService } from '@ticatec/node-common-library';
import DBConnection from '@ticatec/node-common-library/lib/db/DBConnection';
class UserService extends CommonService {
async createUser(userData: User): Promise
return this.executeInTx(async (conn: DBConnection) => {
const userDAO = this.getDAOInstance('UserDAO');
return await userDAO.createUser(conn, userData);
});
}
async getUser(id: number): Promise
return this.executeNonTx(async (conn: DBConnection) => {
const userDAO = this.getDAOInstance('UserDAO');
return await userDAO.findUserById(conn, id);
});
}
}
`
`typescript
import { CommonSearchCriteria } from '@ticatec/node-common-library';
import DBConnection from '@ticatec/node-common-library/lib/db/DBConnection';
class UserSearchCriteria extends CommonSearchCriteria {
constructor(criteria?: any) {
super(criteria);
this.sql = 'SELECT id, name, email, created_at FROM users WHERE 1=1';
this.orderBy = 'ORDER BY created_at DESC';
}
protected buildDynamicQuery(): void {
if (this.criteria?.name) {
this.buildStarCriteria(this.criteria.name, 'name');
}
if (this.criteria?.email) {
this.buildCriteria(this.criteria.email, 'email');
}
if (this.criteria?.dateFrom || this.criteria?.dateTo) {
this.buildRangeCriteria(this.criteria.dateFrom, this.criteria.dateTo, 'created_at');
}
}
}
// Usage
const criteria = new UserSearchCriteria({
name: 'John*', // Will use LIKE query
email: 'john@example.com', // Will use exact match
page: 1,
rows: 20
});
const result = await criteria.paginationQuery(conn);
console.log(Total: ${result.count}, Pages: ${result.pages});`
console.log('Users:', result.list);
- genID(): Generates a 32-bit UUIDexecuteCountSQL()
- : Executes count queriesquickSearch()
- : Performs paginated queries with default row limitsconvertBooleanFields()
- : Converts T/F strings to boolean values
- executeInTx(): Runs functions within transactions with automatic commit/rollbackexecuteNonTx()
- : Runs functions without transactionsgetDAOInstance()
- : Retrieves DAO instances via BeanFactory
- Transaction control: beginTransaction(), commit(), rollback()executeUpdate()
- SQL execution: , insertRecord(), updateRecord(), deleteRecord()find()
- Query methods: , listQuery(), executePaginationSQL()executeSQLFile()
- SQL file processing: resultToList()
- Result transformation: with camelCase conversion
- buildDynamicQuery(): Override to define custom search logicbuildCriteria()
- : Builds equality conditionsbuildStarCriteria()
- : Builds LIKE conditions with wildcard supportbuildRangeCriteria()
- : Builds range conditions (from/to)paginationQuery()
- : Executes paginated queriesquery()
- : Executes non-paginated queries
`typescript
import { BeanFactory, Scope } from '@ticatec/node-common-library';
const factory = BeanFactory.getInstance();
factory.register('UserDAO', UserDAO, Scope.Singleton);
factory.register('TempDAO', TempDAO, Scope.Prototype);
const userDAO = factory.getInstance('UserDAO'); // Same instance
const tempDAO = factory.createBean('TempDAO'); // New instance each time
`
typescript
import { BatchRecord, BatchRecords } from '@ticatec/node-common-library';const batchRecords: BatchRecords = [
{ recNo: 1, data: { name: 'User1', email: 'user1@test.com' }, error: null },
{ recNo: 2, data: { name: 'User2', email: 'user2@test.com' }, error: null }
];
// Process batch records
for (const record of batchRecords) {
try {
await userDAO.createUser(conn, record.data);
} catch (error) {
record.error = error;
}
}
`$3
`typescript
import BitsBoolean from '@ticatec/node-common-library/lib/BitsBoolean';class UserPermissions extends BitsBoolean {
constructor(value: number = 0) {
super(value);
}
setCanRead(value: boolean): void {
this.setBitValue(0, value);
}
getCanRead(): boolean {
return this.getBitValue(0);
}
setCanWrite(value: boolean): void {
this.setBitValue(1, value);
}
getCanWrite(): boolean {
return this.getBitValue(1);
}
}
`$3
`typescript
import { StringUtils } from '@ticatec/node-common-library';const id = StringUtils.genID(); // 32-character UUID without dashes
const uuid = StringUtils.uuid(); // Standard UUID with dashes
const isNum = StringUtils.isNumber('123'); // true
const parsed = StringUtils.parseNumber('abc', 0); // 0 (default value)
`π API Reference
$3
- BaseDAO : Basic CRUD operations interface
- BaseCRUDDAO : Extended CRUD with delete functionality
- DBFactory: Database connection factory interface
- Field: Database field metadata interface
- PaginationList: Paginated query result interface
$3
- PostConstructionFun: Post-processing function type
- BeanLoader: Bean loading function type
- BatchRecord : Batch processing record interface
- BatchRecords : Array of batch processing records
$3
- Scope: Bean scope enumeration (Singleton, Prototype)
- FieldType: Database field type enumeration (Text, Number, Date)
π Error Handling
The library provides specialized exceptions:
`typescript
import { OptimisticLockException } from '@ticatec/node-common-library';try {
await userDAO.updateUser(conn, user);
} catch (error) {
if (error instanceof OptimisticLockException) {
console.log('Concurrent update conflict:', error.entity);
// Handle optimistic lock conflict
}
}
`π Dependencies
- uuid: For UUID generation
- log4js: For logging (peer dependency)
π€ Contributing
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/AmazingFeature)
3. Commit your changes (git commit -m 'Add some AmazingFeature')
4. Push to the branch (git push origin feature/AmazingFeature)
5. Open a Pull Requestπ License
This project is licensed under the MIT License - see the LICENSE file for details.
π¨βπ» Author
Henry Feng - huili.f@gmail.com
π Links
- GitHub Repository
- NPM Package
- Issues
---
Note: This library is designed to create a consistent data access layer across various database drivers. Ensure proper configuration of
log4js for logging and implement your specific DBConnection` class for your chosen database system.