Database
Database Adapters
MoroJS uses a database adapter pattern instead of ORMs. Adapters provide a unified interface for different databases with built-in connection pooling and type safety.
Available Database Adapters
PostgreSQL
Advanced relational database with full SQL support
MySQL
Popular relational database with connection pooling
SQLite
Lightweight database perfect for development
Using Database Adapters
Basic Adapter Setuptypescript
1import { createApp, createDatabaseAdapter, z, validate } from '@morojs/moro';
2
3const app = await createApp({
4 cors: true,
5 compression: true
6});
7
8// Create database adapter
9const db = createDatabaseAdapter('sqlite', {
10 filename: 'app.db',
11 memory: false
12});
13
14// Initialize connection
15async function initializeDatabase() {
16 await db.connect();
17
18 // Create tables
19 await db.query(`
20 CREATE TABLE IF NOT EXISTS users (
21 id INTEGER PRIMARY KEY AUTOINCREMENT,
22 name TEXT NOT NULL,
23 email TEXT UNIQUE NOT NULL,
24 created_at DATETIME DEFAULT CURRENT_TIMESTAMP
25 )
26 `);
27}
28
29// User schema
30const UserSchema = z.object({
31 name: z.string().min(2).max(50),
32 email: z.string().email()
33});
34
35// Routes using adapter
36app.get('/users', async (req, res) => {
37 const users = await db.query('SELECT * FROM users');
38 return { success: true, data: users };
39});
40
41app.post('/users')
42 .body(UserSchema)
43 .handler(async (req, res) => {
44 const newUser = await db.insert('users', req.body);
45 res.status(201);
46 return { success: true, data: newUser };
47 });
48
49// Start application
50initializeDatabase().then(() => {
51 app.listen(3000);
52});Adapter Methods
Available Methodstypescript
1// Connection management
2await db.connect();
3await db.disconnect();
4
5// Query methods
6const users = await db.query('SELECT * FROM users');
7const user = await db.queryOne('SELECT * FROM users WHERE id = ?', [1]);
8
9// CRUD operations
10const newUser = await db.insert('users', {
11 name: 'John Doe',
12 email: 'john@example.com'
13});
14
15const updatedUser = await db.update('users',
16 { name: 'Jane Doe' },
17 { id: 1 }
18);
19
20const deletedCount = await db.delete('users', { id: 1 });
21
22// Transactions
23const result = await db.transaction(async (tx) => {
24 const user = await tx.insert('users', userData);
25 await tx.insert('profiles', { user_id: user.id, ...profileData });
26 return user;
27});
28
29// Batch operations
30const users = await db.batchInsert('users', [
31 { name: 'User 1', email: 'user1@example.com' },
32 { name: 'User 2', email: 'user2@example.com' }
33]);Multiple Database Adapters
Using Multiple Databasestypescript
1// Primary database
2const primaryDb = createDatabaseAdapter('postgresql', {
3 host: 'localhost',
4 user: 'postgres',
5 password: process.env.DB_PASSWORD,
6 database: 'myapp_primary',
7 connectionLimit: 20
8});
9
10// Analytics database
11const analyticsDb = createDatabaseAdapter('mysql', {
12 host: 'analytics.example.com',
13 user: 'analytics',
14 password: process.env.ANALYTICS_PASSWORD,
15 database: 'analytics',
16 connectionLimit: 10
17});
18
19// Cache database
20const cacheDb = createDatabaseAdapter('sqlite', {
21 filename: 'cache.db'
22});
23
24// Initialize all connections
25await Promise.all([
26 primaryDb.connect(),
27 analyticsDb.connect(),
28 cacheDb.connect()
29]);
30
31// Use different databases for different purposes
32app.get('/users/:id', async (req, res) => {
33 const { id } = req.params;
34
35 // Get user from primary database
36 const user = await primaryDb.queryOne(
37 'SELECT * FROM users WHERE id = $1', [id]
38 );
39
40 // Get analytics from analytics database
41 const analytics = await analyticsDb.query(
42 'SELECT * FROM user_stats WHERE user_id = ?', [id]
43 );
44
45 // Check cache
46 const cached = await cacheDb.queryOne(
47 'SELECT data FROM cache WHERE key = ?', [`user_${id}`]
48 );
49
50 return {
51 user,
52 analytics,
53 cached: cached ? JSON.parse(cached.data) : null
54 };
55});Adapter Comparison
| Feature | PostgreSQL | MySQL | SQLite |
|---|---|---|---|
| Performance | Excellent | Excellent | Good |
| Concurrency | Excellent | Good | Limited |
| Setup Complexity | Medium | Medium | Simple |
| Use Case | Production | Production | Development |
| Connection Pooling | Built-in | Built-in | N/A |