adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
530 stars 125 forks source link

Add one_to_many template #343

Closed vabenil closed 1 year ago

adamdruppe commented 1 year ago

one to many is basically the same as what children does right?

will prolly wanna add docs describing the similarities and differences

vabenil commented 1 year ago

They are not really the same because children only gives you the many in the one-to-many relationship say you have a User and Role tables where each User has a role and a Role can be used by multiple users, with:

/*
This would give you all of the users with the Role `role`.
*/
auto res = role.children!(User, Role).execute(db);

However if you wanted to get the Role of a user there would be no way of doing so with children. It doesn't work the other way around.

Also the big thing that one_to_many can do and children can not do is handle multiple relationships(Multiple foreign keys pointing to the same Table for example:

import std.stdio;
import arsd.sqlite;
import arsd.database_generation;

alias FK(alias toWhat) = ForeignKey!(toWhat, null);

@DBName("Professor") struct Professor
{
    int id;
    string name;
}

@DBName("Course") struct Course
{
    int id;
    @FK!(Professor.id) int professor_id;
    @FK!(Professor.id) int assistant_id;
}

mixin(one_to_many!(Course.professor_id, "prof", "courses_taught"));
mixin(one_to_many!(Course.assistant_id, "assistant", "courses_assisted"));

void main()
{
    Database db = new Sqlite("test2.db");

    Course course = db.find!Course(1);
    Professor prof = course.get_prof(db);

    writeln(prof.get_courses_taught(db));
    writeln(prof.get_courses_assisted(db));
}

Here there are 2 relationships from Course to Professor here. One of them you can get from get_courses_taught and the other one with get_courses_assisted. If you attempt to use children like so

    writeln(prof.children!(Course, Professor).execute(db));

You would get: source/arsd/database_generation.d(489,2): Error: static assert: "Course does not have exactly one foreign key of type Professor"

In conclusion

children is nice in that its simple, doesn't require mixins to create extra symbols(functions). However it doesn't handle the one in one-to-many relationships at all, and it also doesn't work in tables with more than one relationship to a table. And finally coming out of my personal taste I believe that prof.get_courses(db) is a clear syntax than say prof.children!(Course, Professor).execute(db)

vabenil commented 1 year ago

Also about the docs. I don't know how to write docs for this project. Could you please point me to where I can read about the syntax for the docs, and where I should add them?

adamdruppe commented 1 year ago

Generally speaking just putting things in the /++ ......... +/ blocks at the top of the file or on teh new functions is good enough (I haven't done much on this one in particular so there's not a lot of xamples but some of the other files do). I'll fix up syntax as needed so just worry about getting the content up

adamdruppe commented 1 year ago

but yeah your comment there is good i get it now.

so if you prefer i can just copy/paste that into the file and merge it now

vabenil commented 1 year ago

Wait, I want to modify the comment with a clearer explanation

vabenil commented 1 year ago

Done

adamdruppe commented 1 year ago

ok i gotta go now ut i'll do the edits and repush any changes when im back

adamdruppe commented 1 year ago

I did a few minor grammar fixes, added the history section, and pasted in your comment here as a detailed discussion under the comment too. I'll prolly cross-link with children later but this is good for now.

Thanks for your contribution!