> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL

> Keep a Mirage filesystem in SQL tables.

The SQL VFS keeps a filesystem in a database's tables. It supports full read
and write operations and needs no extra for a SQLite file: it uses Python's
own `sqlite3`.

## Config

```python theme={null}
from mirage import MountMode, Workspace
from mirage.vfs.sql import SqlVFS

vfs = SqlVFS("./workspace.db")
ws = Workspace({"/sql": vfs}, mode=MountMode.WRITE)
```

| Parameter | Required | Default | Description |
| - | - | - | - |
| `path` | no | in memory | The SQLite file, opened and closed with the mount |
| `capacity` | no | none | The most bytes the files may hold, like `100MB` |
| `driver` | no | none | A `SqlDriver` to borrow instead of a file; you close it |

The tables are laid out as
[AgentFS](https://github.com/tursodatabase/agentfs)'s:

* `fs_inode`: one row per file and directory, with its size and mtime
* `fs_dentry`: each entry's name under its parent directory
* `fs_data`: a file's bytes, in rows of the database's chunk size (4 KiB unless the database says otherwise)
* `fs_config`: the chunk size

One database holds one filesystem. The TypeScript mount reads and writes the
same tables, so a Python and a Node process on one file serve one filesystem.

## VFS.md

The [VFS.md](https://docs.mirage.strukto.ai/home/setup/vfs-md.md) an agent reads with SQL mounted at `/<path>`.

> [tab] Rendered
>
> ### Virtual Filesystem
>
> | Path | Description |
> | - | - |
> | `/<path>` | `sql`, write |
>
> #### Supported Unix Commands for VFS
>
> Unix commands work on each path as on a local filesystem, as far as the path supports them:
>
> | Path | Supported |
> | - | - |
> | `/<path>` | Almost all Unix commands. |
>
> #### Limitations of Unix Commands for VFS
>
> Where a path differs from a local filesystem:
>
> | Path | Limitations |
> | - | - |
> | `/<path>` | `grep -r`, `find` and `du` stop after 1000 files; a glob matching more, `tar -c`, `cp -r` and `rm -r` are refused. |
>
> Run `man <cmd>` or `<cmd> --help` for one command's usage.

> [tab] Raw
>
> ```markdown theme={null}
> ---
> name: workspace-filesystem
> description: The virtual filesystem layout of this workspace.
> ---
>
> # Virtual Filesystem
>
> | Path | Description |
> | --- | --- |
> | `/<path>` | `sql`, write |
>
> ## Supported Unix Commands for VFS
>
> Unix commands work on each path as on a local filesystem, as far as the path supports them:
>
> | Path | Supported |
> | --- | --- |
> | `/<path>` | Almost all Unix commands. |
>
> ## Limitations of Unix Commands for VFS
>
> Where a path differs from a local filesystem:
>
> | Path | Limitations |
> | --- | --- |
> | `/<path>` | `grep -r`, `find` and `du` stop after 1000 files; a glob matching more, `tar -c`, `cp -r` and `rm -r` are refused. |
>
> Run `man <cmd>` or `<cmd> --help` for one command's usage.
> ```

## Cache

Index TTL is `0`, so listings are read from the database every time. A
workspace `index:` block still applies its `ttl` to this mount.

## Example

```python theme={null}
import asyncio

from mirage import MountMode, Workspace
from mirage.vfs.sql import SqlVFS


async def main():
    ws = Workspace({"/sql": SqlVFS("./workspace.db")}, mode=MountMode.WRITE)
    try:
        await ws.shell("mkdir -p /sql/data/")
        await ws.shell('echo "hello world" | tee /sql/data/hello.txt')
        r = await ws.shell("cat /sql/data/hello.txt")
        print(await r.stdout_str())
    finally:
        await ws.close()


if __name__ == "__main__":
    asyncio.run(main())
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.