yahoo / squidb

SquiDB is a SQLite database library for Android and iOS
https://github.com/yahoo/squidb/wiki
Apache License 2.0
1.31k stars 132 forks source link

Index via annotation #222

Open MFlisar opened 8 years ago

MFlisar commented 8 years ago

Following would be really fine:

@Index(name = "my_index", unique = true)
public String value;

@Index
public String value2; // index name should be some default value like tablename + "_" + fieldname + "_index" for example, unique should be a default value, probably false..

For the sake of database migration, the index must be a field of the generated class that is public, so that I can access it in the migration code. And those fields can be used to setup the array that is returned in the database classes getIndexes function.

Is there some reason for not supporting this? I understand why you can't create the array of indizes automatically (you explained it in an issue of someone else), but I don't see a reason for not generating indizes via annotation...

Current solution I use is following:

I have a static function in my database class that looks like following:

private static Index createIndex(Table table, Property property, boolean unique)
{
    return new Index(table.getName() + "_" + property.getName() + "_index", table, unique, property);
}
sbosley commented 8 years ago

Fields with UNIQUE constraints don't need an explicit index. If you do this:

@ColumnSpec(constraints="UNIQUE")
public String value;

It'll create the column with a uniqueness constraint, which causes SQLite to implicitly create an index for the field. So a hypothetical @Index annotation like the one you describe would mostly be useful for non-unique indexes. I suppose the advantage of a unique index on a column instead of using a constraint is that it would be easily droppable later if you changed your mind; I don't know how common that use case is though. I almost always prefer to use the uniqueness constraint since it lets you specify a conflict resolution clause.

This is another thing that would be easily achievable with a plugin. There's no technical reason it's not supported in core, just that it's not the style we prefer when creating indexes. Our general philosophy to avoid feature creep is to keep things minimal, and add new default plugins to the code generator if/when we feel that they serve a wide use case. In fact, the whole code generator itself is just implemented as a collection of plugins. We also encourage users to publish any plugins they write and will link to them in our wiki -- if there's enough demand for one, we'd definitely consider merging it into core.

Just FYI: we set up a gitter chat yesterday at https://gitter.im/yahoo/squidb. It seems like the idea of plugins has come up a lot in the last few issues you've opened :) -- you're welcome to join us over there and one of us can give you some tips on how to experiment with plugins for all the ideas you have.

MFlisar commented 8 years ago

I'm using many foreign keys (mostly not unique), that's what I need the indizes for...

sbosley commented 8 years ago

Makes sense. Note too that there is another way of creating indexes using the Table object:

Index idx = MyModel.TABLE.index("idx_name", MyModel.SOME_FIELD);
Index uniqueIdx = MyModel.TABLE.uniqueIndex("unique_idx_name", MyModel.SOME_UNIQUE_FIELD);

// If you were to generate this code inside the model class, it's even smaller:
Index idx = TABLE.index("idx_name", SOME_FIELD);
Index uniqueIdx = TABLE.uniqueIndex("unique_idx_name", SOME_UNIQUE_FIELD);

I definitely recommend you try using a plugin for this. We can certainly consider it for core, but I don't have a timeline for when we'd get it in and officially released -- creating a plugin that serves your use case lets you have this functionality right now. (And if you feel like it's working well you could consider submitting it back to core as a pull request!)