Query Basics — ODAC.JS Docs
Docs / ODAC.JS / Backend / Database / Query Basics

Query Basics

ODAC features a powerful, efficient, and "magic" Query Builder. It allows you to interact with your database using simple, chainable methods without writing raw SQL.

Accessing Tables

You can access any table directly as a property of Odac.DB.

// Access the 'users' table
const query = Odac.DB.users;

If you have multiple database connections defined in your config:

// Access 'visits' table on 'analytics' connection
const visits = Odac.DB.analytics.visits;

Retrieving Data (Select)

Fetch All Rows

const users = await Odac.DB.users.select();

Fetch a Single Row

Use .first() to get a single object instead of an array.

const user = await Odac.DB.users.where('id', 1).first();

Filtering (Where)

// Simple equals
const users = await Odac.DB.users.where('email', 'john@example.com').select();

// Comparison operators
const products = await Odac.DB.products.where('price', '>', 100).select();
const activeUsers = await Odac.DB.users.where('status', '!=', 'banned').select();

// OR statements
const staff = await Odac.DB.users
  .where('role', 'admin')
  .orWhere('role', 'editor')
  .select();

Ordering and Limiting

const latestPosts = await Odac.DB.posts
  .orderBy('created_at', 'desc')
  .limit(5);

Counting Rows

ODAC simplifies counting rows. Unlike standard Knex behavior which might return objects or strings, count() directly returns a Number for simple queries.

const totalUsers = await Odac.DB.users.count(); // Returns: 150 (Number)

const activeAdmins = await Odac.DB.users
    .where('role', 'admin')
    .where('active', true)
    .count(); // Returns: 5 (Number)

Inserting Data

// Insert a single record
await Odac.DB.users.insert({
  name: 'John Doe',
  email: 'john@example.com'
});

// Insert multiple records
await Odac.DB.tags.insert([
  { name: 'javascript' },
  { name: 'nodejs' }
]);

Updating Data

await Odac.DB.users
  .where('id', 1)
  .update({
    status: 'active',
    last_login: new Date()
  });

Deleting Data

await Odac.DB.users.where('id', 1).delete();


---

## ID Generation (NanoID)

ODAC includes a built-in helper for generating robust, unique string IDs (NanoID) without needing external packages. Secure, URL-friendly, and collision-resistant.

### Automatic Generation (Recommended)

When you define a column as `type: 'nanoid'` in your schema file, ODAC **automatically generates** the ID on every `insert()` — no manual code needed.

**Schema definition:**
```javascript
// schema/posts.js
module.exports = {
  columns: {
    id: { type: 'nanoid', primary: true },
    title: { type: 'string', length: 255 }
  }
}

Usage — just insert, the ID is auto-generated:

await Odac.DB.posts.insert({ title: 'My First Post' });
// → { id: 'V1StGXR8Z5jdHi6BmyTa', title: 'My First Post' }

This works for single inserts and bulk inserts. If you provide an id explicitly, the auto-generation is skipped.

// Bulk insert — each row gets its own unique nanoid
await Odac.DB.posts.insert([
    { title: 'Post A' },
    { title: 'Post B' }
]);

// Explicit ID — auto-generation is skipped
await Odac.DB.posts.insert({ id: 'my-custom-id', title: 'Custom' });

You can also customize the ID length:

// schema/codes.js
module.exports = {
  columns: {
    code: { type: 'nanoid', length: 8, primary: true },
    label: { type: 'string' }
  }
}

Manual Generation

You can also generate NanoIDs manually when needed:

// Generate a standard 21-character ID
const id = Odac.DB.nanoid();

// Generate a custom length ID
const shortId = Odac.DB.nanoid(10);