# Database

NOVA's database layer is built on top of [oxmysql](https://github.com/overextended/oxmysql).

## Connection

Set your database connection in `server.cfg`:

```cfg
set mysql_connection_string "mysql://user:password@localhost/nova_db?charset=utf8mb4"
```

## Query Methods

### Async (Recommended)

```lua
-- Execute (INSERT, UPDATE, DELETE)
MySQL.Async.execute('UPDATE my_table SET value = ? WHERE id = ?', {newValue, id},
    function(rowsChanged)
        print('Updated ' .. rowsChanged .. ' rows')
    end
)

-- Fetch All
MySQL.Async.fetchAll('SELECT * FROM my_table WHERE key = ?', {key},
    function(results)
        for _, row in ipairs(results) do
            print(row.name)
        end
    end
)

-- Fetch Scalar (single value)
MySQL.Async.fetchScalar('SELECT COUNT(*) FROM my_table WHERE key = ?', {key},
    function(count)
        print('Count: ' .. count)
    end
)
```

### Sync

```lua
-- Execute
local rowsChanged = MySQL.Sync.execute(
    'INSERT INTO my_table (key, value) VALUES (?, ?)',
    {key, value}
)

-- Fetch All
local results = MySQL.Sync.fetchAll(
    'SELECT * FROM my_table WHERE owner = ?',
    {identifier}
)

-- Fetch Scalar
local count = MySQL.Sync.fetchScalar(
    'SELECT COUNT(*) FROM my_table WHERE key = ?',
    {key}
)
```

## Database Setup

The framework includes SQL files that create all required tables automatically. Run these during installation:

1. **nova\_core/sql/nova.sql** — Creates all core framework tables
2. **nova\_bank/sql/bank.sql** — Creates banking tables

## Best Practices

::: tip

* Use parameterized queries (`?` placeholders) to prevent SQL injection
* Prefer async queries for non-blocking operations
* Use the player object methods instead of direct DB queries when possible
* The player object caches data in memory for fast access
* Never expose table names or schema details in client-side code :::

## Security

* All database operations should be performed server-side only
* Use parameterized queries to prevent SQL injection
* The framework validates all data before database operations
* Internal table structure is not disclosed in this documentation
