# Database

FhyTS provides an interface-based database abstraction through the IDatabase contract, allowing you to flexibly implement database connections to MySQL, PostgreSQL, SQLite, MongoDB, or others.

## Contract API: IDatabase

Every database driver or adapter must implement the following interface:

| Method | Description |
| ----------------------------- | ------------------------------------------------------------------------ |
| `connect(): Promise<void>` | Initializes a connection to the database. |
| `disconnect(): Promise<void>` | Safely closes the database connection. |
| `query<T>(sql, params?)` | Executes a SQL command or data operation. Returns a `Promise<T>`. |

## Abstract Class: Database

The framework provides an abstract class Database that implements **IDatabase** as a basis for concrete adapters. You can simply create an instance of this class to integrate your preferred database.

## Implementation Example: MySQL

Here's an example of implementing a MySQL driver using the mysql2/promise library:

```javascript
import mysql from 'mysql2/promise';
import { Database } from 'fhyts';

export class MySQLDatabase extends Database {
  private pool!: mysql.Pool;

  async connect(): Promise<void> {
    this.pool = mysql.createPool({
      host: 'localhost',
      user: 'root',
      password: 'yourpassword',
      database: 'yourdb',
      waitForConnections: true,
      connectionLimit: 10,
    });
  }

  async disconnect(): Promise<void> {
    await this.pool.end();
  }

  async query<T = any>(sql: string, params?: any[]): Promise<T> {
    const [rows] = await this.pool.execute(sql, params);
    return rows as T;
  }
}
```

## Usage in Services

Once you register a database instance, you can use it in a service or controller:

```javascript
export class UserService {
  constructor(private db: Database) {}

  async getAllUsers() {
    const users = await this.db.query('SELECT * FROM users');
    return users;
  }
}
```

## Integration with DI Container

```javascript
import { DIContainer } from 'fhyts';
import { MySQLDatabase } from './db/MySQLDatabase';

const container = new DIContainer();

container.register('db', () => {
  const db = new MySQLDatabase();
  db.connect(); // optional: can be managed async separately
  return db;
});
```

## Best Practices

* Create one driver class for each database type.
* Ensure that **connect()** is only called once at the start of the application.
* Use parameterized queries (**?**) to avoid SQL injection.
* Use interfaces to allow driver replacement without changing the service.

## Next

Once you understand Database usage, you can move on to the [Logger](#logger) section to learn how to structuredly log application activity, debug, and errors using the framework's built-in logging system.