-
Notifications
You must be signed in to change notification settings - Fork 182
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
Add notification tags #768
Conversation
Codecov Report
@@ Coverage Diff @@
## master #768 +/- ##
==========================================
+ Coverage 96.05% 96.85% +0.79%
==========================================
Files 87 87
Lines 2460 2638 +178
Branches 267 296 +29
==========================================
+ Hits 2363 2555 +192
+ Misses 68 50 -18
- Partials 29 33 +4
Continue to review full report at Codecov.
|
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.
Few design questions, otherwise LGTM!
@@ -36,7 +62,7 @@ private Changes(@NonNull Set<String> affectedTables) { | |||
*/ | |||
@NonNull | |||
public static Changes newInstance(@NonNull Set<String> affectedTables) { | |||
return new Changes(affectedTables); | |||
return new Changes(affectedTables, Collections.<String>emptySet()); |
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.
omg, this looks so weird after almost year of writing in kotlin style Collections.emptySet<String>()
. I haven't been really writing in java for a long time now…
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.
😿
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
|
||
Changes changes = (Changes) o; | ||
|
||
return affectedTables.equals(changes.affectedTables); | ||
if (!affectedTables.equals(changes.affectedTables)) return false; |
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.
Glad we have EqualsVerifier!
@@ -144,6 +145,110 @@ | |||
} | |||
|
|||
/** | |||
* Allows observe changes of required tags. | |||
* <p/> | |||
* Tags are the addition level of notifications that provides |
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.
Tags are optional meta information that you can attach to Changes object to have more fine-grained control over observing changes in the database.
?
* Immutable set of affected tags. | ||
*/ | ||
@NonNull | ||
private final Set<String> affectedTags; |
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.
Btw, what if we make Set<Object> affectedTags
? Or that would be overkill?
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 thought I will be less convenient for the most frequent case with Strings
.
But I agree tags it is not about common cases, so flexibility should be the main purpose.
@rsinukov also votes for object
.
Let's do 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.
Well, I do agree that Strings will probably be most used and we'll have to force these users to class-cast them for no good reason, let's wait for @geralt-encore opinion then!
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.
+1 for Object
. In my understanding, you can use as tag whatever you want and if String
will be the most frequently used it doesn't mean that tag should be restricted to it. Also, View
tag in Android is Object
as well.
return observeChangesOfTags(Collections.singleton(tag)); | ||
} | ||
|
||
|
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.
el
* @return {@link rx.Observable} of {@link Changes} subscribed to changes of required tags. | ||
*/ | ||
@NonNull | ||
public abstract Observable<Changes> observeChangesOfTablesAndTags( |
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 don't think we need combination methods, user can observe raw changes and filter whatever combination he/she needs (using RxJava, plain java, etc)?
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.
If so, we should open ChangesFilter
to make it visible for Query
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.
Lets make it public
and keep comment that it is for internal usage 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.
I'd prefer to keep as small amount of public methods/classes/API as possible if current ones already allow you to do what you want without too much boilerplate…
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.
+1 for removing it. It can get out of hands pretty quick if we need to introduce one more way of filtering changes. observeChangesOfTablesAndTagsAndWhatever
plus combination look ugly.
* @return {@link rx.Observable} of {@link Changes} subscribed to changes of required tag. | ||
*/ | ||
@NonNull | ||
public Observable<Changes> observeChangesOfTableAndTag(@NonNull String table, @NonNull String tag) { |
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.
Same as above?
* @see com.pushtorefresh.storio.sqlite.StorIOSQLite#observeChangesOfTag(String) | ||
*/ | ||
@NonNull | ||
public CompleteBuilder tag(@Nullable String tag) { |
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.
tags? or overload with Set<String>
? Same for other queries
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.
👍
@@ -65,6 +65,16 @@ public void observesTablesShouldNotBeNull() { | |||
} | |||
|
|||
@Test | |||
public void observesTagsShouldNotBeNull() { | |||
RawQuery rawQuery = RawQuery.builder() | |||
.query("lalala I know SQL") |
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.
kek
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.
nobody knows!
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 won't tell @thevery and Stasic! (If you see this message it's a GitHub's bug obviously).
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.
Nice work! 👍
* Immutable set of affected tags. | ||
*/ | ||
@NonNull | ||
private final Set<String> affectedTags; |
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.
+1 for Object
. In my understanding, you can use as tag whatever you want and if String
will be the most frequently used it doesn't mean that tag should be restricted to it. Also, View
tag in Android is Object
as well.
return new Changes(Collections.singleton(affectedTable)); | ||
final Set<String> tags = affectedTag == null | ||
? Collections.<String>emptySet() | ||
: singleton(affectedTag); |
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 makes sense to reuse static import for singleton
next line or remove it completely.
* @return {@link rx.Observable} of {@link Changes} subscribed to changes of required tags. | ||
*/ | ||
@NonNull | ||
public abstract Observable<Changes> observeChangesOfTablesAndTags( |
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.
+1 for removing it. It can get out of hands pretty quick if we need to introduce one more way of filtering changes. observeChangesOfTablesAndTagsAndWhatever
plus combination look ugly.
@nikitin-da just one comment. I think that it might be a good idea to change signature of |
@geralt-encore good idea! |
|
||
final Observable<Object> observable; | ||
if (!observesTables.isEmpty() || !observesTags.isEmpty()) { | ||
observable = ChangesFilter.applyForTablesAndTags(storIOSQLite.observeChanges(), observesTables, observesTags) |
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.
@artem-zinnatullin It seems we forgot to subscribe on changes 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.
Please correct me if I'm wrong, but it was our design decision, since executeSql
is basically a side effect and does not return data from database, same as we do for Put and Delete, we don't subscribe them to db changes!
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.
Yep, I agree that it is the side effect operation and it will not be clean to subscribe on some changes with it.
But current RawQuery.observesTags
possibility can be misleading.
Maybe we should note this feature in doc, because it may look as unexpected behavior =(
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.
Yes, I definitely remember discussing that, and I'm pretty sure we have docs about 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.
I didn't find it for asRxObservable, for RawQuery and in the doc too=)
@artem-zinnatullin PTAL please, to prevent guys from merge conflicts ;) |
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.
ExecuteSql should not observe changes in db! Otherwise LGTM, though I kinda liked idea of String tags since they're easier to use and understand cc @thevery do you have an opinion here?
@@ -16,28 +17,62 @@ | |||
* <p> | |||
* Hides RxJava from ClassLoader via separate class. | |||
*/ | |||
final class ChangesFilter implements Func1<Changes, Boolean> { | |||
public final class ChangesFilter implements Func1<Changes, Boolean> { |
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.
We can't keep it package private?
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.
No, because it used in com.pushtorefresh.storio.sqlite.impl
for DefaultStorIOSQLite#observeChangesInTables
and com.pushtorefresh.storio.sqlite.operations.execute
for asRxObservable
|
||
final Observable<Object> observable; | ||
if (!observesTables.isEmpty() || !observesTags.isEmpty()) { | ||
observable = ChangesFilter.applyForTablesAndTags(storIOSQLite.observeChanges(), observesTables, observesTags) |
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.
Please correct me if I'm wrong, but it was our design decision, since executeSql
is basically a side effect and does not return data from database, same as we do for Put and Delete, we don't subscribe them to db changes!
@artem-zinnatullin objects are easier to fail ( |
Yeah, I have similar thoughts, moreover, string tags can be more understandable for those who remember how web 2.0 was growing: tag clouds on websites, tags in blog posts/articles, tags in twitter and so on. @geralt-encore? |
It seem there is equality of votes for now, so what type of tag will be final?) |
There was also question about first required tag with vararg #768 (comment) |
@nikitin-da I've changed emojis to ❤️ and 🎉 to remove negativity of 👎 variant haha, so please ask guys from your team to vote here so we could count here, cc @geralt-encore, I'll also ask community to vote. Regarding overloads — I like @geralt-encore's suggestion about |
String variant won 6:5 ) |
Closes: #663