-
Notifications
You must be signed in to change notification settings - Fork 3
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 SQLDelight #22
Add SQLDelight #22
Conversation
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.
Still a draft and most comments are about naming stuff, feature-wise this is awesome Toni 💯
import android.content.SharedPreferences | ||
import java.util.Calendar | ||
|
||
actual class TimeProvider( |
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 find it really odd that a class called TimeProvider
stores anything. Provider usually means that its gets you something. I'd separate this class into two, TimeProvider
having a getCurrentTime
and timeAgo
methods and a TimeStorage
that can persist times.
} | ||
|
||
actual fun persistTime() { | ||
sharedPreferences.edit().apply { |
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.
Using apply
twice in the same method with such a different meaning hurts readability IMO. I'd use an preferences
variable even though it's like ~9 more characters 😝
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 the problem is duplicate names and readability, I'd use run
instead apply
👍
|
||
private fun timeAgo(): Long { | ||
val cal = Calendar.getInstance() | ||
cal.set(1969, Calendar.JULY, 21) |
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.
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.
🚀😉
} | ||
|
||
private fun insert(photos: PhotoShot) { | ||
photosQueries.transaction { |
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.
Do we need a transaction for a single insertion?
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 for the deletion below
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.
the number of insertions isn't related to the transaction right?, I mean if some other thread, try to insert in the same time, thanks to use transaction will be done in the right way if I am not wrong, it's not about things you are doing inside of a transaction is related to the possible calls from outside.
expect class TimeProvider { | ||
|
||
fun persistTime() | ||
fun getPersistedTime(): Long |
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.
When talking about time I'd either use stronger typing like Duration
or specify the unit in the name: getPersistedTimeInMs
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 couldn't use Duration
in kotlin native 🤔, but I can use it like getCurrentTime().toDuration(DurationUnit.MILLISECONDS)
Also instead to use getPersistedTimeInMs
it can be renamed to getPersistedTimestamp()
because It will be a Long
, except if you are working on python or swift xD
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.
Finally, I changed it with getPersistedTimeInMs
class LocalPhotosDataSource(private val cache: TTLCache) { | ||
|
||
fun insert(photos: Photos) { | ||
photos.map(::insert) |
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.
Not a map
but a forEach
photos.map(::insert) | |
photos.forEach(::insert) |
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.
😅
private suspend fun getPhotos(): Photos = | ||
if (localPhotosDataSource.isExpired()) { | ||
logInfo(TAG, "Getting from internet") | ||
photosApiClient.getPhotos().also { photos -> | ||
localPhotosDataSource.removeAll() | ||
localPhotosDataSource.insert(photos) | ||
} | ||
} else { | ||
logInfo(TAG, "Getting from local database") | ||
localPhotosDataSource.getPhotos() | ||
} |
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.
Great 👏
|
||
companion object { | ||
private const val TIME_ARG = "time_arg" | ||
private const val THREE_MONTHS_IN_MILLIS = 259200 |
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.
private const val THREE_MONTHS_IN_MILLIS = 259200 | |
private val THREE_MONTHS_IN_MILLIS = 90.days.toLongMilliseconds() |
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.
Now that the specific time is encoded into the value we can rename the variable to its actual meaning like TIME_IN_MS_TO_EXPIRE_DATA
or something like that
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 think either is fine, three months in millis is the number and time in ms to expire data is the purpose of that number.
But I forgot to use the kotlin.time
the approach I used for the TTLCache -.-, good catch 💪
private const val THREE_MONTHS_IN_MILLIS = 259200 | ||
} | ||
|
||
private val delegate: NSUserDefaults = NSUserDefaults.standardUserDefaults |
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.
Where does the delegate
name comes from? In iOS a delegate is just a listener and it doesn't look like we are using that pattern in here. What about just calling it userDefaults
?
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 know too much in iOS and I guess it was something that it's used in iOS development, I'll change it! 👍
val timeVal = alloc<timeval>() | ||
gettimeofday(timeVal.ptr, null) | ||
val sec = timeVal.tv_sec | ||
val usec = timeVal.tv_usec | ||
((sec * 1_000L) + (usec / 1_000L)) |
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.
Fancy 🤓
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 spent too much time to find how to get a long timestamp on swift, it returns Double -.- with NSDate.timeIntervalSince1970
🎩 What is the goal?
📝 How is it being implemented?
SharedPreferences
for Android andNSUserDefaults
for iOS to save time for cache.Android:
Create Android driver and share it with the injector to initialize dependencies.
IOS:
We need to create the iOS SQLite driver on Kotlin in the
iosMain
module on common lib, which will create this method only accessible by swift or ios module in common lib.Initialize the injector with the iOS driver like we made it on Android.
💥 How can it be tested?
On it, this is a draft