Electron100 / butane

An ORM for Rust with a focus on simplicity and on writing Rust, not SQL
Apache License 2.0
93 stars 13 forks source link

Self referencing tables #14

Closed janosimas closed 2 years ago

janosimas commented 2 years ago

Hi, I trying to create a type with a optional self reference but I'm getting the error recursive type has infinite size.

Is there a way to create recursive types like this?

#[model]
#[derive(Debug, Default)]
pub struct MyType {
    #[auto]
    pub id: i32,
    pub recursion: Option<MyType>, 
}
janosimas commented 2 years ago

I suppose this should be Option<ForeignKey<MyType>> but that also didn't work.

Electron100 commented 2 years ago

Hi @janosimas, This is more of a Rust limitation than a Butane limitation -- if you remove the #[model] and #[auto] attributes from your first example it still won't compile -- Rust doesn't allow a struct to contain an option of itself. Of course in regular Rust you could have pub recursion: Option<Box<MyType>> which won't work in Butane.

ForeignKey internally uses a OnceCell, which I believe uses an Option internally. I could potentially be persuaded to make ForeignKey use boxing internally to support recursion, but I'd like to understand a little more about your use case. What type of relationship are you trying to represent?

janosimas commented 2 years ago

I'm testing some code as db instead of text. I'm with this issue when representing a module-like relationship.

struct Module {
  #[auto] id: i32,
  name: String,
  parent: Option<ForeignKey<Module>>,
}

I understand the rust limitation, I understood the library had a level of indirection that would allow that.

Electron100 commented 2 years ago

Ok. That seems reasonable. I've pushed a branch with a commit that should allow this to work. The branch is fkey_self (https://github.com/Electron100/butane/tree/fkey_self), commit id 80213117a4e70f98cf883b970924b107344faace.

Could you try this out and let me know if it meets your needs? If so, I'll merge it to master and release.

janosimas commented 2 years ago

It worked perfectly.

Electron100 commented 2 years ago

Released 0.4.2 which includes this change