Browse Source

Convert AppDatabase to kotlin

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
54ff196bb1
  1. 3
      app/build.gradle
  2. 480
      app/src/main/java/awais/instagrabber/db/AppDatabase.kt
  3. 6
      app/src/main/java/awais/instagrabber/db/Converters.kt

3
app/build.gradle

@ -1,6 +1,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: "androidx.navigation.safeargs" apply plugin: "androidx.navigation.safeargs"
apply plugin: 'kotlin-kapt'
apply from: 'sentry.gradle' apply from: 'sentry.gradle'
def getGitHash = { -> def getGitHash = { ->
@ -146,6 +147,7 @@ android {
// Error: Duplicate files during packaging of APK // Error: Duplicate files during packaging of APK
exclude 'META-INF/LICENSE.md' exclude 'META-INF/LICENSE.md'
exclude 'META-INF/LICENSE-notice.md' exclude 'META-INF/LICENSE-notice.md'
exclude 'META-INF/atomicfu.kotlin_module'
} }
testOptions.unitTests { testOptions.unitTests {
@ -196,6 +198,7 @@ dependencies {
implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-guava:$room_version" implementation "androidx.room:room-guava:$room_version"
implementation "androidx.room:room-ktx:$room_version" implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version"
// CameraX // CameraX

480
app/src/main/java/awais/instagrabber/db/AppDatabase.kt

@ -1,270 +1,252 @@
package awais.instagrabber.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import awais.instagrabber.db.dao.AccountDao;
import awais.instagrabber.db.dao.DMLastNotifiedDao;
import awais.instagrabber.db.dao.FavoriteDao;
import awais.instagrabber.db.dao.RecentSearchDao;
import awais.instagrabber.db.entities.Account;
import awais.instagrabber.db.entities.DMLastNotified;
import awais.instagrabber.db.entities.Favorite;
import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.utils.Utils;
@Database(entities = {Account.class, Favorite.class, DMLastNotified.class, RecentSearch.class},
version = 6)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = AppDatabase.class.getSimpleName();
private static AppDatabase INSTANCE;
public abstract AccountDao accountDao();
public abstract FavoriteDao favoriteDao();
public abstract DMLastNotifiedDao dmLastNotifiedDao();
public abstract RecentSearchDao recentSearchDao();
public static AppDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "cookiebox.db")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6)
.build();
package awais.instagrabber.db
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import awais.instagrabber.db.dao.AccountDao
import awais.instagrabber.db.dao.DMLastNotifiedDao
import awais.instagrabber.db.dao.FavoriteDao
import awais.instagrabber.db.dao.RecentSearchDao
import awais.instagrabber.db.entities.Account
import awais.instagrabber.db.entities.DMLastNotified
import awais.instagrabber.db.entities.Favorite
import awais.instagrabber.db.entities.RecentSearch
import awais.instagrabber.utils.Utils
import awais.instagrabber.utils.extensions.TAG
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
@Database(entities = [Account::class, Favorite::class, DMLastNotified::class, RecentSearch::class], version = 6)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun accountDao(): AccountDao
abstract fun favoriteDao(): FavoriteDao
abstract fun dmLastNotifiedDao(): DMLastNotifiedDao
abstract fun recentSearchDao(): RecentSearchDao
companion object {
private lateinit var INSTANCE: AppDatabase
fun getDatabase(context: Context): AppDatabase {
if (!this::INSTANCE.isInitialized) {
synchronized(AppDatabase::class.java) {
if (!this::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "cookiebox.db")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6)
.build()
}
} }
} }
return INSTANCE
} }
return INSTANCE;
}
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_FULL_NAME + " TEXT");
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_PROFILE_PIC + " TEXT");
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_FULL_NAME + " TEXT")
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_PROFILE_PIC + " TEXT")
}
} }
};
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
final List<Favorite> oldFavorites = backupOldFavorites(db);
// recreate with new columns (as there will be no doubt about the `query_display` column being present or not in the future versions)
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME);
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + " ("
+ Favorite.COL_ID + " INTEGER PRIMARY KEY,"
+ Favorite.COL_QUERY + " TEXT,"
+ Favorite.COL_TYPE + " TEXT,"
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
+ Favorite.COL_PIC_URL + " TEXT,"
+ Favorite.COL_DATE_ADDED + " INTEGER)");
// add the old favorites back
for (final Favorite oldFavorite : oldFavorites) {
insertOrUpdateFavorite(db, oldFavorite);
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) {
val oldFavorites = backupOldFavorites(db)
// recreate with new columns (as there will be no doubt about the `query_display` column being present or not in the future versions)
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME)
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + " ("
+ Favorite.COL_ID + " INTEGER PRIMARY KEY,"
+ Favorite.COL_QUERY + " TEXT,"
+ Favorite.COL_TYPE + " TEXT,"
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
+ Favorite.COL_PIC_URL + " TEXT,"
+ Favorite.COL_DATE_ADDED + " INTEGER)")
// add the old favorites back
for (oldFavorite in oldFavorites) {
insertOrUpdateFavorite(db, oldFavorite)
}
} }
} }
};
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
// Required when migrating to Room.
// The original table primary keys were not 'NOT NULL', so the migration to Room were failing without the below migration.
// Taking this opportunity to rename cookies table to accounts
// Create new table with name 'accounts'
db.execSQL("CREATE TABLE " + Account.TABLE_NAME + " ("
+ Account.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ Account.COL_UID + " TEXT,"
+ Account.COL_USERNAME + " TEXT,"
+ Account.COL_COOKIE + " TEXT,"
+ Account.COL_FULL_NAME + " TEXT,"
+ Account.COL_PROFILE_PIC + " TEXT)");
// Insert all data from table 'cookies' to 'accounts'
db.execSQL("INSERT INTO " + Account.TABLE_NAME + " ("
+ Account.COL_UID + ","
+ Account.COL_USERNAME + ","
+ Account.COL_COOKIE + ","
+ Account.COL_FULL_NAME + ","
+ Account.COL_PROFILE_PIC + ") "
+ "SELECT "
+ Account.COL_UID + ","
+ Account.COL_USERNAME + ","
+ Account.COL_COOKIE + ","
+ Account.COL_FULL_NAME + ","
+ Account.COL_PROFILE_PIC
+ " FROM cookies");
// Drop old cookies table
db.execSQL("DROP TABLE cookies");
// Create favorite backup table
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + "_backup ("
+ Favorite.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ Favorite.COL_QUERY + " TEXT,"
+ Favorite.COL_TYPE + " TEXT,"
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
+ Favorite.COL_PIC_URL + " TEXT,"
+ Favorite.COL_DATE_ADDED + " INTEGER)");
// Insert all data from table 'favorite' to 'favorite_backup'
db.execSQL("INSERT INTO " + Favorite.TABLE_NAME + "_backup ("
+ Favorite.COL_QUERY + ","
+ Favorite.COL_TYPE + ","
+ Favorite.COL_DISPLAY_NAME + ","
+ Favorite.COL_PIC_URL + ","
+ Favorite.COL_DATE_ADDED + ") "
+ "SELECT "
+ Favorite.COL_QUERY + ","
+ Favorite.COL_TYPE + ","
+ Favorite.COL_DISPLAY_NAME + ","
+ Favorite.COL_PIC_URL + ","
+ Favorite.COL_DATE_ADDED
+ " FROM " + Favorite.TABLE_NAME);
// Drop favorites
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME);
// Rename favorite_backup to favorites
db.execSQL("ALTER TABLE " + Favorite.TABLE_NAME + "_backup RENAME TO " + Favorite.TABLE_NAME);
private val MIGRATION_3_4: Migration = object : Migration(3, 4) {
override fun migrate(db: SupportSQLiteDatabase) {
// Required when migrating to Room.
// The original table primary keys were not 'NOT NULL', so the migration to Room were failing without the below migration.
// Taking this opportunity to rename cookies table to accounts
// Create new table with name 'accounts'
db.execSQL("CREATE TABLE " + Account.TABLE_NAME + " ("
+ Account.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ Account.COL_UID + " TEXT,"
+ Account.COL_USERNAME + " TEXT,"
+ Account.COL_COOKIE + " TEXT,"
+ Account.COL_FULL_NAME + " TEXT,"
+ Account.COL_PROFILE_PIC + " TEXT)")
// Insert all data from table 'cookies' to 'accounts'
db.execSQL("INSERT INTO " + Account.TABLE_NAME + " ("
+ Account.COL_UID + ","
+ Account.COL_USERNAME + ","
+ Account.COL_COOKIE + ","
+ Account.COL_FULL_NAME + ","
+ Account.COL_PROFILE_PIC + ") "
+ "SELECT "
+ Account.COL_UID + ","
+ Account.COL_USERNAME + ","
+ Account.COL_COOKIE + ","
+ Account.COL_FULL_NAME + ","
+ Account.COL_PROFILE_PIC
+ " FROM cookies")
// Drop old cookies table
db.execSQL("DROP TABLE cookies")
// Create favorite backup table
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + "_backup ("
+ Favorite.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+ Favorite.COL_QUERY + " TEXT,"
+ Favorite.COL_TYPE + " TEXT,"
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
+ Favorite.COL_PIC_URL + " TEXT,"
+ Favorite.COL_DATE_ADDED + " INTEGER)")
// Insert all data from table 'favorite' to 'favorite_backup'
db.execSQL("INSERT INTO " + Favorite.TABLE_NAME + "_backup ("
+ Favorite.COL_QUERY + ","
+ Favorite.COL_TYPE + ","
+ Favorite.COL_DISPLAY_NAME + ","
+ Favorite.COL_PIC_URL + ","
+ Favorite.COL_DATE_ADDED + ") "
+ "SELECT "
+ Favorite.COL_QUERY + ","
+ Favorite.COL_TYPE + ","
+ Favorite.COL_DISPLAY_NAME + ","
+ Favorite.COL_PIC_URL + ","
+ Favorite.COL_DATE_ADDED
+ " FROM " + Favorite.TABLE_NAME)
// Drop favorites
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME)
// Rename favorite_backup to favorites
db.execSQL("ALTER TABLE " + Favorite.TABLE_NAME + "_backup RENAME TO " + Favorite.TABLE_NAME)
}
} }
};
static final Migration MIGRATION_4_5 = new Migration(4, 5) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `dm_last_notified` (" +
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`thread_id` TEXT, " +
"`last_notified_msg_ts` INTEGER, " +
"`last_notified_at` INTEGER)");
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_dm_last_notified_thread_id` ON `dm_last_notified` (`thread_id`)");
private val MIGRATION_4_5: Migration = object : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `dm_last_notified` (" +
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`thread_id` TEXT, " +
"`last_notified_msg_ts` INTEGER, " +
"`last_notified_at` INTEGER)")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_dm_last_notified_thread_id` ON `dm_last_notified` (`thread_id`)")
}
} }
};
static final Migration MIGRATION_5_6 = new Migration(5, 6) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `recent_searches` (" +
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`ig_id` TEXT NOT NULL, " +
"`name` TEXT NOT NULL, " +
"`username` TEXT, " +
"`pic_url` TEXT, " +
"`type` TEXT NOT NULL, " +
"`last_searched_on` INTEGER NOT NULL)");
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_recent_searches_ig_id_type` ON `recent_searches` (`ig_id`, `type`)");
private val MIGRATION_5_6: Migration = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `recent_searches` (" +
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`ig_id` TEXT NOT NULL, " +
"`name` TEXT NOT NULL, " +
"`username` TEXT, " +
"`pic_url` TEXT, " +
"`type` TEXT NOT NULL, " +
"`last_searched_on` INTEGER NOT NULL)")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_recent_searches_ig_id_type` ON `recent_searches` (`ig_id`, `type`)")
}
} }
};
@NonNull
private static List<Favorite> backupOldFavorites(@NonNull final SupportSQLiteDatabase db) {
// check if old favorites table had the column query_display
final boolean queryDisplayExists = checkColumnExists(db, Favorite.TABLE_NAME, "query_display");
Log.d(TAG, "backupOldFavorites: queryDisplayExists: " + queryDisplayExists);
final List<Favorite> oldModels = new ArrayList<>();
final String sql = "SELECT "
+ "query_text,"
+ "date_added"
+ (queryDisplayExists ? ",query_display" : "")
+ " FROM " + Favorite.TABLE_NAME;
try (final Cursor cursor = db.query(sql)) {
if (cursor != null && cursor.moveToFirst()) {
do {
try {
final String queryText = cursor.getString(cursor.getColumnIndex("query_text"));
final Pair<FavoriteType, String> favoriteTypeQueryPair = Utils.migrateOldFavQuery(queryText);
if (favoriteTypeQueryPair == null) continue;
final FavoriteType type = favoriteTypeQueryPair.first;
final String query = favoriteTypeQueryPair.second;
final long epochMillis = cursor.getLong(cursor.getColumnIndex("date_added"));
final LocalDateTime localDateTime = LocalDateTime.ofInstant(
Instant.ofEpochMilli(epochMillis),
ZoneId.systemDefault()
);
oldModels.add(new Favorite(
0,
query,
type,
queryDisplayExists ? cursor.getString(cursor.getColumnIndex("query_display")) : null,
null,
localDateTime
));
} catch (Exception e) {
Log.e(TAG, "onUpgrade", e);
private fun backupOldFavorites(db: SupportSQLiteDatabase): List<Favorite> {
// check if old favorites table had the column query_display
val queryDisplayExists = checkColumnExists(db, Favorite.TABLE_NAME, "query_display")
Log.d(TAG, "backupOldFavorites: queryDisplayExists: $queryDisplayExists")
val oldModels: MutableList<Favorite> = ArrayList()
val sql = ("SELECT "
+ "query_text,"
+ "date_added"
+ (if (queryDisplayExists) ",query_display" else "")
+ " FROM " + Favorite.TABLE_NAME)
try {
db.query(sql).use { cursor ->
if (cursor != null && cursor.moveToFirst()) {
do {
try {
val queryText = cursor.getString(cursor.getColumnIndex("query_text"))
val favoriteTypeQueryPair = Utils.migrateOldFavQuery(queryText) ?: continue
val type = favoriteTypeQueryPair.first
val query = favoriteTypeQueryPair.second
val epochMillis = cursor.getLong(cursor.getColumnIndex("date_added"))
val localDateTime = LocalDateTime.ofInstant(
Instant.ofEpochMilli(epochMillis),
ZoneId.systemDefault()
)
oldModels.add(Favorite(
0,
query,
type,
if (queryDisplayExists) cursor.getString(cursor.getColumnIndex("query_display")) else null,
null,
localDateTime
))
} catch (e: Exception) {
Log.e(TAG, "onUpgrade", e)
}
} while (cursor.moveToNext())
} }
} while (cursor.moveToNext());
}
} catch (e: Exception) {
Log.e(TAG, "onUpgrade", e)
} }
} catch (Exception e) {
Log.e(TAG, "onUpgrade", e);
Log.d(TAG, "backupOldFavorites: oldModels:$oldModels")
return oldModels
} }
Log.d(TAG, "backupOldFavorites: oldModels:" + oldModels);
return oldModels;
}
private static synchronized void insertOrUpdateFavorite(@NonNull final SupportSQLiteDatabase db, @NonNull final Favorite model) {
final ContentValues values = new ContentValues();
values.put(Favorite.COL_QUERY, model.getQuery());
values.put(Favorite.COL_TYPE, model.getType().toString());
values.put(Favorite.COL_DISPLAY_NAME, model.getDisplayName());
values.put(Favorite.COL_PIC_URL, model.getPicUrl());
values.put(Favorite.COL_DATE_ADDED, model.getDateAdded().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
int rows;
if (model.getId() >= 1) {
rows = db.update(Favorite.TABLE_NAME,
SQLiteDatabase.CONFLICT_IGNORE,
values,
Favorite.COL_ID + "=?",
new String[]{String.valueOf(model.getId())});
} else {
rows = db.update(Favorite.TABLE_NAME,
SQLiteDatabase.CONFLICT_IGNORE,
values,
Favorite.COL_QUERY + "=?" + " AND " + Favorite.COL_TYPE + "=?",
new String[]{model.getQuery(), model.getType().toString()});
}
if (rows != 1) {
db.insert(Favorite.TABLE_NAME, SQLiteDatabase.CONFLICT_IGNORE, values);
@Synchronized
private fun insertOrUpdateFavorite(db: SupportSQLiteDatabase, model: Favorite) {
val values = ContentValues()
values.put(Favorite.COL_QUERY, model.query)
values.put(Favorite.COL_TYPE, model.type.toString())
values.put(Favorite.COL_DISPLAY_NAME, model.displayName)
values.put(Favorite.COL_PIC_URL, model.picUrl)
values.put(Favorite.COL_DATE_ADDED, model.dateAdded!!.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
val rows: Int = if (model.id >= 1) {
db.update(Favorite.TABLE_NAME,
SQLiteDatabase.CONFLICT_IGNORE,
values,
Favorite.COL_ID + "=?", arrayOf(model.id.toString()))
} else {
db.update(Favorite.TABLE_NAME,
SQLiteDatabase.CONFLICT_IGNORE,
values,
Favorite.COL_QUERY + "=?" + " AND " + Favorite.COL_TYPE + "=?", arrayOf(model.query, model.type.toString()))
}
if (rows != 1) {
db.insert(Favorite.TABLE_NAME, SQLiteDatabase.CONFLICT_IGNORE, values)
}
} }
}
private static boolean checkColumnExists(@NonNull final SupportSQLiteDatabase db,
@NonNull final String tableName,
@NonNull final String columnName) {
boolean exists = false;
try (Cursor cursor = db.query("PRAGMA table_info(" + tableName + ")")) {
if (cursor.moveToFirst()) {
do {
final String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
if (currentColumn.equals(columnName)) {
exists = true;
@Suppress("SameParameterValue")
private fun checkColumnExists(
db: SupportSQLiteDatabase,
tableName: String,
columnName: String,
): Boolean {
var exists = false
try {
db.query("PRAGMA table_info($tableName)").use { cursor ->
if (cursor.moveToFirst()) {
do {
val currentColumn = cursor.getString(cursor.getColumnIndex("name"))
if (currentColumn == columnName) {
exists = true
}
} while (cursor.moveToNext())
} }
} while (cursor.moveToNext());
}
} catch (ex: Exception) {
Log.e(TAG, "checkColumnExists", ex)
} }
} catch (Exception ex) {
Log.e(TAG, "checkColumnExists", ex);
return exists
} }
return exists;
} }
}
}

