No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
DestinyofYeet 493c74ccda
All checks were successful
Build / build (pull_request) Successful in 3m19s
Check / check_commit_format (pull_request) Successful in 18s
Check / check_cargo_lock (pull_request) Successful in 3s
Check / check_cargo (pull_request) Successful in 14s
Upload to crates.io / check_tag (push) Successful in 3s
Upload to crates.io / publish_macro (push) Successful in 2m30s
Upload to crates.io / publish_db_core (push) Successful in 2m53s
Upload to crates.io / publish_db_sqlite (push) Successful in 3m27s
Upload to crates.io / publish (push) Successful in 3m14s
chore(version): bump
2026-09-24 12:07:18 +02:00
.forgejo chore(workflow): add workflow trigger for check 2026-09-18 01:12:56 +02:00
crates feat(join): fixed tests 2026-09-21 14:34:15 +02:00
examples feat(reoccuring-tasks): run task at startup if needed 2026-09-24 12:05:57 +02:00
nix chore(version): bump 2026-09-24 12:07:18 +02:00
src feat(reoccuring-tasks): run task at startup if needed 2026-09-24 12:05:57 +02:00
.envrc chore: init 2026-05-01 20:49:01 +02:00
.gitignore chore(gitignore): ignore .cargo 2026-08-14 12:50:02 +02:00
Cargo.lock chore(version): bump 2026-09-24 12:07:18 +02:00
Cargo.toml chore(version): bump 2026-09-24 12:07:18 +02:00
deny.toml feat(workflows): check advisories 2026-09-16 22:53:42 +02:00
flake.lock chore: init 2026-05-01 20:49:01 +02:00
flake.nix fix(nix_build): hash and flake 2026-08-06 02:08:35 +02:00
LICENSE feat(workflows): adds build and check workflow 2026-06-02 19:36:28 +02:00
README.md feat(join): basic join 2026-09-21 00:58:52 +02:00

Dataloom

I wanted to build something like the python framework Django

How to use?

Take this struct for example


pub struct MyStruct {
  name: String,
  value: i32
}

To use this in django-rs, you need to derive and implement a few things.


#[derive(FromIter, SaveData)]
pub struct MyStruct {
  id: Option<i64>,

  name: String,
  value: i32
}

impl Model for MyStruct {
  // ...
}
  

A new id field has appeared. This id field controls wether the struct should be inserted or updated in the database. When creating a new instance of MyStruct set it to None. All MyStructs from the Database have the id field set.

impl Model for MyStruct {
    // This is the name of the table that gets created
    const TABLE_NAME: &'static str = "MyStructs";

    // This is the migration path of the Model
    fn get_migration() -> &'static Vec<ModelMigration> {
        // A LazyLock is needed for `&'static instead Vec<ModelMigration>` of just `Vec<ModelMigration>`, since get_migrations() will get called a lot
        static MIGRATION: LazyLock<Vec<ModelMigration>> = LazyLock::new(|| {
            vec![ModelMigration::new(
                // This is the ordering. The framework will step through the Migrations in the sorted order.
                0,
                MigrationKind::Create(vec![
                    // A 'id' Column is currently required. Once I abstract get_migration in some way, this shouldn't be required
                    CreateColumn::new(
                        "id",
                        ColumnType::Integer,
                        CreateOptions::default().set_primary_key(),
                    ),

                    CreateColumn::new(
                        "name",
                        ColumnType::String,
                        CreateOptions::default().set_non_nullable().set_unique(),
                    ),

                    CreateColumn::new(
                      "value",
                      ColumnType::Integer,
                      CreateOptions::default().set_non_nullable()
                    )
                ]),
            )]
        });

        &MIGRATION
    }

    // This is the real check if it gets inserted or updated
    fn get_id(&self) -> Option<i64> {
        self.id
    }

    fn set_id(&mut self, id: i64) {
        self.id = Some(id);
    }

    fn get_id_column_name(&self) -> &'static str {
        "id"
    }
}

In your main function you can then initialise the server. In the future I want to implement a PostgresStrategy and some other LoggingStrategy.

pub fn main() {
    let server = setup_test_server();
    let db = server.get_database();
    db.migrate_model::<MyStruct>().unwrap();

    let mut my_struct = MyStruct {
        id: None,
        name: "some_name".to_string(),
        value: 1337,
    };

    // This will set the 'id' field.
    db.save_model(&db.get_connection(), &mut my_struct).unwrap();

    let my_retrieved_struct: MyStruct = db
        .search_single_model::<MyStruct>(
            &db.get_connection(),
            SearchQuery::builder()
                // This searches for id = {my_struct.id}
                .q_where(
                    SearchConstraint::new::<MyStruct>("id", SearchOp::EQ, my_struct.id.unwrap())
                        .unwrap(),
                )
                .build(),
        )
        // this returns a Result<Option<MyStruct>, DatabaseStrategyError>
        .unwrap()
        .unwrap();

    assert_eq!(my_retrieved_struct, my_struct);
}