Skip to content
This repository was archived by the owner on Apr 3, 2021. It is now read-only.

chore: Built CacheLayer to an extent #16

Merged
merged 2 commits into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.stvayush.keepitclean.business.data.cache

object CacheConstants {

const val CACHE_TIMEOUT = 2000L //time in millisecs

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.stvayush.keepitclean.business.data.cache


/** An object that contains cache error strings defined in it */
object CacheErrors {

const val CACHE_ERROR_UNKNOWN = "Unknown cache error "
const val CACHE_ERROR_ = "Cache error "

/** If a caching request takes more than the time defined in @param[CacheConstants]
* then it'll throw TLE/timeout
* */
const val CACHE_ERROR_TIMEOUT = "Cache timeout error "

/** If we search some data/note in the cache and isn't found then it'll return null */
const val CACHE_DATA_NULL = "Cache data null/ not found "

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.stvayush.keepitclean.business.data.cache

import com.stvayush.keepitclean.business.data.cache.CacheErrors.CACHE_DATA_NULL
import com.stvayush.keepitclean.business.domain.state.DataState
import com.stvayush.keepitclean.business.domain.state.StateEvent
import com.stvayush.keepitclean.business.domain.state.StateResource.MessageType
import com.stvayush.keepitclean.business.domain.state.StateResource.Response
import com.stvayush.keepitclean.business.domain.state.StateResource.UIComponentType

/** What this class does is that it takes two parameters as input- @code[cacheResultResponse] and @code[stateEvent]
* and now it has a function to handle and process the response obtained from the @param[CacheResult]
* which processes error and success accordingly and returns a nullable @code[DataState]
* which wraps around the @code[ViewState] (of which a ViewModel is capable of reading)
* also do note that the class @param[CacheResponseHandler] outputs the objects of type of @param[ViewState]
* */

abstract class CacheResponseHandler<ViewState, Data>(
private val cacheResultResponse: CacheResult<Data?>, /** CacheResultResponse is the output emitted from @param[CacheResult]*/
private val stateEvent: StateEvent?
) {
suspend fun getResult(): DataState<ViewState>? {
return when (cacheResultResponse) {
is CacheResult.GenericError -> {
DataState.error(
response = Response(
message = "${stateEvent?.errorInfo()}\n" +
" Reason: ${cacheResultResponse.errorMessage}",
uiComponentType = UIComponentType.Dialog(),
/** If you're confused nigga, then see StateResource */
messageType = MessageType.Error()
), stateEvent = stateEvent
)
}

is CacheResult.Success -> {
if (cacheResultResponse.value == null) {
DataState.error(
response = Response(
message = "${stateEvent?.errorInfo()}\n" +
" Reason: ${CACHE_DATA_NULL}",
uiComponentType = UIComponentType.Dialog(),
/** If you're confused nigga, then see StateResource */
messageType = MessageType.Error()
), stateEvent = stateEvent
)
} else {
handleSuccess(resultObject = cacheResultResponse.value)
}
}

}
}

abstract fun handleSuccess(resultObject: Data): DataState<ViewState>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.stvayush.keepitclean.business.data.cache

/** This'll be emitted when a CacheRequest is made as
* @code[Success] or as @code[GenericError] which will be parsed into
* @param[DataState](package com.stvayush.keepitclean.business.domain.state.datastate){i don't know why hyperlinking isn't working here}
* because dataState is something
* of which a viewModel is aware of
* */

sealed class CacheResult<out T> {

data class Success<out T>(val value: T) : CacheResult<T>()

data class GenericError(val errorMessage: String? = null) : CacheResult<Nothing>()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.stvayush.keepitclean.business.data.cache.abstraction

import com.stvayush.keepitclean.business.domain.model.Note

/** An abstract class between LocalDataSource and SQLite */
/** This contains of all the functions that'll be performed in the cache */

interface NoteCacheLayerDataSource {

/** This function will be used for inserting the note in the cache */
suspend fun insertNote(note: Note): Long

suspend fun deleteNote(primaryKey: String): Int
suspend fun deleteMultipleNotes(note: List<Note>): Int
suspend fun updateNote(
primaryKey: String,
newTitle: String,
newBody: String
): Int

suspend fun searchNotes(
query: String,
filterAndOrder: String,
page: Int
): List<Note>

suspend fun searchNoteById(primaryKey: String): Note?
suspend fun totalNotes(): Int

/** This function is solely made for testing purposes as we won't be adding a list of notes in the real app/use case */
suspend fun insertMultipleNotes(note: List<Note>): LongArray

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.stvayush.keepitclean.business.data.cache.implementation

import com.stvayush.keepitclean.business.data.cache.abstraction.NoteCacheLayerDataSource
import com.stvayush.keepitclean.business.domain.model.Note
import com.stvayush.keepitclean.framework.datasource.abstraction.NoteDaoService
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class NoteCacheLayerDataSourceImpl
@Inject
constructor(private val noteDaoService: NoteDaoService) : NoteCacheLayerDataSource {

override suspend fun insertNote(note: Note) = noteDaoService.insertNote(note)

override suspend fun deleteNote(primaryKey: String) = noteDaoService.deleteNote(primaryKey)

override suspend fun deleteMultipleNotes(note: List<Note>) =
noteDaoService.deleteMultipleNotes(note)

override suspend fun updateNote(
primaryKey: String,
newTitle: String,
newBody: String
) = noteDaoService.updateNote(primaryKey, newTitle, newBody)

override suspend fun searchNotes(
query: String,
filterAndOrder: String,
page: Int
) = noteDaoService.searchNotes(query, filterAndOrder, page)

override suspend fun searchNoteById(primaryKey: String) =
noteDaoService.searchNoteById(primaryKey)

override suspend fun totalNotes() = noteDaoService.totalNotes()

override suspend fun insertMultipleNotes(note: List<Note>) =
noteDaoService.insertMultipleNotes(note)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.stvayush.keepitclean.business.domain.state

import com.stvayush.keepitclean.business.domain.state.StateResource.StateMessage
import com.stvayush.keepitclean.business.domain.utils.printLogD
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.stvayush.keepitclean.business.domain.state

import com.stvayush.keepitclean.business.domain.state.StateResource.Response
import com.stvayush.keepitclean.business.domain.state.StateResource.StateMessage

/** Inspired by Resource.kt class from the googleSamples for android
* On receiving a response from the server, the class provides a callback
* that includes message, the involved stateEvent and the response(data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package com.stvayush.keepitclean.business.domain.state

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.stvayush.keepitclean.business.domain.state.StateResource.MessageType
import com.stvayush.keepitclean.business.domain.state.StateResource.Response
import com.stvayush.keepitclean.business.domain.state.StateResource.StateMessage
import com.stvayush.keepitclean.business.domain.state.StateResource.UIComponentType
import com.stvayush.keepitclean.business.domain.state.StateResource.UIComponentType.None
import com.stvayush.keepitclean.business.domain.utils.printLogD
import kotlinx.android.parcel.IgnoredOnParcel

Expand Down Expand Up @@ -62,7 +67,7 @@ class MessageStack : ArrayList<StateMessage>() {
return StateMessage( // this does nothing
Response(
message = "does nothing",
uiComponentType = UIComponentType.None(),
uiComponentType = None(),
messageType = MessageType.None()
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,35 @@ import com.stvayush.keepitclean.business.domain.utils.TodoCallback

/** A very wide utils class covering maximum ui common events */

data class StateMessage(val response: com.stvayush.keepitclean.business.domain.state.Response)
//remove this object qualifier if run into errors
object StateResource {
data class StateMessage(val response: Response)

data class Response(
data class Response(
val message: String?,
val uiComponentType: UIComponentType,
val messageType: MessageType
)
)

sealed class UIComponentType {
sealed class UIComponentType {

class Toast : UIComponentType()

class Dialog : UIComponentType()

class AreYouSureDialog(
val callback: AreYouSureCallback
val callback: AreYouSureCallback
) : UIComponentType()

class SnackBar(
val undoCallback: SnackbarUndoCallback? = null,
val onDismissCallback: TodoCallback? = null
val undoCallback: SnackbarUndoCallback? = null,
val onDismissCallback: TodoCallback? = null
) : UIComponentType()

class None : UIComponentType()
}
}

sealed class MessageType {
sealed class MessageType {

class Success : MessageType()

Expand All @@ -40,40 +42,38 @@ sealed class MessageType {
class Info : MessageType()

class None : MessageType()
}
}


interface StateMessageCallback {
interface StateMessageCallback {

fun removeMessageFromStack()
}

}

interface AreYouSureCallback {
interface AreYouSureCallback {

fun proceed()

fun cancel()
}
}

interface SnackbarUndoCallback {
interface SnackbarUndoCallback {

fun undo()
}
}

class SnackbarUndoListener
constructor(
class SnackbarUndoListener
constructor(
private val snackbarUndoCallback: SnackbarUndoCallback?
) : View.OnClickListener {
) : View.OnClickListener {

override fun onClick(v: View?) {
snackbarUndoCallback?.undo()
snackbarUndoCallback?.undo()
}

}

}

interface DialogInputCaptureCallback {
interface DialogInputCaptureCallback {

fun onTextCaptured(text: String)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.stvayush.keepitclean.framework.datasource.abstraction

import com.stvayush.keepitclean.business.domain.model.Note

/** I just copied it from the @param[NoteCacheLayerDataSource](com.stvayush.keepitclean.business.data.cache.abstraction.notecachelayer)!
* trust me!
* (Oops, i went a bit overboard, i'll be modifying this file a bit, it won't be the exact copy of @param[NoteCacheLayerDataSource]
* */

interface NoteDaoService {
/** This function will be used for inserting the note in the cache */
suspend fun insertNote(note: Note): Long

suspend fun deleteNote(primaryKey: String): Int
suspend fun deleteMultipleNotes(note: List<Note>): Int
suspend fun updateNote(
primaryKey: String,
newTitle: String,
newBody: String
): Int

/** Wait nigga, i'll be modifying this function later on,
* right now its already too much on the commit tree,
* so leaving as of now */
suspend fun searchNotes(
query: String,
filterAndOrder: String,
page: Int
): List<Note>

suspend fun searchNoteById(primaryKey: String): Note?
suspend fun totalNotes(): Int

/** This function is solely made for testing purposes as we won't be adding a list of notes in the real app/use case */
suspend fun insertMultipleNotes(note: List<Note>): LongArray

}