[API/Mobidziennik] Fix getting grade added dates, colors and averages.

This commit is contained in:
Kuba Szczodrzyński 2020-02-19 22:59:32 +01:00
parent 0bb340e96e
commit 164cfbfd0d
4 changed files with 147 additions and 166 deletions

View File

@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik
import android.util.LongSparseArray
import androidx.core.util.isNotEmpty
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_MOBIDZIENNIK_WEB
@ -39,9 +38,9 @@ class DataMobidziennik(app: App, profile: Profile?, loginStore: LoginStore) : Da
val teachersMap = LongSparseArray<String>()
val subjectsMap = LongSparseArray<String>()
val gradeAddedDates = LongSparseArray<Long>()
val gradeAverages = LongSparseArray<Float>()
val gradeColors = LongSparseArray<Int>()
val gradeAddedDates = sortedMapOf<Long, Long>()
val gradeAverages = sortedMapOf<Long, Float>()
val gradeColors = sortedMapOf<Long, Int>()
private var mLoginServerName: String? = null
var loginServerName: String?

View File

@ -138,11 +138,10 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
gradeAddedDateMillis
))
}
} else {
data.gradeAverages.put(gradeId, gradeClassAverage)
data.gradeAddedDates.put(gradeId, gradeAddedDateMillis)
data.gradeColors.put(gradeId, gradeColor)
}
data.gradeAverages[gradeId] = gradeClassAverage
data.gradeAddedDates[gradeId] = gradeAddedDateMillis
data.gradeColors[gradeId] = gradeColor
}
}
}

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import android.util.LongSparseArray;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.room.Transaction;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_GRADE;
@Dao
public abstract class GradeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long add(Grade grade);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void addAll(List<Grade> gradeList);
@Query("DELETE FROM grades WHERE profileId = :profileId")
public abstract void clear(int profileId);
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeType = :type")
public abstract void clearWithType(int profileId, int type);
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester")
public abstract void clearForSemester(int profileId, int semester);
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester AND gradeType = :type")
public abstract void clearForSemesterWithType(int profileId, int semester, int type);
@RawQuery(observedEntities = {Grade.class})
abstract LiveData<List<GradeFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<GradeFull>> getAll(int profileId, String filter, String orderBy) {
return getAll(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + TYPE_GRADE + " AND metadata.profileId = "+profileId+"\n" +
"WHERE grades.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY "+orderBy)); // TODO: 2019-04-30 why did I add sorting by gradeType???
}
public LiveData<List<GradeFull>> getAllOrderBy(int profileId, String orderBy) {
return getAll(profileId, "1", orderBy);
}
public LiveData<List<GradeFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter, "addedDate DESC");
}
@RawQuery
abstract List<GradeFull> getAllNow(SupportSQLiteQuery query);
public List<GradeFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + TYPE_GRADE + " AND metadata.profileId = "+profileId+"\n" +
"WHERE grades.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public List<GradeFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
public List<GradeFull> getAllWithParentIdNow(int profileId, long parentId) {
return getAllNow(profileId, "gradeParentId = "+parentId);
}
@Query("SELECT * FROM grades " +
"LEFT JOIN subjects USING(profileId, subjectId) " +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + TYPE_GRADE + " AND metadata.profileId = grades.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
public abstract List<GradeFull> getNotNotifiedNow();
@RawQuery
abstract GradeFull getNow(SupportSQLiteQuery query);
public GradeFull getNow(int profileId, String filter) {
return getNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + TYPE_GRADE + " AND metadata.profileId = "+profileId+"\n" +
"WHERE grades.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public GradeFull getByIdNow(int profileId, long gradeId) {
return getNow(profileId, "gradeId = "+gradeId);
}
@Query("UPDATE grades SET gradeClassAverage = :classAverage, gradeColor = :color WHERE profileId = :profileId AND gradeId = :gradeId")
public abstract void updateDetailsById(int profileId, long gradeId, float classAverage, int color);
@Query("UPDATE metadata SET addedDate = :addedDate WHERE profileId = :profileId AND thingType = "+TYPE_GRADE+" AND thingId = :gradeId")
public abstract void updateAddedDateById(int profileId, long gradeId, long addedDate);
@Transaction
public void updateDetails(int profileId, LongSparseArray<Float> gradeAverages, LongSparseArray<Long> gradeAddedDates, LongSparseArray<Integer> gradeColors) {
for (int i = 0; i < gradeAverages.size(); i++) {
long gradeId = gradeAverages.keyAt(i);
float classAverage = gradeAverages.valueAt(i);
long addedDate = gradeAddedDates.valueAt(i);
int color = gradeColors.valueAt(i);
updateDetailsById(profileId, gradeId, classAverage, color);
updateAddedDateById(profileId, gradeId, addedDate);
}
}
@Query("SELECT gradeId FROM grades WHERE profileId = :profileId ORDER BY gradeId")
public abstract List<Integer> getIds(int profileId);
@Query("SELECT gradeClassAverage FROM grades WHERE profileId = :profileId ORDER BY gradeId")
public abstract List<Float> getClassAverages(int profileId);
@Query("SELECT gradeColor FROM grades WHERE profileId = :profileId ORDER BY gradeId")
public abstract List<Integer> getColors(int profileId);
@Query("SELECT addedDate FROM metadata WHERE profileId = :profileId AND thingType = "+TYPE_GRADE+" ORDER BY thingId")
public abstract List<Long> getAddedDates(int profileId);
@Transaction
public void getDetails(int profileId, LongSparseArray<Long> gradeAddedDates, LongSparseArray<Float> gradeAverages, LongSparseArray<Integer> gradeColors) {
List<Integer> ids = getIds(profileId);
List<Float> classAverages = getClassAverages(profileId);
List<Integer> colors = getColors(profileId);
List<Long> addedDates = getAddedDates(profileId);
for (int index = 0; index < ids.size(); index++) {
if (classAverages.size() > index) {
gradeAverages.put(ids.get(index), classAverages.get(index));
}
if (colors.size() > index) {
gradeColors.put(ids.get(index), colors.get(index));
}
if (addedDates.size() > index) {
gradeAddedDates.put(ids.get(index), addedDates.get(index));
}
}
}
public LiveData<List<GradeFull>> getAllFromDate(int profileId, long date) {
return getAllWhere(profileId, "addedDate > " + date);
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData
import androidx.room.*
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
import java.util.*
import kotlin.collections.List
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.iterator
import kotlin.collections.set
@Dao
abstract class GradeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun add(grade: Grade): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun addAll(gradeList: List<Grade>)
@Query("DELETE FROM grades WHERE profileId = :profileId")
abstract fun clear(profileId: Int)
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeType = :type")
abstract fun clearWithType(profileId: Int, type: Int)
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester")
abstract fun clearForSemester(profileId: Int, semester: Int)
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester AND gradeType = :type")
abstract fun clearForSemesterWithType(profileId: Int, semester: Int, type: Int)
@RawQuery(observedEntities = [Grade::class])
abstract fun getAll(query: SupportSQLiteQuery?): LiveData<List<GradeFull>>
fun getAll(profileId: Int, filter: String, orderBy: String): LiveData<List<GradeFull>> {
return getAll(SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = " + profileId + "\n" +
"WHERE grades.profileId = " + profileId + " AND " + filter + "\n" +
"ORDER BY " + orderBy)) // TODO: 2019-04-30 why did I add sorting by gradeType???
}
fun getAllOrderBy(profileId: Int, orderBy: String): LiveData<List<GradeFull>> {
return getAll(profileId, "1", orderBy)
}
fun getAllWhere(profileId: Int, filter: String): LiveData<List<GradeFull>> {
return getAll(profileId, filter, "addedDate DESC")
}
@RawQuery
abstract fun getAllNow(query: SupportSQLiteQuery?): List<GradeFull>
fun getAllNow(profileId: Int, filter: String): List<GradeFull> {
return getAllNow(SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = " + profileId + "\n" +
"WHERE grades.profileId = " + profileId + " AND " + filter + "\n" +
"ORDER BY addedDate DESC"))
}
fun getNotNotifiedNow(profileId: Int): List<GradeFull> {
return getAllNow(profileId, "notified = 0")
}
fun getAllWithParentIdNow(profileId: Int, parentId: Long): List<GradeFull> {
return getAllNow(profileId, "gradeParentId = $parentId")
}
@get:Query("SELECT * FROM grades " +
"LEFT JOIN subjects USING(profileId, subjectId) " +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = grades.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
abstract val notNotifiedNow: List<GradeFull>
@RawQuery
abstract fun getNow(query: SupportSQLiteQuery): GradeFull?
@Query("UPDATE grades SET gradeClassAverage = :classAverage, gradeColor = :color WHERE profileId = :profileId AND gradeId = :gradeId")
abstract fun updateDetailsById(profileId: Int, gradeId: Long, classAverage: Float, color: Int)
@Query("UPDATE metadata SET addedDate = :addedDate WHERE profileId = :profileId AND thingType = " + Metadata.TYPE_GRADE + " AND thingId = :gradeId")
abstract fun updateAddedDateById(profileId: Int, gradeId: Long, addedDate: Long)
@Transaction
open fun updateDetails(profileId: Int, gradeAverages: SortedMap<Long, Float>, gradeAddedDates: SortedMap<Long, Long>, gradeColors: SortedMap<Long, Int>) {
for ((gradeId, addedDate) in gradeAddedDates) {
val classAverage = gradeAverages[gradeId] ?: 0.0f
val color = gradeColors[gradeId] ?: 0xff2196f3.toInt()
updateDetailsById(profileId, gradeId, classAverage, color)
updateAddedDateById(profileId, gradeId, addedDate)
}
}
@Query("SELECT gradeId FROM grades WHERE profileId = :profileId ORDER BY gradeId")
abstract fun getIds(profileId: Int): List<Long>
@Query("SELECT gradeClassAverage FROM grades WHERE profileId = :profileId ORDER BY gradeId")
abstract fun getClassAverages(profileId: Int): List<Float>
@Query("SELECT gradeColor FROM grades WHERE profileId = :profileId ORDER BY gradeId")
abstract fun getColors(profileId: Int): List<Int>
@Query("SELECT addedDate FROM metadata WHERE profileId = :profileId AND thingType = " + Metadata.TYPE_GRADE + " ORDER BY thingId")
abstract fun getAddedDates(profileId: Int): List<Long>
@Transaction
open fun getDetails(profileId: Int, gradeAddedDates: SortedMap<Long, Long>, gradeAverages: SortedMap<Long, Float>, gradeColors: SortedMap<Long, Int>) {
val ids = getIds(profileId).iterator()
val classAverages = getClassAverages(profileId).iterator()
val colors = getColors(profileId).iterator()
val addedDates = getAddedDates(profileId).iterator()
while (ids.hasNext() && classAverages.hasNext() && colors.hasNext() && addedDates.hasNext()) {
val gradeId = ids.next()
gradeAverages[gradeId] = classAverages.next()
gradeColors[gradeId] = colors.next()
gradeAddedDates[gradeId] = addedDates.next()
}
}
fun getAllFromDate(profileId: Int, date: Long): LiveData<List<GradeFull>> {
return getAllWhere(profileId, "addedDate > $date")
}
}