{"id":17169480,"url":"https://github.com/salmans/codd","last_synced_at":"2025-04-13T16:06:45.638Z","repository":{"id":47587785,"uuid":"266631688","full_name":"salmans/codd","owner":"salmans","description":"A minimal in-memory database with relational algebraic expressions as queries","archived":false,"fork":false,"pushed_at":"2021-08-23T05:13:51.000Z","size":187,"stargazers_count":61,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-13T16:06:29.811Z","etag":null,"topics":["database","relational-algebra","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salmans.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-24T21:58:21.000Z","updated_at":"2025-03-09T11:56:39.000Z","dependencies_parsed_at":"2022-08-30T08:51:55.946Z","dependency_job_id":null,"html_url":"https://github.com/salmans/codd","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salmans%2Fcodd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salmans%2Fcodd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salmans%2Fcodd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salmans%2Fcodd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salmans","download_url":"https://codeload.github.com/salmans/codd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741204,"owners_count":21154254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","relational-algebra","rust"],"created_at":"2024-10-14T23:26:21.829Z","updated_at":"2025-04-13T16:06:45.594Z","avatar_url":"https://github.com/salmans.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# codd\n\n[`codd`](https://en.wikipedia.org/wiki/Edgar_F._Codd) is a library for evaluating *typed* relational expressions in a monotonically growing minimal database in memory. `codd` is primarily developed to support an implementation of [`razor`](https://github.com/salmans/rusty-razor) based on relational algebra, however, its design is consistent with common concepts of database theory and may be used as a minimal general purpose database.\n\nThe implementation of database instances in `codd` is borrowed from [`datafrog`](https://github.com/rust-lang/datafrog):\n* `Instance\u003cT\u003e` (`Variable\u003cT\u003e` in `datafrog`) contains tuples of type `T`,\n* Incremental view maintenance is implemented by maintaining tuples of `Instance\u003cT\u003e` in three sets of `to_add` (candidate tuples to be inserted), `recent` (recently added tuples), and `stable` (old tuples that have been reflected in all views).\n\nIn contrast, `codd` distinguishes relation instances from views and offers the trait `Expression\u003cT\u003e` and types that implement `Expression\u003cT\u003e` to query a database.\n\nThe relational algebra and database terminology in `codd` is adopted from [Alice's book](http://webdam.inria.fr/Alice/).\n\n## Build\n\n`codd` is written in [Rust](https://www.rust-lang.org). You can use Rust 1.54.0 or newer to build the library:\n\n```\ngit clone https://github.com/salmans/codd.git\ncd codd\ncargo build\n```\n\n## Example: [music](https://github.com/salmans/codd/blob/master/core/examples/music.rs)\n\nAdd `codd` to your project dependencies in Cargo.toml:\n\n```\n[dependencies]\ncodd = \"0.1\"\n```\n\nUse `codd` in your code:\n\n```rust\nuse codd::{Database, Error, Expression};\n```\n\nCreate a new database:\n\n```rust\n    let mut music = Database::new(); // music database\n```\n\nAdd relations to the database:\n\n```rust    \n    // `musician`, `band` and `song` are `Relation` expressions.\n    let musician = music.add_relation(\"musician\")?;\n    let band = music.add_relation(\"band\")?;\n    let song = music.add_relation(\"song\")?;\n```\n\nInsert tuples (records) to your database relations:\n\n```rust\n    music.insert(\n        \u0026musician,\n        vec![\n            Musician {\n                name: \"John Petrucci\".into(),\n                band: Some(\"Dream Theater\".into()),\n                instruments: vec![Guitar],\n            },\n            Musician {\n                name: \"Taylor Swift\".into(),\n                band: None,\n                instruments: vec![Vocals],\n            },\n            // more tuples...\n        ]\n        .into(),\n    )?;\n    \n    // add tuples to other relations...\n```\n\nConstruct query expressions and evaluate them in the database:\n\n```rust\n\n    let guitarist_name = musician\n        .builder()\n        .select(|m| m.instruments.contains(\u0026Guitar))\n        .project(|g| g.name.to_string())\n        .build();\n\n    assert_eq!(\n        vec![\n            \"Alex Turner\".to_string(),\n            \"Conor Mason\".into(),\n            \"John Petrucci\".into(),\n        ],\n        music.evaluate(\u0026guitarist_name)?.into_tuples() // evaluate the query and get the results\n    );\n```\n\nHere is a more complex query:\n\n```rust\n    let dt_member = musician\n        .builder()\n        .with_key(|m| m.band.clone())\n            // use `band` as the join key for `musician`\n        .join(band.builder().with_key(|b| Some(b.name.clone()))) \n            // join with `band` with `name` as the join key\n        .on(|_, m, b| (m.name.to_string(), b.name.to_string()))\n            // combine tuples of `musician` and `band` in a new relation\n        .select(|m| m.1 == \"Dream Theater\")\n        .project(|m| m.0.to_string())\n        .build();\n\n    assert_eq!(\n        vec![\"John Petrucci\".to_string(), \"Jordan Rudess\".into()],\n        music.evaluate(\u0026dt_member)?.into_tuples()\n    );\n```\n\nStore views of expressions:\n\n```rust\n    let dt_member_view = music.store_view(dt_members)?; // view on `dt_member`\n    let drummer_view = music.store_view(                // drummers view\n        musician\n            .builder()\n            .select(|m| m.instruments.contains(\u0026Drums))\n            .build(),\n    )?;\n\n    // inserting more tuples:\n    music.insert(\n        \u0026musician,\n        vec![\n            Musician {\n                name: \"John Myung\".into(),\n                band: Some(\"Dream Theater\".into()),\n                instruments: vec![Guitar],\n            },\n            Musician {\n                name: \"Mike Mangini\".into(),\n                band: Some(\"Dream Theater\".into()),\n                instruments: vec![Drums],\n            },\n        ]\n        .into(),\n    )?;\n\n    // views are up-to-date:\n    assert_eq!(\n        vec![\n            Musician {\n                name: \"Lars Ulrich\".into(),\n                band: Some(\"Metallica\".into()),\n                instruments: vec![Drums]\n            },\n            Musician {\n                name: \"Mike Mangini\".into(),\n                band: Some(\"Dream Theater\".into()),\n                instruments: vec![Drums]\n            }\n        ],\n        music.evaluate(\u0026drummer_view)?.into_tuples()\n    );\n    assert_eq!(\n        vec![\n            \"John Myung\".to_string(),\n            \"John Petrucci\".into(),\n            \"Jordan Rudess\".into(),\n            \"Mike Mangini\".into()\n        ],\n        music.evaluate(\u0026dt_member_view)?.into_tuples()\n    );\n\n    Ok(())\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalmans%2Fcodd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalmans%2Fcodd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalmans%2Fcodd/lists"}