Skip to content
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

Feature/logs filtering #24

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open

Feature/logs filtering #24

wants to merge 17 commits into from

Conversation

levinzonr
Copy link
Contributor

added #18

  • .db file sharing

Copy link
Contributor

@msmoljan msmoljan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Roman,

I added some comments regarding change requests. Some of the requests are not trivial, so feel free to ping me anytime for explanation or if you have suggestions :)

Thanks!


override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return when(item?.itemId) {
R.id.actionShareDb -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're allowing the users of the library to create their own repository implementation, we could also let them share their backing storage. Additionally, it would be good to move everything I/O-related away from the presentation layer. This also includes the createDbCopy below.

Suggestions:

  • Create a repository method that tells you if it can offer a shareable "dump" of the backing data store (e.g. it could be a database like in our case, a text file or something else). Because some repositories might not be able to offer this, we have to also be able to return false here and the "share" button should appear/disappear accordingly.
  • Create another repository method returning a Uri to this dump file directly, so it can be immediately used in the intent. This way we don't care what the file is (e.g. SQLite, txt, csv or sth else), and we're encapsulating the I/O code into the repository implementation.

Copy link
Contributor Author

@levinzonr levinzonr Dec 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally makes sence, I've add this to LogRepository interface as a getShareableCopyUri() : Uri? ( Need help with this naming ) and implementation of copy is moved to LogDatabase

@@ -2,7 +2,14 @@
<string name="title_log_categories">Log categories</string>
<string name="tagTitle">Tag:</string>
<string name="severityTitle">Severity:</string>

<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this and the TODO

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -12,7 +12,7 @@ import com.nodesagency.logviewer.data.model.Category
import com.nodesagency.logviewer.data.model.LogEntry
import com.nodesagency.logviewer.data.model.Severity

private const val DATABASE_NAME = "log_database"
internal const val DATABASE_NAME = "log_database"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on a later comment regarding moving the I/O operations behind the repository, the LogDatabase could provide the backing DB's dump as a file Uri through some new method. This way we could also revert this back to private, as this class shouldn't expose any details about the backing DB to the outside world.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed :)

@@ -0,0 +1,18 @@
package com.nodesagency.logviewer.domain

sealed class FilterState(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this class should be internal, as we wouldn't want to expose it to the library users.

Could the name also be simplified to just Filter? It's less redundant and Filter.ByTag would be really nice to read :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sry, I'm wrong regarding internal, as I see it needs to be exposed through the repository interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, since it's public, please document the class, as well as its public methods and children with kotlindoc comments (you can use Logger.kt for reference).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is especially important to document how each filter is expected to behave, i.e. if the query needs to match the string exactly or if it's enough that they're similar in a way. Since we're using the SQL LIKE internally, every other repository implementation should also be expected to behave that way. E.g. you only need to enter a substring of a tag and it will find all tags containing that substring.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs are added and class is renamed 👍

@@ -44,4 +46,9 @@ interface LogRepository {
fun deleteAllCategoriesAndLogs()

fun getLogDetails(logEntryId: Long): LogDetails


fun getLogsFilteredBy(state: FilterState) : DataSource.Factory<Int, LogEntry>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the FilterState is renamed to Filter as mentioned in another comment, please rename the parameter to filter as well. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doone!

app:actionViewClass="androidx.appcompat.widget.SearchView" />

<item
app:showAsAction="ifRoom"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The presentation shouldn't know anything about our data layer implementation detail. This should be easily replacable after the other comments are accounted for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't quite whats this is referring to, hope it's fixed already


<menu>
<item
android:id="@+id/actionShareDb"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the other comments, at this point we shouldn't care if what we're sharing is a database, an XML file or something else, as long as it's some kind of a log dump file.

Hence we could name this something like actionShareLogDump. Please also adjust the title string in the same way (both the resource name and the actual string).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -16,6 +16,9 @@ internal interface CategoryDao {
@Query("SELECT * FROM Categories ORDER BY name ASC")
fun getAlphabeticallySortedCategories(): DataSource.Factory<Int, Category>

@Query("SELECT * FROM Categories WHERE (lower(name) LIKE :name)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this return the proper category if the :name is "I/O", but the name (the stored value compared) is lowercased to "i/o"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIKE is supposed to be case insensitive so I've removed lower() completely. Will cover this case with unit tests later

@@ -18,4 +18,13 @@ internal interface LogEntryDao {
@Insert
fun insert(entry: LogEntry)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar question regarding lowercasing for getLogsWithSeverity, getLogsWithMessage and getLogsWithTag

Will this return the proper category if the :name is "I/O", but the name (the stored value compared) is lowercased to "i/o"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIKE is supposed to be case insensitive so I've removed lower() completely. Will cover this case with unit tests later

@@ -74,4 +79,22 @@ internal class DatabaseLogRepository(
.logDetailsDao()
.getLogDetails(logEntryId)
}


override fun getLogsFilteredBy(state: FilterState): DataSource.Factory<Int, LogEntry> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to cover this and getCategoriesByName with tests if you have some time. Since they are a bit smarter than the rest of the class, it would be good to assure they're performing 100% correctly. You can use LoggerTest.kt for reference. You can also reuse its code for in-memory DB creation etc.

The other methods are more trivial so I was lazy to add tests for those. Shame on me and I should have done it regardless, will make up for it at some point :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed :D

@msmoljan msmoljan assigned msmoljan and levinzonr and unassigned msmoljan Dec 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants