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
Rework ExtendedStorage API and service plugin API to remove any Notebook::Ptr #30
Conversation
src/notebook.h
Outdated
| /** | ||
| Constructs a new Notebook object. | ||
| */ | ||
| explicit Notebook(); | ||
|
|
||
| explicit Notebook(const QString &name, const QString &description); | ||
| explicit Notebook(const QString &name, const QString &description, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old thing, but the explicit keyword doesn't look needed in any of these. Remove if you feel like it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I've removed them.
src/extendedstorage.cpp
Outdated
| } | ||
|
|
||
| if (!nb || d->mNotebooks.contains(nb->uid())) { | ||
| if (d->mNotebooks.contains(nb.uid())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we guard for notebook validity somewhere around here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you mentioned later, isValidNotebook() is more about testing if notebook is writable. But that's a good remark anyway, and I've added a commit that guard against writing to the database runtime only notebooks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meant here more Notebook::isValid() type of validity check. Now it looks like this will proceed adding a notebook without a uid.
src/extendedstorage.cpp
Outdated
| if (!nb.isNull()) { | ||
| if (nb->isRunTimeOnly() || nb->isReadOnly()) { | ||
| const Notebook &nb = notebook(notebookUid); | ||
| if (nb.isValid()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting method. Could assume it's the same as notebook(uid).isValid() but it's not exactly. Three cases using it, pondering if it's needed or should the name be adjusted a little, e.g. notebookWritable() or something to that direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I've renamed the method to isWritableNotebook(). I makes more sense, I agree.
src/sqlitestorage.cpp
Outdated
| qCDebug(lcMkcal) << "Storage is empty, initializing"; | ||
| createDefaultNotebook(); | ||
| if (!setDefaultNotebook(Notebook(QString::fromLatin1("Defaul"), QString()))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Defaul"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
src/sqlitestorage.cpp
Outdated
| @@ -1800,7 +1807,7 @@ bool SqliteStorage::loadNotebooks() | |||
| sqlite3_stmt *stmt = NULL; | |||
| bool isDefault; | |||
|
|
|||
| Notebook::Ptr nb; | |||
| Notebook *nb; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor detail, but I could move to the while() declaration to keep the scope minimal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you suggested, I've turn the SqliteFormat method into returning a Notebook and not a pointer to one. I've updated here accordingly.
src/sqliteformat.cpp
Outdated
| @@ -1298,10 +1340,10 @@ bool SqliteFormat::Private::insertCalendarProperty(const QByteArray &id, | |||
| } | |||
| //@endcond | |||
|
|
|||
| Notebook::Ptr SqliteFormat::selectCalendars(sqlite3_stmt *stmt, bool *isDefault) | |||
| Notebook* SqliteFormat::selectCalendars(sqlite3_stmt *stmt, bool *isDefault) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, does the pointer return value save much when the result gets deleted anyway? Perhaps could alternatively just return a Notebook instance which wouldn't need the deletion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, it's now returning a Notebook instance. instead of a pointer on a Notebook instance.
|
I'm propagating changes in CalDAV plugin at the moment and this is raising a concern : there could be cases where the notebook is read-only, but we would like to get the upstream changes. The current pattern is to get the corresponding Notebook::Ptr and to make it read/write, do the calendar modifications and save them. This is working without touching the read-only flag status in the DB itself because we're dealing with a pointer to the internal Notebook in the ExtendedStorage object and calling the Now changing for Notebook references make the whole pattern to fail. Except if we flip the flag in the DB itself with a call to What do you think about removing the |
|
Maybe an additional question regarding API changes : since we're not dealing with pointers anymore, I've found the need for a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about removing the || isReadOnly() from isValidNotebook() ? The read-only flag would only be used as a hint for UI operations, but not enforced at the DB where we can still do all desired modifications when calling save() ? I may rename the isValidNotebook() to isStoredNotebook() or something to reflect this ?
Makes sense removing the isReadOnly() check. Better consider that more as a hint towards application code. It's strange usage now when readonly status gets changed without updateNotebook() and it's assumed effective.
Maybe an additional question regarding API changes : since we're not dealing with pointers anymore, I've found the need for a ExtendedStorage::containsNotebook() method, to know if we should call addNotebook() or updateNotebook().
[...] But thinking more about it, we may drop addNotebook() and updateNotebook() completely and create a new storeNotebook() which internally update or add the notebook, depending if it already exists or not. What do you think ?
The containsNotebook() could nicely fit the API, I'm ok with such. For latter I do sort of like if the additions and updates are separated for keeping it clearer which one is happening.
All in all this is looking mostly fine, but haven't tested much beyond compilation. Would need some api adaptation PR at least for nemo-calendar. Suppose that's coming up too?
src/extendedstorage.cpp
Outdated
| } | ||
|
|
||
| if (!nb || d->mNotebooks.contains(nb->uid())) { | ||
| if (d->mNotebooks.contains(nb.uid())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meant here more Notebook::isValid() type of validity check. Now it looks like this will proceed adding a notebook without a uid.
src/extendedstorage.cpp
Outdated
| } | ||
| const Notebook &nb = d->mNotebooks.value(nbid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: extra space after =
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected.
Exactly, I've removed it's usage. I took the opportunity to actually completely remove
I didn't try it yet in QML bindings, but you can see it in action for buteo plugin : see sailfishos/buteo-sync-plugin-caldav#11 |
|
Since we're already modifying the API in @pvuorela do you know if there are other places where this ServiceHandler::send/updateInvitation API is in use ? |
src/sqlitestorage.cpp
Outdated
| (*savedIncidences) << *it; | ||
| if (dbop == DBInsert || dbop == DBUpdate) { | ||
| const Notebook ¬ebook = mStorage->notebook(notebookUid); | ||
| // Nota here : allow to save/delete incidences in a read-only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: "nota" sound like a typo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a contraction of latine "nota bene" ;) Maybe a bit over contracted actually. I've updated for a more English "notice:" construction.
src/sqlitestorage.cpp
Outdated
| @@ -1169,6 +1171,8 @@ int SqliteStorage::Private::loadIncidences(sqlite3_stmt *stmt1, | |||
| // << incidence->dtStart() << endDateTime | |||
| // << "in calendar"; | |||
| count += 1; | |||
| } else { | |||
| delete incidence; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the above break; case leaking memory now since selectComponents() return value is owned by the caller? Pondering should it still just return Incidence::Ptr since incidences are going to end up as such and there are these cases where it's ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I've reverted these changes at the moment. Ideally it's in preparation of SqliteStorage not assuming that loaded incidences will be used in the same thread. But these changes can be done at that moment.
Don't assume that incidences are shared pointer when it's not necessary, like in internal database reads.
Use direct reference to ExtendedStorage when there is no intent to keep a pointer on this objects. Use the notebook uid as argument instead of passing the calendar to get it.
|
I've fixed the conflict and checked that it compiles and pass the tests. |
|
With the simpler notebook api change in, think we could close this now. |
@pvuorela, this is a proposition to remove completely the Notebook::Ptr style, using either notebook ids or reference to notebooks.
This is done in steps:
What do you think ? Applying these API changes will imply to update:
The changes in ExtendedStorage API will correct some weirdness (in my opinion) like the fact that you need to use the exact Notebook::Ptr object when updating, while any change to the DB file is actually detaching your Ptr from the one that is stored, thus making any update call fails.