6
app/src/main/java/awais/instagrabber/db/Converters.kt

@ -7,8 +7,7 @@ import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.ZoneOffset import java.time.ZoneOffset
object Converters {
@JvmStatic
class Converters {
@TypeConverter @TypeConverter
fun fromFavoriteTypeString(value: String?): FavoriteType? = fun fromFavoriteTypeString(value: String?): FavoriteType? =
if (value == null) null if (value == null) null
@ -18,16 +17,13 @@ object Converters {
null null
} }
@JvmStatic
@TypeConverter @TypeConverter
fun favoriteTypeToString(favoriteType: FavoriteType?): String? = favoriteType?.toString() fun favoriteTypeToString(favoriteType: FavoriteType?): String? = favoriteType?.toString()
@JvmStatic
@TypeConverter @TypeConverter
fun fromTimestampToLocalDateTime(value: Long?): LocalDateTime? = fun fromTimestampToLocalDateTime(value: Long?): LocalDateTime? =
if (value == null) null else LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.systemDefault()) if (value == null) null else LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.systemDefault())
@JvmStatic
@TypeConverter @TypeConverter
fun localDateTimeToTimestamp(localDateTime: LocalDateTime?): Long? = localDateTime?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli() fun localDateTimeToTimestamp(localDateTime: LocalDateTime?): Long? = localDateTime?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli()
} }
Loading…
Cancel
Save