Sign in

    magpiedb

    Download zip
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    6 months ago
    Downloads
    42

    #magpiedb

    magpiedb is an experimental embedded OLAP database engine written in MoonBit.

    Today it runs as a native-first library and small CLI, with support for querying CSV and JSONL files using a compact SQL subset.

    #Current status

    Implemented today:

    • SELECT ... FROM read_csv('...')
    • SELECT ... FROM read_jsonl('...')
    • WHERE
    • aliases and scalar expressions
    • aggregates: COUNT, SUM, AVG, MIN, MAX
    • GROUP BY
    • HAVING
    • INNER JOIN
    • aggregate queries over joined inputs
    • ORDER BY
    • LIMIT

    Not implemented yet:

    • LEFT JOIN
    • multiple joins in one query
    • persistent tables / on-disk storage
    • Parquet / Arrow

    #Quick start

    Run the CLI:

    moon run cmd/main

    Run a single query directly:

    moon run cmd/main "SELECT name, age FROM read_csv('fixtures/csv/people.csv') WHERE age > 18"

    Run tests:

    moon test --target native

    #Example queries

    Simple scan:

    SELECT name, age FROM read_csv('fixtures/csv/people.csv') WHERE age > 18

    Sort and limit:

    SELECT name, age FROM read_csv('fixtures/csv/people.csv') ORDER BY age DESC LIMIT 2

    Grouped aggregate:

    SELECT active, COUNT(*) AS total FROM read_jsonl('fixtures/jsonl/events.jsonl') GROUP BY active HAVING COUNT(*) > 1

    Inner join:

    SELECT people.name, events.active FROM read_csv('fixtures/csv/join_people.csv') AS people JOIN read_jsonl('fixtures/jsonl/join_events.jsonl') AS events ON people.id = events.id WHERE events.active = true

    Aggregate over a join:

    SELECT people.name, COUNT(*) AS total FROM read_csv('fixtures/csv/join_people.csv') AS people JOIN read_csv('fixtures/csv/join_flags.csv') AS flags ON people.id = flags.id GROUP BY people.name HAVING COUNT(*) > 1

    Aggregate over a join with sort and limit:

    SELECT people.name, COUNT(*) AS total FROM read_csv('fixtures/csv/join_people.csv') AS people JOIN read_csv('fixtures/csv/join_flags.csv') AS flags ON people.id = flags.id GROUP BY people.name ORDER BY total DESC, people.name LIMIT 2

    #Library usage

    At the API level, usage is intentionally small:

    import {
    "codeworm96/magpiedb" @db
    }

    async fn run_query() -> Result[Unit, @db.DbError] {
    let conn = @db.Database::new().connect()
    let result = conn.query(
    "SELECT COUNT(*) AS total FROM read_csv('fixtures/csv/people.csv')",
    )?

    println(result.schema().columns.length().to_string())
    while true {
    match result.next() {
    Some(row) => println(row.to_string())
    None => break
    }
    }
    Ok(())
    }

    Public entrypoints:

    • Database::new()
    • Database::connect()
    • Connection::query(sql) (async)
    • ResultSet::schema()
    • ResultSet::next()

    #Data model

    Current logical types:

    • NULL
    • BOOLEAN
    • BIGINT
    • DOUBLE
    • VARCHAR

    CSV empty fields and missing JSONL keys become NULL.

    #Development notes

    • Preferred target is native.
    • The project currently uses moonlex and moonyacc for SQL front-end generation.
    • CSV input currently uses xunyoyo/NyaCSV.
    • The roadmap lives in PLAN.md.

    #License

    Apache-2.0.

    ColumnDef

    Root re-exports keep the public API small while execution types live in engine.

    LogicalType

    Root re-exports keep the public API small while execution types live in engine.

    Row

    Rows stay as a public convenience type; internal operators should stay columnar.

    Schema

    Root re-exports keep the public API small while execution types live in engine.

    Value

    Root re-exports keep the public API small while execution types live in engine.

    DbError

    pub suberror DbError {
    InvalidArgument(String)
    SqlSyntax(String)
    Bind(String)
    Scan(String)
    Io(String)
    Execute(String)
    Unsupported(String)
    Internal(String)
    } derive(
    Debug
    )

    Public error surface shared by parsing, binding, scanning, and execution.
    impl Show for DbError

    Connection

    pub struct Connection {
    } derive(Eq,
    Debug
    )

    Connection::query

    async fn Connection::query(self : Connection, sql : String) -> Result[ResultSet, DbError]

    Database

    pub struct Database {
    } derive(Eq,
    Debug
    )

    Database::connect

    fn Database::connect(self : Database) -> Connection

    Database::new

    fn Database::new() -> Database

    ResultSet

    pub struct ResultSet {
    schema :
    Schema

    // private fields
    } derive(Eq,
    Debug
    )

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io