ApemanDB
ApemanDB is a database abstraction layer built as a thin wrapper around the popular Sequelize ORM, specifically optimized for use within the 'apeman' project ecosystem. It simplifies database interactions by abstracting direct Sequelize usage, particularly for defining models through a structured JSON schema. The library is currently at version 8.7.4 and, while no explicit release cadence is documented, its version history suggests active development. A key differentiator is its tight integration with `apemanenv` for environment-specific database configurations, allowing developers to manage database settings (like dialect, host, credentials) in a centralized, declarative manner. This approach aims to streamline database setup and model management for apeman web applications, reducing boilerplate associated with raw Sequelize initialization and model definition.
Common errors
-
Dialect needs to be explicitly defined. If you are using SQLite, install 'sqlite3' package.
cause Missing database driver package or incorrect 'DIALECT' in database.json.fixInstall the correct driver (e.g., `npm install sqlite3` or `npm install mysql2`) for your chosen database, and ensure the `DIALECT` property is correctly set in `env/database.json`. -
Error: connect ECONNREFUSED 127.0.0.1:3306
cause The database server is not running, or the host/port/credentials in `database.json` are incorrect, preventing a connection.fixVerify that your database server (e.g., MySQL, PostgreSQL) is running and accessible. Double-check `HOST`, `PORT`, `USERNAME`, and `PASSWORD` in your `env/database.json`. -
TypeError: Cannot read properties of undefined (reading 'User')
cause The `modelsDir` path provided to `apemandb.create` is incorrect, or the JSON model file (e.g., `user.json`) is malformed or missing.fixEnsure the `modelsDir` path is absolute and correctly points to your model definition directory. Verify that JSON model files are valid and present in that directory.
Warnings
- breaking ApemanDB is a wrapper around Sequelize. Major version updates in Sequelize (e.g., from v6 to v7) can introduce breaking changes that ApemanDB may not fully abstract or document, requiring users to consult Sequelize's migration guides for underlying changes.
- gotcha ApemanDB is tightly coupled with `apemanenv` for database configuration. Deviations from the expected `apemanenv` structure for `database.json` or its loading mechanism will result in connection failures or unexpected behavior.
- gotcha Database drivers (e.g., `mysql2`, `sqlite3`, `pg`) are peer dependencies of Sequelize and must be installed separately based on the chosen dialect in `database.json`. Failing to install the correct driver for your specified dialect will lead to runtime errors.
- gotcha Model definitions are exclusively handled via JSON files. This approach, while simplifying common use cases, can limit direct programmatic control over Sequelize's full feature set (e.g., custom instance methods, hooks) compared to defining models directly in JavaScript/TypeScript.
Install
-
npm install apemandb -
yarn add apemandb -
pnpm add apemandb
Imports
- create
import { create } from 'apemandb'; // apemandb primarily uses CommonJS 'require' pattern in examples.const db = require('apemandb').create(envConfig, { modelsDir: './db/models' }); - apemanenv
import apemanenv from 'apemanenv'; // Examples explicitly use CommonJS `require`.
const apemanenv = require('apemanenv'); - DB Instance (methods)
await db.User.create(); // Access models via `db.models` property, not directly on the instance.
await db.sync(); await db.models.User.create({ username: 'test' });
Quickstart
const path = require('path');
const apemanenv = require('apemanenv');
const apemandb = require('apemandb');
// 1. Define environment configuration (env/database.json)
// In a real project, this would be loaded by apemanenv automatically.
// For quickstart, we'll simulate the structure.
const envDir = path.join(__dirname, 'env');
require('fs').mkdirSync(envDir, { recursive: true });
require('fs').writeFileSync(path.join(envDir, 'database.json'), JSON.stringify({
"default": {
"DIALECT": "sqlite",
"SCHEMA": "apeman-demo-web",
"STORAGE": ":memory:"
},
"development": {
"SCHEMA": "apeman-demo-web_dev",
"STORAGE": "./tmp/dev-database.db"
},
"test": {
"DIALECT": "sqlite",
"SCHEMA": "apeman-demo-web_test",
"STORAGE": ":memory:"
}
}, null, 2));
// 2. Define a model (db/models/user.json)
const modelsDir = path.join(__dirname, 'db', 'models');
require('fs').mkdirSync(modelsDir, { recursive: true });
require('fs').writeFileSync(path.join(modelsDir, 'user.json'), JSON.stringify({
"$name": "User",
"$description": "A user model",
"$attributes": {
"username": {
"$type": "STRING",
"$unique": true
},
"introText": {
"$type": "STRING(1024)",
"$nullable": true
}
}
}, null, 2));
async function main() {
// Load environment variables
const envConfig = apemanenv(__dirname); // Simulates env loading from __dirname
// Initialize ApemanDB with configuration and models
const db = apemandb.create(envConfig, { modelsDir: modelsDir });
try {
// Connect to the database and synchronize models (create tables)
await db.sync({ force: true }); // `force: true` drops tables before recreating
console.log('Database and tables synchronized!');
// Create a new user record
const newUser = await db.models.User.create({ username: 'john_doe', introText: 'Hello world!' });
console.log('Created user:', newUser.toJSON());
// Find a user
const foundUser = await db.models.User.findOne({ where: { username: 'john_doe' } });
console.log('Found user:', foundUser.toJSON());
} catch (error) {
console.error('Database operation failed:', error.message);
} finally {
// Close the database connection if it's not an in-memory SQLite
if (db.sequelize.options.dialect !== 'sqlite' || db.sequelize.options.storage !== ':memory:') {
await db.sequelize.close();
console.log('Database connection closed.');
}
}
}
main();