apstanisic / zmaj

Zmaj is a headless CMS for managing database
https://zmaj.vercel.app
MIT License
5 stars 0 forks source link

There can be multiple foreign keys with same name #67

Closed apstanisic closed 1 year ago

apstanisic commented 1 year ago

Foreign key names are only unique in scope of the table, not on the database level, so it's possible to have 2 foreign keys with same name.

This should work kinda normally, bit might cause unforeseen problems. Maybe easiest solution is to switch from current relations schema to something like this fk_name, fk_table_name, is_owner. This requires 1 more field of info in db, but with that I can be 100% certain in the future. So if it's is_owner, that means that it's m2o, if not it's o2m. table_name will be deleted from schema, since we can get that value with this 3 values

Edit: I can also use fk_column,fk_table,is_owner, since there can only be single foreign key on one column

Edit: This is not high priority, since in 99.999% fk names use some kinda convention, but it could still maybe someday cause problem

Edit: There can be multiple foreign keys on the same column, they just have to have foreign key. Maybe 1 in billion chance that this exists somewhere, but it works. That means that that value must exist in 2 different tables, which is maybe a valid use case. So use fk name, not fk column.

Edit: But this makes it a problem, since 1 field is 1 value, and if there are multiple relations, it can cause some bugs. Use fk_table,fk_column, and simply take first fk for that. I have never seen anyone use 2 fks on same column in real code. Checking for it, and narrowing to only allowed possibilities is to much work for a little gain

Edit: Currently there is a check to ensure that property name is unique, but it's meaningless, since it can conflict with field name.

apstanisic commented 1 year ago

Okay, so I changed my mind. Having 2 fks with same name is definitely an anti-pattern, so there should not be special handing for 1 in a million case. I will simply do this allFks -> sort by fkTable -> unique by fkName. This will only return first fk, second will simply be ignored.