[LuckyNumber] Add lucky number metadata. Migrate Date field to int.

This commit is contained in:
Kuba Szczodrzyński 2019-10-18 08:46:55 +02:00
parent c03eca3804
commit 24ab2e7795
8 changed files with 161 additions and 36 deletions

View File

@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.api.v2.librus.ENDPOINT_LIBRUS_API_LUCKY_NUMBER
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApi import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.getInt import pl.szczodrzynski.edziennik.getInt
import pl.szczodrzynski.edziennik.getJsonObject import pl.szczodrzynski.edziennik.getJsonObject
import pl.szczodrzynski.edziennik.getString import pl.szczodrzynski.edziennik.getString
@ -21,23 +22,30 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
} }
init { init {
data.profile?.luckyNumber = -1
data.profile?.luckyNumberDate = null
apiGet(TAG, "LuckyNumbers") { json -> apiGet(TAG, "LuckyNumbers") { json ->
if (json.isJsonNull) { if (json.isJsonNull) {
profile?.luckyNumberEnabled = false //profile?.luckyNumberEnabled = false
} else { } else {
profile?.apply {
luckyNumber = -1
luckyNumberDate = Date.getToday()
json.getJsonObject("LuckyNumber")?.also { luckyNumberEl -> json.getJsonObject("LuckyNumber")?.also { luckyNumberEl ->
luckyNumber = luckyNumberEl.getInt("LuckyNumber") ?: -1
luckyNumberDate = Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay"))
}
data.luckyNumberList.add(LuckyNumber( val luckyNumberObject = LuckyNumber(
profileId, profileId,
luckyNumberDate ?: Date.getToday(), Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay")) ?: Date.getToday(),
luckyNumber luckyNumberEl.getInt("LuckyNumber") ?: -1
)
data.luckyNumberList.add(luckyNumberObject)
data.metadataList.add(
Metadata(
profileId,
Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(),
profile?.empty ?: false,
profile?.empty ?: false,
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -4,27 +4,37 @@
package pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.web package pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.web
import pl.szczodrzynski.edziennik.App.profileId
import pl.szczodrzynski.edziennik.api.v2.Regexes import pl.szczodrzynski.edziennik.api.v2.Regexes
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
class MobidziennikLuckyNumberExtractor(val data: DataMobidziennik, text: String) { class MobidziennikLuckyNumberExtractor(val data: DataMobidziennik, text: String) {
init { init {
data.profile?.luckyNumber = -1 data.profile?.luckyNumber = -1
data.profile?.luckyNumberDate = Date.getToday() data.profile?.luckyNumberDate = null
Regexes.MOBIDZIENNIK_LUCKY_NUMBER.find(text)?.let { Regexes.MOBIDZIENNIK_LUCKY_NUMBER.find(text)?.let {
try { try {
val luckyNumber = it.groupValues[1].toInt() val luckyNumber = it.groupValues[1].toInt()
data.profile?.luckyNumber = luckyNumber val luckyNumberObject = LuckyNumber(
data.profile?.luckyNumberDate = Date.getToday()
data.luckyNumberList.add(
LuckyNumber(
data.profileId, data.profileId,
Date.getToday(), Date.getToday(),
luckyNumber luckyNumber
)
data.luckyNumberList.add(luckyNumberObject)
data.metadataList.add(
Metadata(
profileId,
Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(),
data.profile?.empty ?: false,
data.profile?.empty ?: false,
System.currentTimeMillis()
)) ))
} catch (_: Exception){} } catch (_: Exception){}
} }

View File

@ -11,6 +11,7 @@ import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase; import androidx.sqlite.db.SupportSQLiteDatabase;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate; import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDateInt;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterJsonObject; import pl.szczodrzynski.edziennik.data.db.converters.ConverterJsonObject;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterListLong; import pl.szczodrzynski.edziennik.data.db.converters.ConverterListLong;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterListString; import pl.szczodrzynski.edziennik.data.db.converters.ConverterListString;
@ -87,13 +88,14 @@ import pl.szczodrzynski.edziennik.utils.models.Date;
DebugLog.class, DebugLog.class,
EndpointTimer.class, EndpointTimer.class,
LessonRange.class, LessonRange.class,
Metadata.class}, version = 58) Metadata.class}, version = 59)
@TypeConverters({ @TypeConverters({
ConverterTime.class, ConverterTime.class,
ConverterDate.class, ConverterDate.class,
ConverterJsonObject.class, ConverterJsonObject.class,
ConverterListLong.class, ConverterListLong.class,
ConverterListString.class}) ConverterListString.class,
ConverterDateInt.class})
public abstract class AppDb extends RoomDatabase { public abstract class AppDb extends RoomDatabase {
public abstract GradeDao gradeDao(); public abstract GradeDao gradeDao();
@ -616,6 +618,32 @@ public abstract class AppDb extends RoomDatabase {
database.execSQL("CREATE UNIQUE INDEX index_metadata_profileId_thingType_thingId ON metadata (profileId, thingType, thingId);"); database.execSQL("CREATE UNIQUE INDEX index_metadata_profileId_thingType_thingId ON metadata (profileId, thingType, thingId);");
} }
}; };
private static final Migration MIGRATION_58_59 = new Migration(58, 59) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("UPDATE metadata SET addedDate = addedDate*1000 WHERE addedDate < 10000000000;");
database.execSQL("INSERT INTO metadata (profileId, thingType, thingId, seen, notified, addedDate)\n" +
"SELECT profileId,\n" +
"10 AS thingType,\n" +
"luckyNumberDate*10000+substr(luckyNumberDate, 6)*100+substr(luckyNumberDate, 9) AS thingId,\n" +
"1 AS seen,\n" +
"1 AS notified,\n" +
"CAST(strftime('%s', luckyNumberDate) AS INT)*1000 AS addedDate\n" +
"FROM luckyNumbers;");
database.execSQL("ALTER TABLE luckyNumbers RENAME TO _old_luckyNumbers;");
database.execSQL("CREATE TABLE luckyNumbers (\n" +
"profileId INTEGER NOT NULL,\n" +
"luckyNumberDate INTEGER NOT NULL, \n" +
"luckyNumber INTEGER NOT NULL, \n" +
"PRIMARY KEY(profileId, luckyNumberDate))");
database.execSQL("INSERT INTO luckyNumbers (profileId, luckyNumberDate, luckyNumber)\n" +
"SELECT profileId,\n" +
"luckyNumberDate*10000+substr(luckyNumberDate, 6)*100+substr(luckyNumberDate, 9) AS luckyNumberDate,\n" +
"luckyNumber\n" +
"FROM _old_luckyNumbers;");
database.execSQL("DROP TABLE _old_luckyNumbers;");
}
};
public static AppDb getDatabase(final Context context) { public static AppDb getDatabase(final Context context) {
@ -671,7 +699,8 @@ public abstract class AppDb extends RoomDatabase {
MIGRATION_54_55, MIGRATION_54_55,
MIGRATION_55_56, MIGRATION_55_56,
MIGRATION_56_57, MIGRATION_56_57,
MIGRATION_57_58 MIGRATION_57_58,
MIGRATION_58_59
) )
.allowMainThreadQueries() .allowMainThreadQueries()
//.fallbackToDestructiveMigration() //.fallbackToDestructiveMigration()

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-10-17.
*/
package pl.szczodrzynski.edziennik.data.db.converters;
import androidx.room.TypeConverter;
import pl.szczodrzynski.edziennik.utils.models.Date;
public class ConverterDateInt {
@TypeConverter
public static Date toDate(int value) {
return Date.fromYmd(Integer.toString(value));
}
@TypeConverter
public static int toInt(Date value) {
return value == null ? 0 : value.getValue();
}
}

View File

@ -1,8 +1,9 @@
package pl.szczodrzynski.edziennik.data.db.modules.luckynumber; package pl.szczodrzynski.edziennik.data.db.modules.luckynumber;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo; import androidx.room.ColumnInfo;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.annotation.NonNull; import androidx.room.Ignore;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
@ -12,7 +13,7 @@ public class LuckyNumber {
public int profileId; public int profileId;
@NonNull @NonNull
@ColumnInfo(name = "luckyNumberDate") @ColumnInfo(name = "luckyNumberDate", typeAffinity = 3)
public Date date; public Date date;
@ColumnInfo(name = "luckyNumber") @ColumnInfo(name = "luckyNumber")
public int number; public int number;
@ -23,4 +24,8 @@ public class LuckyNumber {
this.number = number; this.number = number;
} }
@Ignore
public LuckyNumber() {
this.date = Date.getToday();
}
} }

View File

@ -1,35 +1,72 @@
package pl.szczodrzynski.edziennik.data.db.modules.luckynumber; package pl.szczodrzynski.edziennik.data.db.modules.luckynumber;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.OnConflictStrategy; import androidx.room.OnConflictStrategy;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List; import java.util.List;
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata;
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_LUCKY_NUMBER;
@Dao @Dao
public interface LuckyNumberDao { public abstract class LuckyNumberDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
void add(LuckyNumber luckyNumber); public abstract void add(LuckyNumber luckyNumber);
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
void addAll(List<LuckyNumber> luckyNumberList); public abstract void addAll(List<LuckyNumber> luckyNumberList);
@Query("DELETE FROM luckyNumbers WHERE profileId = :profileId") @Query("DELETE FROM luckyNumbers WHERE profileId = :profileId")
void clear(int profileId); public abstract void clear(int profileId);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date") @Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date")
LiveData<LuckyNumber> getByDate(int profileId, Date date); public abstract LiveData<LuckyNumber> getByDate(int profileId, Date date);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date") @Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date")
LuckyNumber getByDateNow(int profileId, Date date); public abstract LuckyNumber getByDateNow(int profileId, Date date);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId ORDER BY luckyNumberDate DESC") @Nullable
LiveData<List<LuckyNumber>> getAll(int profileId); @Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate > :date ORDER BY luckyNumberDate ASC LIMIT 1")
public abstract LuckyNumber getNearestFutureNow(int profileId, Date date);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId ORDER BY luckyNumberDate DESC") @RawQuery(observedEntities = {LuckyNumber.class})
List<LuckyNumber> getAllNow(int profileId); abstract LiveData<List<LuckyNumberFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<LuckyNumberFull>> getAll(int profileId, String filter) {
return getAll(new SimpleSQLiteQuery("SELECT\n" +
"*\n" +
"FROM luckyNumbers\n" +
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = "+profileId+"\n" +
"WHERE luckyNumbers.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public LiveData<List<LuckyNumberFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public LiveData<List<LuckyNumberFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
@RawQuery(observedEntities = {Notice.class, Metadata.class})
abstract List<LuckyNumberFull> getAllNow(SupportSQLiteQuery query);
public List<LuckyNumberFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT\n" +
"*\n" +
"FROM luckyNumbers\n" +
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = "+profileId+"\n" +
"WHERE luckyNumbers.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public List<LuckyNumberFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
} }

View File

@ -0,0 +1,13 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-10-18.
*/
package pl.szczodrzynski.edziennik.data.db.modules.luckynumber;
public class LuckyNumberFull extends LuckyNumber {
// metadata
public boolean seen;
public boolean notified;
public long addedDate;
}

View File

@ -19,6 +19,7 @@ public class Metadata {
public static final int TYPE_ANNOUNCEMENT = 7; public static final int TYPE_ANNOUNCEMENT = 7;
public static final int TYPE_MESSAGE = 8; public static final int TYPE_MESSAGE = 8;
public static final int TYPE_TEACHER_ABSENCE = 9; public static final int TYPE_TEACHER_ABSENCE = 9;
public static final int TYPE_LUCKY_NUMBER = 10;
public int profileId; public int profileId;