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
Inheritance / Polymorphism #473
Comments
SQLDelight currently wont play well with joined table inheritance (the sql side solution to inheritance). The query will have to return a -- AnimalParent.sq
CREATE TABLE animal_parent (
name STRING NOT NULL PRIMARY KEY,
zoo_id INTEGER REFERENCES zoo
);
-- Dog.sq
CREATE TABLE dog (
name STRING PRIMARY KEY REFERENCES animal_parent,
can_small_from_far INTEGER AS Boolean
);
-- Spider.sq
CREATE TABLE spider (
name STRING PRIMARY KEY REFERENCES animal_parent,
bites INTEGER AS Boolean
);
-- Animal.sq
animals_view:
CREATE VIEW animal AS
SELECT animal_parent.name, zoo_id, can_smell_from_far, bites
FROM animal_parent
LEFT JOIN dog USING (name)
LEFT JOIN spider USER (spider); // Dog.java
@AutoValue public abstract class Dog implements Animal {
@Override public Boolean bites() {
throw new UnsupportedOperationException("Only available to spiders");
}
}
// Spider.java
@AutoValue public abstract class Spider implements Animal {
@Override public Boolean can_smell_from_far() {
throw new UnsupportedOperationException("Only available to dogs");
}
}
// Animal.java
public interface Animal extends AnimalModel {
Factory FACTORY = new Factory();
RowMapper<Animal> MAPPER = FACTORY.get_all_animals_in_the_zooMapper(new Get_all_animals_in_the_zooCreator<Animal>() {
@Override public Animal create(String name, int zoo_id, Boolean can_smell_from_far, Boolean bites) {
if (can_smell_from_far != null) {
// This is a dog
return new AutoValue_Dog(name, zoo_id, can_smell_from_far);
}
if (bites != null) {
// This is a spider
return new AutoValue_Spider(name, zoo_id, bites);
}
throw new AssertionError();
}
});
} and then your queries are on the get_all_animals_in_zoo:
SELECT *
FROM animal
WHERE zoo_id=?; it's pretty verbose. There might be a slightly more elegant solution or something that could be built into sqldelight but I haven't encountered this problem myself so I'm not sure. Let me know if you have more questions/concerns. |
I also had the same use case in past. In my chat messenger app, when I am storing message it can be of different type Image, Text, Video (around 10). What I did is to write my custom mapper and marshal.
My mapper and marshal are taking care of deserialising and serialising base message into and from string. It's not a scalable approach though and I am thinking of generating this code myself using some kind of converter like Converter<BaseMessage,String>. I need to check code - http://stackoverflow.com/questions/14308467/sqlite-convert-text-to-numbers (sql server has a really useful method which I couldn't find in sqlite - http://www.w3schools.com/sql/func_convert.asp) @AlecStrong, Do you recommend committing model files along with .sq files into the version control. https://github.com/alexsimo/delightful-persistence/tree/4d17062afae866750133545368695a0de5205ad0/app/src/main/java/com/alexsimo/delightfulpersistence/database |
If you mean the generated |
working-kotlin branch has diverged significantly from this style so closing for now |
Hi there, I'd like to know if is there any update on this. Is there any plans for SqlDelight to support polymorphism/inheritance? @AlecStrong Would you still recommend the same approach to deal with this still? That is, joining all inherited tables into a single view and treating it on mapper as a STI. I find it somehow uncomfortable, but maybe it still remains as good strategy to deal with it. Thank you! |
Given than i have these models:
and if i have two tables (Zoo, Animal), and we have a Query getAllAnimalIntTheZoo(int zooId).
can it return sub-types of Animal?
The text was updated successfully, but these errors were encountered: