# Getting Started

<figure><img src="https://2684121194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCE40T5ADNteu7XvszmlE%2Fuploads%2FLk1czD3d4h4Ay4a3FLyt%2FPicsart_25-02-07_02-39-46-166.png?alt=media&#x26;token=8a10d808-bb1a-481f-ae13-b0fa65785f22" alt=""><figcaption></figcaption></figure>

***NexORM*** is a powerful ORM designed to simplify database management while delivering high performance and flexibility. Inspired by [**MongoDB**](https://www.mongodb.com/docs/), [**Prisma**](https://www.prisma.io/docs), and [**TypeORM**](https://typeorm.io/), it combines the best features of these tools, offering advanced operators (like $set and $inc with more), a built-in caching system, and a <mark style="color:purple;">**decorator-based**</mark> schema definition for clean and intuitive modeling.

With full <mark style="color:blue;">**TypeScript**</mark> support, ***Nexorm*** ensures  <mark style="background-color:yellow;">**type-safe**</mark> , modern development using ~~<mark style="color:yellow;">**JavaScript (ES2021)**</mark>~~. It supports **MySQL**, **PostgreSQL**, **SQLite**, **MariaDB**, and **MSSQL**, making it suitable for projects of any scale, from small apps to complex enterprise systems.

Start building with ***NexORM*** to enjoy effortless, scalable, and maintainable database interactions.

## Features

* **Full Type Support:** *Seamless TypeScript integration for type-safe development.*
* **Decorator-Based Schema Definition:** *Clean and intuitive schema modeling using decorators.*
* **Multi-Database Support:** *Compatible with MySQL, PostgreSQL, SQLite, MariaDB, and MSSQL.*
* **Full JSON Support:** *Easily handle arrays and objects in JSON format.*
* **Hooks Support:** *Lifecycle hooks for enhanced control over database events.*
* **Encryption, Decryption, and Hashing:** *Built-in utilities for secure data management.*
* **Validation Support:** *Ensure data integrity with powerful validation tools.*
* **Multi-Connection Support:** *Manage multiple database connections effortlessly.*
* **CLI Support:** *Command-line tools for streamlined database operations.*
* **Cache Support:** *Built-in caching for faster queries and improved performance.*
* **Index Support:** *Optimize queries with advanced indexing capabilities.*
* **Advanced Operator Support:** *Extendable operators for flexible database operations.*
* **Debug and Logging Support:** *Track and troubleshoot with detailed logs and debug tools.*

And more...

***With NexORM your schemas & models look like this:***

```typescript
/* ./schemas/user.ts */
import Model from 'nexorm/model';
import { 
  Schema, Timestamps, 
  Column, Default, Required 
} from 'nexorm/decorators';

@Schema
@Timestamps /* UpdatedAt And CreatedAt Sections */
class UserSchema {

@Column
@Required
static personName = String; /* Required String Column */

@Column
@Required
static personSurname = String; /* Required String Column */

@Column
@Default(16)
static personAge = Number; /* Number Column If Value Is Not Available */
                            /* Value Is Set To '16' */

@Column
@Default(['Personal'])
static tags = Array(String); /* String[] Column If Value Is Not Available */
                                 /* Value Is Set To '["Personal"]' */

@Column
static audit = Object; /* Object Column */

};

/* Integrating The Schema Into The Model And Exporting */
export default new Model(UserSchema);

```

***And your domain logic will look this way:***

```typescript
import User from './schemas/user';

const allUsers = await User.$everything();
const firstUser = await User.$searchFirst();

const filteredUsers = await User.$search({
   $where: {
         personName: 'John',
         personAge: {
             $gte: 18
         }
   }
});

const findUser = await User.$searchOne({
    $where: {
        tags: {
            $in: [['Personal']]
        }
    },
    $options: {
        $sort: {
            personAge: -1
        }
    }
});

```

## Installation <a href="#installation" id="installation"></a>

1. **Install the npm package:**\ <mark style="color:blue;">**`npm install nexorm --save`**</mark> <br>
2. **You may need to install `reflect-metadata`:**\ <mark style="color:blue;">**`npm install reflect-metadata --save`**</mark> \
   **and import it somewhere in the global place of your app (for example in `src/index.ts`):**\ <mark style="color:blue;">**`import 'reflect-metadata';`**</mark><br>
3. **You may need to install node typings:**\ <mark style="color:blue;">**`npm install @types/node --save-dev`**</mark> <br>
4. **Install a database driver:**
   * for **MySQL**\ <mark style="color:green;">**`npm install mysql2 --save`**</mark>&#x20;
   * for **PostgreSQL**\ <mark style="color:green;">**`npm install pg --save`**</mark>&#x20;
   * for **SQLite**\ <mark style="color:green;">**`npm install sqlite3 --save`**</mark>&#x20;
   * for **Microsoft SQL Server**\ <mark style="color:green;">**`npm install tedious --save`**</mark>&#x20;
   * for **MariaDB**\ <mark style="color:green;">**`npm install mariadb --save`**</mark>&#x20;

### TypeScript Configuration

Also, make sure you are using TypeScript version **4.5** or higher, and you have enabled the following settings in **`tsconfig.json`**:

```json
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
```

You may also need to enable **`es6`** in the **`lib`** section of compiler options, or install **`es6-shim`** from **`@types`**.

## Quick Start

The quickest way to get started with NexORM is to use its CLI commands to generate a <mark style="color:blue;">**`nexorm.config.ts`**</mark> or ~~<mark style="color:yellow;">**`nexorm.config.js`**</mark>~~ file.

```typescript
nexorm init /* With Selection Prompts */
nexorm init -y /* Skip All Prompts */
nexorm init --database sqlite --language ts --babel false /* For Manuel */
```

After edit the <mark style="color:blue;">**`nexorm.config.ts`**</mark> or ~~<mark style="color:yellow;">**`nexorm.config.js`**</mark>~~ file and put your own database connection configuration options in there:

```typescript
/* nexorm.config.ts */

/* eslint-disable @typescript-eslint/no-var-requires */
/** @type {import('nexorm').NexormConfig} */
import type { NexormConfig } from "nexorm";

export default [{
    $provider: "nexorm",
    $database: "sqlite",
    $databaseEngine: "InnoDB",
    $filePath: "./nexorm.sqlite",
    $autoConnect: true,
    $onConnection: () => {
        console.log("[Nexorm] Database ready!");
    },
    $onError: (error: Error) => {
        console.error("[Nexorm] Error connecting to database:", error);
    },
}] satisfies NexormConfig;
```

### Configuration File Options

You can adjust the configuration file according to your needs using the table below.

<table><thead><tr><th width="205" align="center" valign="top">Value</th><th width="375" align="center">Type</th><th>Default</th></tr></thead><tbody><tr><td align="center" valign="top"><strong><code>$provider</code></strong><mark style="color:red;"><strong><code>*</code></strong></mark></td><td align="center"><mark style="color:blue;"><strong>'nexorm'</strong></mark><strong> </strong><mark style="color:green;"><strong>|</strong></mark> <mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:yellow;"><strong><code>nexorm</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$database</code></strong><mark style="color:red;"><strong><code>*</code></strong></mark></td><td align="center"><mark style="color:blue;"><strong>'mysql'</strong></mark><strong> </strong><mark style="color:green;"><strong>|</strong></mark><strong> </strong><mark style="color:blue;"><strong>'postgres'</strong></mark><strong> </strong><mark style="color:green;"><strong>|</strong></mark><strong> </strong><mark style="color:blue;"><strong>'sqlite'</strong></mark><strong> </strong><mark style="color:green;"><strong>|</strong></mark><strong> </strong><mark style="color:blue;"><strong>'mariadb'</strong></mark><strong> </strong><mark style="color:green;"><strong>|</strong></mark><strong> </strong><mark style="color:blue;"><strong>'mssql'</strong></mark> </td><td><mark style="color:yellow;"><strong><code>sqlite</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$dialectModule</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:yellow;"><strong>any</strong></mark></td><td><strong><code>(Empty)</code></strong></td></tr><tr><td align="center" valign="top"><strong><code>$autoConnect</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:green;"><strong>Boolean</strong></mark></td><td><mark style="color:yellow;"><strong><code>true</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$filePath</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:yellow;"><strong><code>./nexorm.sqlite</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$databaseEngine</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:yellow;"><strong><code>B-tree</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$ssl</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:green;"><strong>Boolean</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:purple;"><strong>Object</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool.</code></strong><mark style="color:yellow;"><strong><code>$acquire</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool.</code></strong><mark style="color:yellow;"><strong><code>$idle</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool.</code></strong><mark style="color:yellow;"><strong><code>$max</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool.</code></strong><mark style="color:yellow;"><strong><code>$min</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$pool.</code></strong><mark style="color:yellow;"><strong><code>$evict</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><mark style="color:purple;"><strong><code>$onConnection</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="background-color:purple;"><strong>Function</strong></mark></td><td><mark style="color:purple;"><strong><code>(() ⇒ {..});</code></strong></mark></td></tr><tr><td align="center" valign="top"><mark style="color:purple;"><strong><code>$onDisconnect</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="background-color:purple;"><strong>Function</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><mark style="color:purple;"><strong><code>$onError</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="background-color:purple;"><strong>Function</strong></mark></td><td><mark style="color:purple;"><strong><code>(() ⇒ {..});</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$host</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$port</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$username</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$password</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$connectionURI</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:orange;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$cache</code></strong><mark style="color:red;"><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:purple;"><strong>Object</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$cache.</code></strong><mark style="color:yellow;"><strong><code>$type</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:blue;"><strong>'memory'</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr><tr><td align="center" valign="top"><strong><code>$cache.</code></strong><mark style="color:yellow;"><strong><code>$duration</code></strong><strong><code>?</code></strong></mark></td><td align="center"><mark style="color:red;"><strong>Number</strong></mark></td><td><mark style="color:red;"><strong><code>(Empty)</code></strong></mark></td></tr></tbody></table>

## Create Model

Working with a database starts with creating tables. How do you tell **NexORM** to create a database table? The answer is - through the models. Your models in your app are your database tables.

For example, you have a **`Member`** model:

```typescript
@Schema
class Member {

@Column
@UUID()
static userId = String;

@Column
static username = String;

@Column
static displayName = String;

@Column
static age = Number;

@Column
static avatar = Buffer;

@Column
static banner = String;

@Column
static createdAt = Date;

@Column
static lastJoinedAt = Date;

@Column
@Hash('SHA256','hex')
static password = String;

@Column
@Default(false)
static isPremium = Boolean;

@Column
static badges = Array(String);

@Column
static logins = { timestamp: Number, ip: String };

};

export default new Model(Member);
```

And you want to store photos in your database. To store things in the database, first, you need a database table, and database tables are created from your models. Not all models, but only those you define as *entities*.

## Updating in the database <a href="#updating-in-the-database" id="updating-in-the-database"></a>

Now let's update a member from the database:

```typescript
import Member from './schemas/Member';
import * as fs from 'fs';



/* Update Or Create Row */
var upsertedMember = await Member.$upsert({
    $where: {
        isPremium: true
    },
    $update: {
        $toggle: {
            isPremium: true
        },
        $camelcase: {
            username: true
        }
    },
    $rules: {
        username: {
            $alphaNumeric: true
        }
    }
});


/* Update One Row */
await Member.$update({
    $where: {
        userId: '1234567890',
        username: 'fivesobes'
    },
    $update: {
        $set: {
            avatar: fs.readFileSync(path.join(__dirname, 'avatar.png')),
            lastJoinedAt: new Date()
        },
        $toggle: {
            isPremium: true
        },
    },
    $options: { $upsert: true }
});


/* Update Many Rows */
await Member.$updateMany({
    $where: {
        isPremium: true,
        badges: {
            $in: [['Verify', 'VIP']]
        }
    },
    $update: {
        $set: {
            badges: []
        },
        $toggle: {
            isPremium: true
        }
    },
});
```

## Searching in the database

Now let's search a member from the database:

<pre class="language-typescript"><code class="lang-typescript"><strong>import Member from './schemas/Member';
</strong>

/* Search All */
var allMembers = await Member.$everything();


/* Search One */
var member = await Member.$searchOne({
    $where: {
        userId: '1234567890',
    },
    $options: {
        $attributes: ['userId','username','displayName','avatar','banner'],
        $raw: true
    }
});


/* Search Many */
var memberList = await Member.$search({
    $where: {
        isPremium: true
    },
    $options: {
        $sort: {
            lastJoinedAt: -1,
            createdAt: -1
        },
        $limit: 30,
        $cache: true
    }
});


/* Search By Id */
var searchMemberById = await Member.$searchById('7ca9320b-1803-459c-a1ff-39b8d5e14a25');


/* Search By Ids */
var searchMembersByIds = await Member.$searchByIds([
    '7ca9320b-1803-459c-a1ff-39b8d5e14a25',
    '7ca9320b-1803-459c-a1ff-39b8d5e14a26',
    '7ca9320b-1803-459c-a1ff-39b8d5e14a27'
]);


/* Distinct Rows */
var memberListDistinct = await Member.$distinct({
    $field: ['userId','username','displayName'],
    $options: {
        $cache: { $key: 'memberList', $ttl: 60_000 }
    }
});


/* Get Count */
var count = await Member.$count({
    $where: {
        lastJoinedAt: {
            $gte: new Date('2021-01-01')
        }
    },
    $options: {
        $paranoid: true
    }
});


/* Search And Get Count */
var [ members, count ] = await Member.$searchAndCount({
    $where: {
        createdAt: {
            $lte: new Date('2021-01-01'),
            $gte: new Date('2020-01-01')
        }
    }
});

</code></pre>

## Deleting in the database

Now let's delete a member from the database:

```typescript
import Member from './schemas/Member';


/* Delete All */
await Member.$truncate();


/* Delete One */
var deletedMember = await Member.$delete({
    $where: {
        userId: '1234567890',
        isPremium: {
            $eq: false
        }
    }
});


/* Delete Many */
var deletedMembers = await Member.$deleteMany({
    $where: {
        isPremium: false,
        banner: {
            $startsWith: '.png'
        }
    },
    $options: {
       $limit: 40,
       $logging(sql, benchmark) {
            console.log(`${sql} took ${benchmark}ms`);
       },
       $force: true
    }
});


/* Soft Delete One */
await Member.$softDelete({
    $where: {
        username: 'fivesobes'
    }
});


/* Soft Delete Many */
await Member.$softDeleteMany({
    $where: {
        isPremium: false
    },
    $options: {
        $limit: 5
    }
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fivesobes.gitbook.io/nexorm/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
