ApemanDB

raw JSON →
8.7.4 verified Wed Apr 22 auth: no javascript

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.

error 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.
fix
Install 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 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.
fix
Verify that your database server (e.g., MySQL, PostgreSQL) is running and accessible. Double-check HOST, PORT, USERNAME, and PASSWORD in your env/database.json.
error 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.
fix
Ensure 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.
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.
fix Always check the release notes for both `apemandb` and the underlying `sequelize` package when upgrading major versions. Be prepared to adapt to Sequelize's API 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.
fix Ensure `env/database.json` and `env/index.js` follow the structure prescribed by `apemanenv` and `apemandb` documentation. Verify environment variable loading if applicable.
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.
fix Install the appropriate database driver package (e.g., `npm install mysql2`) corresponding to the `DIALECT` specified in your `database.json`.
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.
fix Understand the JSON schema limitations. For advanced Sequelize features not exposed via the JSON model definition, you might need to extend the database instance post-initialization or consider alternative solutions if full Sequelize flexibility is paramount.
npm install apemandb
yarn add apemandb
pnpm add apemandb

Demonstrates setting up `apemanenv` for database configuration, defining a model using `apemandb`'s JSON schema, and initializing the `apemandb` instance to synchronize schema and perform basic CRUD operations.

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