Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement relations for Models #23

Open
lteacher opened this issue May 5, 2016 · 3 comments
Open

Implement relations for Models #23

lteacher opened this issue May 5, 2016 · 3 comments

Comments

@lteacher
Copy link
Owner

lteacher commented May 5, 2016

Details
Note: this task depends on the completion of #6

Of course it wont be an object relational mapper if there are no relations. It needs to be possible to implement there.

I had given this some though and considered potential for the names, I think the annotation I cant suggest as I want to have a look around and think about what the most beautiful name might be...

I will come back to this one as it will take a lot of thought there are a lot of examples to draw from but I want to find a nice way that looks and acts in an enjoyable way, ie... its definitely not going to be hibernate but may look there for some inspiration.

Also I forgot that I had given thought to how the queries are connected and though that it could fit together easily like:

// Include some rel, this might be anything but key point is instead of run() there is a new joining term
Model.find('User').filter((user) => hasName).incl('Role').filter((role) => _isAdmin).run();
@lteacher
Copy link
Owner Author

lteacher commented May 5, 2016

What if relations and types could be used to infer what is happening? for example:

@Model('user')
class User {
  @Rel('role') List roles; // List -> 'Has many'
}

@Model('role')
class Role {
  @Rel('user') User parent; // User -> 'Belongs to'
  @Rel('permission') List perm; // Has many......
}

@Model('permission')
class Permission {
  @Rel('role') List roles; // But its actually 'Many to Many'
}

Probably the last one is the hardest since it should be joined on a separate table

@lteacher
Copy link
Owner Author

Hmm added the thoughts above a while ago, I am pretty sure the relations will be like the following:

@Model() // 'name' is auto set to Classname in lowercase e.g 'user'
class User {
  // Attribute definitions
  @Attr(primaryKey: true) int id;
  @Attr() String username;
  @Attr() String password;

  // Has one to many 'roles', the model relation is inferred by <Role>
  @Rel() List<Role> roles;
}

@Model()
class Role {
  // Belongs to user, using model type for example if type cant be inferred
  @Rel(model: User) dynamic user;
}

Currently an issue is trying to figure out how link the query together, at the moment its something like

Model.find(User)
    .where('name').eq('Bob')
    .incl('roles').where('type').eq('admin')
    .incl('permissions').where('access').eq(true)
    .run()

Which makes sense for developer but that really must result as below behind the scenes:

chain
  where
    eq
      incl
chain
  where
    eq
chain
  where
    eq
      run

So I have one solution in mind which is not nice but maybe its the best way to start off with which is to create the new chain action when an incl is hit, then link the chain to a parent. Then on run while parent is not null go back to the root and run... then use the sub chains as the includes which need to be added into the map of results in either executeSingle or executeMulti which just in turn adds the singular or multiple results onto the entity.

For example

  • If include is hit for a chain
    • Add a new action which is find or findAll depending on the relation.
    • Run that find chain during mapping of results, for example here (actually just noticed the var still says user there lol, changed it)

Consider:

  • Finds need to have a parent key to find the sub relations which means the query must happen in stream mapping
  • Updates know the keys up front, no one wants to wait for the parent when it can be done at the same time, and some updates don't require any key similar to removals below
  • Removals need to remove children but may never reference any key.

lteacher added a commit that referenced this issue May 16, 2016
lteacher added a commit that referenced this issue May 22, 2016
- Rel annotation
- Relations in schema
- Derived fields in relation tables
- More tests...
@lteacher
Copy link
Owner Author

This feature is the biggest yet clearly... A lot has been done outstanding is actually just fixiing up how the dependent queries will chain together from an adapter point of view, but am on break for 2 weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant