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

Android Undo Snackbar Implementation #208

Closed bleuf1shi closed 8 years ago

bleuf1shi commented 8 years ago

I'm using squidb:2.0.3.

I've over simplified the example code from my own:

final ContactModel contactModelCopy = contactModelOriginal;
mDatabaseMaster.deleteWhere(ContactModel.class, ContactModel.CONTACT_CONTACT_ID.eq(contactModelOriginal.getContactContactId()));

Snackbar snackbar = Snackbar.make(mUiCoordinatorLayout, "DELETED!", Snackbar.LENGTH_LONG)
.setAction("UNDO", new View.OnClickListener() {
    @Override
    public void onClick(View view) {
          mDatabaseMaster.persist(contactModelCopy);
    }
});
snackbar.show();

The delete works, however, the persist that occurs afterwards always fails. Persist in this "after deleting" case will return false.

Any ideas on how I can implement the ability to delete an item from the database and then allow the ability to subsequently re-insert the same object?

Thanks

Here is my ContactSpec:

@TableModelSpec(className = "ContactModel", tableName = "contact_table")
public class ContactSpec {

    //region Reserved Fake ContactId's
    final transient public static long GENERIC_CONTACT_ID_ANY_CONTACT = Long.MIN_VALUE + 1;
    final transient public static long GENERIC_CONTACT_ID_UNKNOWN_CONTACT = Long.MIN_VALUE + 2;

    @ModelMethod
    public static boolean isGenericContactId(ContactModel contactModel) {
        long contactId = contactModel.getContactContactId();
        if(GENERIC_CONTACT_ID_ANY_CONTACT == contactId){
           return true;
        }else if (GENERIC_CONTACT_ID_UNKNOWN_CONTACT == contactId) {
            return true;
        }else{//Not a generic contact
            return false;
        }
    }
    //endregion

    @ColumnSpec(defaultValue = "true")
    private boolean alertEnabled;

    //region Android Contacts DB Links
    @ColumnSpec(defaultValue = "")
    private String contactLookupKey;

    @ColumnSpec(defaultValue = "-1")
    private long contactContactId;
    //endregion

    //region SMS Settings
    @ColumnSpec(defaultValue = "false")
    private boolean smsIncludedAsCommunication;

    @ColumnSpec(defaultValue = "")
    private String smsUriRingtone;

    @ColumnSpec(defaultValue = "false")
    private boolean smsRingtoneCrescendo;

    @ColumnSpec(defaultValue = "")
    private String smsLocationKey;
    //endregion

    //region Call Settings
    @ColumnSpec(defaultValue = "")
    private String callUriRingtone;

    @ColumnSpec(defaultValue = "false")
    private boolean callRingtoneCrescendo;
    //endregion

    //region Communication Triggers
    @ColumnSpec(defaultValue = "3")
    private int minimumCommunicationsCountTrigger;

    @ColumnSpec(defaultValue = "10")
    private int minimumCommunicationsMinutesSpanTrigger;
    //endregion
}
sbosley commented 8 years ago

The reason it's failing is that you haven't unset the rowid in the model object, so persist() is attempting to do an update operation, but failing since it can't find the corresponding rowid anymore. You can unset the rowid after the delete operation by calling contactModelCopy.setId(TableModel.NO_ID). Or, you can call createNew() instead of persist(), which will force the operation to clear the model id and then perform an insert.

bleuf1shi commented 8 years ago

Perfect. Thank You.