pinchbv / floor

The typesafe, reactive, and lightweight SQLite abstraction for your Flutter applications
https://pinchbv.github.io/floor/
Apache License 2.0
965 stars 191 forks source link

Support for defaultValue in @ColumnInfo #256

Open VadimOsovsky opened 4 years ago

vitusortner commented 4 years ago

Hi! What's your exact use case for this?

tulioccalazans commented 4 years ago

@vitusortner In Room, if defaultValue is defined, we don't have to set this property. This way, in an insertion the field get the default value. It is related to SQLite default value definition See 'The DEFAULT clause' section.

@ColumnInfo(name: "IsActive", defaultValue: "false")
  bool active;

It is an useful feature.

Because of the lack of the defaultValue property, we need to do:

// WARNING: We need to iterate to add values to some fields, because Floor doesn't support defaultValue yet.
    //await floor.contactDao.insertAll(list);
    for (var c in list) {
      c.group = false;
      c.active = true;
      c.assistant = true;
      c.muteNotifications = false;
      await floor.contactDao.insert(c);
    }
mqus commented 4 years ago

Why not assign a default value in the class description by changing

@ColumnInfo(name: "IsActive", defaultValue: "false")
  bool active;

to

@ColumnInfo(name: "IsActive")
bool active=false;

? This should cover 90% of the use cases. Could help me understand why that won't work in your case?

VadimOsovsky commented 4 years ago

@mqus having non final fields isn't something I usualy do unless really needed

mqus commented 4 years ago

Sorry, you had no finals in your example code, so I assumed otherwise :wink:

What about

  @ColumnInfo(name: "IsActive")
  final bool active;

  YourClass(this.id, this.foo, {this.bar, this.active=false});

? here, bar would have the default value null and active would have the default value false.

mqus commented 4 years ago

Tbh, If I would implement this, I would probably do it in the same manner as room had done it, Meaning that the generated CREATE query for the entity would set the default value, but it won't ever be used because the @insert queries do not omit fields which were set to null. To be able to use that default value, you would have to use queries we still don't support.

cassioseffrin commented 4 years ago

Seizing the opportunity of this thread. Could I create a default value as the output a query: Default value: SELECT strftime('%s', 'now') || (last_insert_rowid()+1)

@ColumnInfo(name: "timestampId", defaultValue: SELECT strftime('%s', 'now') || (last_insert_rowid()+1))

I know It's a little tricky but It's all I need .

May I can do it making an alter table onCreate event. However if I can do it as a default value will be much more clear.

👍

mqus commented 4 years ago

As I wrote before, building a CREATE TABLE statement which sets the default with literal values or expressions (like you wrote) is very easy. But selectively omitting fields when creating an @insert function is hard[1]! If we don't omit them (like we do now) we set the column of this entity to its value (possibly null) and sqlite won't use the default value, ever. To use this, you would have to use @Query('INSERT ...') dao methods, which in turn don't play nicely with streams (yet). I think it would be cleaner to set default values using dart provisions right now or using triggers, as you wrote.

I think we can accept contributions for the defaultValue field in @ColumnInfo and its implementation, even if its not usable in @insert methods (like in room). What do you think about this, @vitusortner ?

[1] You would have to decide at runtime(slow, for each entity separately) if you want to add single columns to the database or not. Now, the main issue is, when do you omit the columns? when the value is null? What about fields that are nullable even in the database? sqlite makes a difference between inserting null values and values that were not provided, a distinction that is impossible with the dart type system (and most others). So if we have a nullable column with a default value, should null be inserted or the default value? Floor could provide a fixed solution to this edge case or ignore it but this is not as clear-cut as I would like it.

vitusortner commented 4 years ago

Contributions for ColumnInfo.defaultValue are very welcome, indeed!

cassioseffrin commented 4 years ago

Hello,

Any news about ColumnInfo.defaultValue?

leononly commented 1 year ago

Yes this feature is welcome indeed, as we might send the .db file to other system to implement. I hope we can have this feature soon.

lucasdidur commented 2 days ago

Any update about this? We are in 2024