diff --git a/app/build.gradle b/app/build.gradle index 135863562..4720ce4d7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -174,7 +174,7 @@ ext { } dependencies { - implementation "io.github.wulkanowy:sdk:1.4.4" + implementation "io.github.wulkanowy:sdk:42bce37748" coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json new file mode 100644 index 000000000..04518141c --- /dev/null +++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json @@ -0,0 +1,2430 @@ +{ + "formatVersion": 1, + "database": { + "version": 46, + "identityHash": "f310243440ca00cbc35e62ebaca5c7d8", + "entities": [ + { + "tableName": "Students", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "scrapperBaseUrl", + "columnName": "scrapper_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "mobileBaseUrl", + "columnName": "mobile_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginType", + "columnName": "login_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginMode", + "columnName": "login_mode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "certificateKey", + "columnName": "certificate_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "privateKey", + "columnName": "private_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isParent", + "columnName": "is_parent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userLoginId", + "columnName": "user_login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userName", + "columnName": "user_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentName", + "columnName": "student_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolSymbol", + "columnName": "school_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolShortName", + "columnName": "school_short", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolName", + "columnName": "school_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "className", + "columnName": "class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "registrationDate", + "columnName": "registration_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "nick", + "columnName": "nick", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatarColor", + "columnName": "avatar_color", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Students_email_symbol_student_id_school_id_class_id", + "unique": true, + "columnNames": [ + "email", + "symbol", + "student_id", + "school_id", + "class_id" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Semesters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryName", + "columnName": "diary_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolYear", + "columnName": "school_year", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterName", + "columnName": "semester_name", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "current", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Semesters_student_id_diary_id_semester_id", + "unique": true, + "columnNames": [ + "student_id", + "diary_id", + "semester_id" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Exams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Timetable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subjectOld", + "columnName": "subjectOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "room", + "columnName": "room", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roomOld", + "columnName": "roomOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherOld", + "columnName": "teacherOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "info", + "columnName": "info", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isStudentPlan", + "columnName": "student_plan", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "changes", + "columnName": "changes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canceled", + "columnName": "canceled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Attendance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timeId", + "columnName": "time_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excused", + "columnName": "excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excusable", + "columnName": "excusable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excuseStatus", + "columnName": "excuse_status", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AttendanceSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subjectId", + "columnName": "subject_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "month", + "columnName": "month", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceExcused", + "columnName": "absence_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceForSchoolReasons", + "columnName": "absence_for_school_reasons", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "latenessExcused", + "columnName": "lateness_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Grades", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "entry", + "columnName": "entry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "modifier", + "columnName": "modifier", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gradeSymbol", + "columnName": "grade_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weightValue", + "columnName": "weightValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "predictedGrade", + "columnName": "predicted_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalGrade", + "columnName": "final_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proposedPoints", + "columnName": "proposed_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalPoints", + "columnName": "final_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pointsSum", + "columnName": "points_sum", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "average", + "columnName": "average", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPredictedGradeNotified", + "columnName": "is_predicted_grade_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFinalGradeNotified", + "columnName": "is_final_grade_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "predictedGradeLastChange", + "columnName": "predicted_grade_last_change", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "finalGradeLastChange", + "columnName": "final_grade_last_change", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradePartialStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classAverage", + "columnName": "class_average", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentAverage", + "columnName": "student_average", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classAmounts", + "columnName": "class_amounts", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentAmounts", + "columnName": "student_amounts", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesPointsStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "others", + "columnName": "others", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "student", + "columnName": "student", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradeSemesterStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "amounts", + "columnName": "amounts", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentGrade", + "columnName": "student_grade", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageId", + "columnName": "message_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sender", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recipient", + "columnName": "recipient_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unread", + "columnName": "unread", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "removed", + "columnName": "removed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasAttachments", + "columnName": "has_attachments", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadBy", + "columnName": "unread_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readBy", + "columnName": "read_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MessageAttachments", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", + "fields": [ + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageId", + "columnName": "message_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "oneDriveId", + "columnName": "one_drive_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "filename", + "columnName": "filename", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "real_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "categoryType", + "columnName": "category_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPointsShow", + "columnName": "is_points_show", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Homework", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isDone", + "columnName": "is_done", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isAddedByUser", + "columnName": "is_added_by_user", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Subjects", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "LuckyNumbers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "luckyNumber", + "columnName": "lucky_number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "CompletedLesson", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topic", + "columnName": "topic", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "substitution", + "columnName": "substitution", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resources", + "columnName": "resources", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ReportingUnits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "senderName", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Recipients", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "realName", + "columnName": "real_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginId", + "columnName": "login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MobileDevices", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "userLoginId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deviceId", + "columnName": "device_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Teachers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "School", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contact", + "columnName": "contact", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headmaster", + "columnName": "headmaster", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pedagogue", + "columnName": "pedagogue", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Conferences", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "agenda", + "columnName": "agenda", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "presentOnConference", + "columnName": "present_on_conference", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "conferenceId", + "columnName": "conference_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "TimetableAdditional", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "repeatId", + "columnName": "repeat_id", + "affinity": "BLOB", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "isAddedByUser", + "columnName": "is_added_by_user", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "StudentInfo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fullName", + "columnName": "full_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "first_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "secondName", + "columnName": "second_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "surname", + "columnName": "surname", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "birthDate", + "columnName": "birth_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "birthPlace", + "columnName": "birth_place", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gender", + "columnName": "gender", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hasPolishCitizenship", + "columnName": "has_polish_citizenship", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "familyName", + "columnName": "family_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentsNames", + "columnName": "parents_names", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "registeredAddress", + "columnName": "registered_address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "correspondenceAddress", + "columnName": "correspondence_address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "phoneNumber", + "columnName": "phone_number", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cellPhoneNumber", + "columnName": "cell_phone_number", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "firstGuardian.fullName", + "columnName": "first_guardian_full_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstGuardian.kinship", + "columnName": "first_guardian_kinship", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstGuardian.address", + "columnName": "first_guardian_address", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstGuardian.phones", + "columnName": "first_guardian_phones", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstGuardian.email", + "columnName": "first_guardian_email", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "secondGuardian.fullName", + "columnName": "second_guardian_full_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "secondGuardian.kinship", + "columnName": "second_guardian_kinship", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "secondGuardian.address", + "columnName": "second_guardian_address", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "secondGuardian.phones", + "columnName": "second_guardian_phones", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "secondGuardian.email", + "columnName": "second_guardian_email", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "TimetableHeaders", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SchoolAnnouncements", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notifications", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AdminMessages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "versionMin", + "columnName": "version_name", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "versionMax", + "columnName": "version_max", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "targetRegisterHost", + "columnName": "target_register_host", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "targetFlavor", + "columnName": "target_flavor", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "destinationUrl", + "columnName": "destination_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "priority", + "columnName": "priority", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isDismissible", + "columnName": "is_dismissible", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f310243440ca00cbc35e62ebaca5c7d8')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index 6b4abb40d..2f4c74fbf 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -67,49 +67,7 @@ import io.github.wulkanowy.data.db.entities.Teacher import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.db.entities.TimetableAdditional import io.github.wulkanowy.data.db.entities.TimetableHeader -import io.github.wulkanowy.data.db.migrations.Migration10 -import io.github.wulkanowy.data.db.migrations.Migration11 -import io.github.wulkanowy.data.db.migrations.Migration12 -import io.github.wulkanowy.data.db.migrations.Migration13 -import io.github.wulkanowy.data.db.migrations.Migration14 -import io.github.wulkanowy.data.db.migrations.Migration15 -import io.github.wulkanowy.data.db.migrations.Migration16 -import io.github.wulkanowy.data.db.migrations.Migration17 -import io.github.wulkanowy.data.db.migrations.Migration18 -import io.github.wulkanowy.data.db.migrations.Migration19 -import io.github.wulkanowy.data.db.migrations.Migration2 -import io.github.wulkanowy.data.db.migrations.Migration20 -import io.github.wulkanowy.data.db.migrations.Migration21 -import io.github.wulkanowy.data.db.migrations.Migration22 -import io.github.wulkanowy.data.db.migrations.Migration23 -import io.github.wulkanowy.data.db.migrations.Migration24 -import io.github.wulkanowy.data.db.migrations.Migration25 -import io.github.wulkanowy.data.db.migrations.Migration26 -import io.github.wulkanowy.data.db.migrations.Migration27 -import io.github.wulkanowy.data.db.migrations.Migration28 -import io.github.wulkanowy.data.db.migrations.Migration29 -import io.github.wulkanowy.data.db.migrations.Migration3 -import io.github.wulkanowy.data.db.migrations.Migration30 -import io.github.wulkanowy.data.db.migrations.Migration31 -import io.github.wulkanowy.data.db.migrations.Migration32 -import io.github.wulkanowy.data.db.migrations.Migration33 -import io.github.wulkanowy.data.db.migrations.Migration34 -import io.github.wulkanowy.data.db.migrations.Migration35 -import io.github.wulkanowy.data.db.migrations.Migration36 -import io.github.wulkanowy.data.db.migrations.Migration37 -import io.github.wulkanowy.data.db.migrations.Migration38 -import io.github.wulkanowy.data.db.migrations.Migration39 -import io.github.wulkanowy.data.db.migrations.Migration4 -import io.github.wulkanowy.data.db.migrations.Migration40 -import io.github.wulkanowy.data.db.migrations.Migration41 -import io.github.wulkanowy.data.db.migrations.Migration42 -import io.github.wulkanowy.data.db.migrations.Migration43 -import io.github.wulkanowy.data.db.migrations.Migration44 -import io.github.wulkanowy.data.db.migrations.Migration5 -import io.github.wulkanowy.data.db.migrations.Migration6 -import io.github.wulkanowy.data.db.migrations.Migration7 -import io.github.wulkanowy.data.db.migrations.Migration8 -import io.github.wulkanowy.data.db.migrations.Migration9 +import io.github.wulkanowy.data.db.migrations.* import io.github.wulkanowy.utils.AppInfo import javax.inject.Singleton @@ -157,7 +115,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 45 + const val VERSION_SCHEMA = 46 fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf( Migration2(), @@ -203,6 +161,7 @@ abstract class AppDatabase : RoomDatabase() { Migration42(), Migration43(), Migration44(), + Migration46(), ) fun newInstance( diff --git a/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt b/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt index 1993c4338..b7013a32a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt @@ -1,40 +1,33 @@ package io.github.wulkanowy.data.db import androidx.room.TypeConverter +import io.github.wulkanowy.utils.toTimestamp import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.time.Instant import java.time.LocalDate -import java.time.LocalDateTime import java.time.Month import java.time.ZoneOffset -import java.util.Date +import java.util.* class Converters { private val json = Json @TypeConverter - fun timestampToDate(value: Long?): LocalDate? = value?.run { - Date(value).toInstant().atZone(ZoneOffset.UTC).toLocalDate() - } + fun timestampToLocalDate(value: Long?): LocalDate? = + value?.let(::Date)?.toInstant()?.atZone(ZoneOffset.UTC)?.toLocalDate() @TypeConverter - fun dateToTimestamp(date: LocalDate?): Long? { - return date?.atStartOfDay()?.toInstant(ZoneOffset.UTC)?.toEpochMilli() - } + fun dateToTimestamp(date: LocalDate?): Long? = date?.toTimestamp() @TypeConverter - fun timestampToTime(value: Long?): LocalDateTime? = value?.let { - LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC) - } + fun instantToTimestamp(instant: Instant?): Long? = instant?.toEpochMilli() @TypeConverter - fun timeToTimestamp(date: LocalDateTime?): Long? { - return date?.atZone(ZoneOffset.UTC)?.toInstant()?.toEpochMilli() - } + fun timestampToInstant(timestamp: Long?): Instant? = timestamp?.let(Instant::ofEpochMilli) @TypeConverter fun monthToInt(month: Month?) = month?.value diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt index e84bad592..ca9da9ea9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt @@ -4,7 +4,7 @@ import androidx.room.Dao import androidx.room.Query import io.github.wulkanowy.data.db.entities.Conference import kotlinx.coroutines.flow.Flow -import java.time.LocalDateTime +import java.time.Instant import javax.inject.Singleton @Dao @@ -12,5 +12,5 @@ import javax.inject.Singleton interface ConferenceDao : BaseDao { @Query("SELECT * FROM Conferences WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :startDate") - fun loadAll(diaryId: Int, studentId: Int, startDate: LocalDateTime): Flow> + fun loadAll(diaryId: Int, studentId: Int, startDate: Instant): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt index 4ad946508..ba3958dbc 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.LocalDateTime +import java.time.Instant @Entity(tableName = "Conferences") data class Conference( @@ -27,7 +27,7 @@ data class Conference( @ColumnInfo(name = "conference_id") val conferenceId: Int, - val date: LocalDateTime + val date: Instant, ) : Serializable { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt index fb7b60bbc..a42832ced 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt @@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.entities import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey -import java.time.LocalDateTime +import java.time.Instant @Entity(tableName = "GradesSummary") data class GradeSummary( @@ -45,8 +45,8 @@ data class GradeSummary( var isFinalGradeNotified: Boolean = true @ColumnInfo(name = "predicted_grade_last_change") - var predictedGradeLastChange: LocalDateTime = LocalDateTime.now() + var predictedGradeLastChange: Instant = Instant.now() @ColumnInfo(name = "final_grade_last_change") - var finalGradeLastChange: LocalDateTime = LocalDateTime.now() + var finalGradeLastChange: Instant = Instant.now() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt index 7b6e0dbf2..8782bc765 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.LocalDateTime +import java.time.Instant @Entity(tableName = "Messages") data class Message( @@ -29,7 +29,7 @@ data class Message( val subject: String, - val date: LocalDateTime, + val date: Instant, @ColumnInfo(name = "folder_id") val folderId: Int, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt index 83d82c0b9..887e43239 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.LocalDateTime +import java.time.Instant @Entity(tableName = "MobileDevices") data class MobileDevice( @@ -17,7 +17,7 @@ data class MobileDevice( val name: String, - val date: LocalDateTime + val date: Instant, ) : Serializable { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt index 740137f0f..4867e3329 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import io.github.wulkanowy.services.sync.notifications.NotificationType -import java.time.LocalDateTime +import java.time.Instant @Entity(tableName = "Notifications") data class Notification( @@ -18,7 +18,7 @@ data class Notification( val type: NotificationType, - val date: LocalDateTime, + val date: Instant, val data: String? = null ) { diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt index af9fe831a..76da9643d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt @@ -5,7 +5,7 @@ import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey import java.io.Serializable -import java.time.LocalDateTime +import java.time.Instant @Entity( tableName = "Students", @@ -74,7 +74,7 @@ data class Student( val isCurrent: Boolean, @ColumnInfo(name = "registration_date") - val registrationDate: LocalDateTime + val registrationDate: Instant, ) : Serializable { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt index 29b3737bc..d23d388f9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt @@ -4,8 +4,8 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable +import java.time.Instant import java.time.LocalDate -import java.time.LocalDateTime @Entity(tableName = "Timetable") data class Timetable( @@ -18,9 +18,9 @@ data class Timetable( val number: Int, - val start: LocalDateTime, + val start: Instant, - val end: LocalDateTime, + val end: Instant, val date: LocalDate, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt index db32de874..478026102 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt @@ -4,9 +4,9 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable +import java.time.Instant import java.time.LocalDate -import java.time.LocalDateTime -import java.util.UUID +import java.util.* @Entity(tableName = "TimetableAdditional") data class TimetableAdditional( @@ -17,9 +17,9 @@ data class TimetableAdditional( @ColumnInfo(name = "diary_id") val diaryId: Int, - val start: LocalDateTime, + val start: Instant, - val end: LocalDateTime, + val end: Instant, val date: LocalDate, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt index 1dc38e14c..c827b82ba 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt @@ -43,12 +43,14 @@ class Migration12 : Migration(11, 12) { private fun getStudentsIds(database: SupportSQLiteDatabase): List { val students = mutableListOf() - val studentsCursor = database.query("SELECT student_id FROM Students") - if (studentsCursor.moveToFirst()) { - do { - students.add(studentsCursor.getInt(0)) - } while (studentsCursor.moveToNext()) + database.query("SELECT student_id FROM Students").use { + if (it.moveToFirst()) { + do { + students.add(it.getInt(0)) + } while (it.moveToNext()) + } } + return students } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt index 0cf8cd9b0..36de1e837 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt @@ -25,12 +25,14 @@ class Migration13 : Migration(12, 13) { private fun getStudentsIds(database: SupportSQLiteDatabase): MutableList> { val students = mutableListOf>() - val studentsCursor = database.query("SELECT id, school_name FROM Students") - if (studentsCursor.moveToFirst()) { - do { - students.add(studentsCursor.getInt(0) to studentsCursor.getString(1)) - } while (studentsCursor.moveToNext()) + database.query("SELECT id, school_name FROM Students").use { + if (it.moveToFirst()) { + do { + students.add(it.getInt(0) to it.getString(1)) + } while (it.moveToNext()) + } } + return students } @@ -42,12 +44,14 @@ class Migration13 : Migration(12, 13) { private fun getStudentsAndClassIds(database: SupportSQLiteDatabase): List> { val students = mutableListOf>() - val studentsCursor = database.query("SELECT student_id, class_id FROM Students") - if (studentsCursor.moveToFirst()) { - do { - students.add(studentsCursor.getInt(0) to studentsCursor.getInt(1)) - } while (studentsCursor.moveToNext()) + database.query("SELECT student_id, class_id FROM Students").use { + if (it.moveToFirst()) { + do { + students.add(it.getInt(0) to it.getInt(1)) + } while (it.moveToNext()) + } } + return students } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt index 6592228a1..5c60beead 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt @@ -22,24 +22,28 @@ class Migration27 : Migration(26, 27) { private fun getStudentsIdsAndNames(database: SupportSQLiteDatabase): MutableList> { val students = mutableListOf>() - val studentsCursor = database.query("SELECT id, user_login_id, student_name FROM Students") - if (studentsCursor.moveToFirst()) { - do { - students.add(Triple(studentsCursor.getLong(0), studentsCursor.getInt(1), studentsCursor.getString(2))) - } while (studentsCursor.moveToNext()) + database.query("SELECT id, user_login_id, student_name FROM Students").use { + if (it.moveToFirst()) { + do { + students.add(Triple(it.getLong(0), it.getInt(1), it.getString(2))) + } while (it.moveToNext()) + } } + return students } private fun getReportingUnits(database: SupportSQLiteDatabase): MutableList> { val units = mutableListOf>() - val unitsCursor = database.query("SELECT sender_id, sender_name FROM ReportingUnits") - if (unitsCursor.moveToFirst()) { - do { - units.add(unitsCursor.getInt(0) to unitsCursor.getString(1)) - } while (unitsCursor.moveToNext()) + database.query("SELECT sender_id, sender_name FROM ReportingUnits").use { + if (it.moveToFirst()) { + do { + units.add(it.getInt(0) to it.getString(1)) + } while (it.moveToNext()) + } } + return units } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt index cc540388c..f63431d00 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt @@ -10,15 +10,17 @@ class Migration35(private val appInfo: AppInfo) : Migration(34, 35) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE Students ADD COLUMN `avatar_color` INTEGER NOT NULL DEFAULT 0") - val studentsCursor = database.query("SELECT * FROM Students") - - while (studentsCursor.moveToNext()) { - val studentId = studentsCursor.getLongOrNull(0) - database.execSQL( - """UPDATE Students - SET avatar_color = ${appInfo.defaultColorsForAvatar.random()} - WHERE id = $studentId""" - ) + database.query("SELECT * FROM Students").use { + while (it.moveToNext()) { + val studentId = it.getLongOrNull(0) + database.execSQL( + """ + UPDATE Students + SET avatar_color = ${appInfo.defaultColorsForAvatar.random()} + WHERE id = $studentId + """ + ) + } } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt new file mode 100644 index 000000000..d3fa5cf93 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt @@ -0,0 +1,102 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import java.time.Instant +import java.time.ZoneId +import java.time.ZoneOffset + +class Migration46 : Migration(45, 46) { + + override fun migrate(database: SupportSQLiteDatabase) { + migrateConferences(database) + migrateMessages(database) + migrateMobileDevices(database) + migrateNotifications(database) + migrateTimetable(database) + migrateTimetableAdditional(database) + } + + private fun migrateConferences(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM Conferences").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) + val timestampUtc = timestampLocal.timestampLocalToUTC() + + database.execSQL("UPDATE Conferences SET date = $timestampUtc WHERE id = $id") + } + } + } + + private fun migrateMessages(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM Messages").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) + val timestampUtc = timestampLocal.timestampLocalToUTC() + + database.execSQL("UPDATE Messages SET date = $timestampUtc WHERE id = $id") + } + } + } + + private fun migrateMobileDevices(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM MobileDevices").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) + val timestampUtc = timestampLocal.timestampLocalToUTC() + + database.execSQL("UPDATE MobileDevices SET date = $timestampUtc WHERE id = $id") + } + } + } + + private fun migrateNotifications(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM Notifications").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) + val timestampUtc = timestampLocal.timestampLocalToUTC() + + database.execSQL("UPDATE Notifications SET date = $timestampUtc WHERE id = $id") + } + } + } + + private fun migrateTimetable(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM Timetable").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) + val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end")) + val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() + val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() + + database.execSQL("UPDATE Timetable SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") + } + } + } + + private fun migrateTimetableAdditional(database: SupportSQLiteDatabase) { + database.query("SELECT * FROM TimetableAdditional").use { + while (it.moveToNext()) { + val id = it.getLong(it.getColumnIndexOrThrow("id")) + val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) + val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end")) + val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() + val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() + + database.execSQL("UPDATE TimetableAdditional SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") + } + } + } + + private fun Long.timestampLocalToUTC(): Long = Instant.ofEpochMilli(this) + .atZone(ZoneOffset.UTC) + .withZoneSameLocal(ZoneId.of("Europe/Warsaw")) + .withZoneSameInstant(ZoneId.systemDefault()) + .toInstant() + .toEpochMilli() +} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt index 52dc9b30b..17a9e5cdb 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt @@ -10,7 +10,7 @@ fun List.mapToEntities(semester: Semester) = map { diaryId = semester.diaryId, agenda = it.agenda, conferenceId = it.id, - date = it.date, + date = it.dateZoned.toInstant(), presentOnConference = it.presentOnConference, subject = it.subject, title = it.title diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt index 913e4d030..13f0ab33e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt @@ -4,7 +4,7 @@ import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.MessageAttachment import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Student -import java.time.LocalDateTime +import java.time.Instant import io.github.wulkanowy.sdk.pojo.Message as SdkMessage import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient @@ -18,7 +18,7 @@ fun List.mapToEntities(student: Student) = map { senderId = it.sender?.loginId ?: 0, recipient = it.recipients.singleOrNull()?.name ?: "Wielu adresatów", subject = it.subject.trim(), - date = it.date ?: LocalDateTime.now(), + date = it.dateZoned?.toInstant() ?: Instant.now(), folderId = it.folderId, unread = it.unread ?: false, removed = it.removed, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt index f0c375bfa..b1e96a27b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt @@ -3,13 +3,13 @@ package io.github.wulkanowy.data.mappers import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.pojos.MobileDeviceToken -import io.github.wulkanowy.sdk.pojo.Token as SdkToken import io.github.wulkanowy.sdk.pojo.Device as SdkDevice +import io.github.wulkanowy.sdk.pojo.Token as SdkToken fun List.mapToEntities(semester: Semester) = map { MobileDevice( userLoginId = semester.studentId, - date = it.createDate, + date = it.createDateZoned.toInstant(), deviceId = it.id, name = it.name ) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt index c93323038..a2110d7f5 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt @@ -2,7 +2,7 @@ package io.github.wulkanowy.data.mappers import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import java.time.LocalDateTime +import java.time.Instant import io.github.wulkanowy.sdk.pojo.Student as SdkStudent fun List.mapToEntities(password: String = "", colors: List) = map { @@ -24,7 +24,7 @@ fun List.mapToEntities(password: String = "", colors: List) = scrapperBaseUrl = it.scrapperBaseUrl, loginType = it.loginType.name, isCurrent = false, - registrationDate = LocalDateTime.now(), + registrationDate = Instant.now(), mobileBaseUrl = it.mobileBaseUrl, privateKey = it.privateKey, certificateKey = it.certificateKey, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt index 045101c42..e55aa3cf7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt @@ -21,8 +21,8 @@ fun List.mapToEntities(semester: Semester) = map { studentId = semester.studentId, diaryId = semester.diaryId, number = it.number, - start = it.start, - end = it.end, + start = it.startZoned.toInstant(), + end = it.endZoned.toInstant(), date = it.date, subject = it.subject, subjectOld = it.subjectOld, @@ -45,8 +45,8 @@ fun List.mapToEntities(semester: Semester) = map { diaryId = semester.diaryId, subject = it.subject, date = it.date, - start = it.start, - end = it.end + start = it.startZoned.toInstant(), + end = it.endZoned.toInstant(), ) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt index e32271833..a1667ccbc 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt @@ -6,16 +6,10 @@ import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.mappers.mapToEntities import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.init -import io.github.wulkanowy.utils.networkBoundResource -import io.github.wulkanowy.utils.uniqueSubtract +import io.github.wulkanowy.utils.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.sync.Mutex import java.time.Instant -import java.time.LocalDateTime -import java.time.ZoneOffset import javax.inject.Inject import javax.inject.Singleton @@ -35,7 +29,7 @@ class ConferenceRepository @Inject constructor( semester: Semester, forceRefresh: Boolean, notify: Boolean = false, - startDate: LocalDateTime = LocalDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC), + startDate: Instant = Instant.EPOCH, ) = networkBoundResource( mutex = saveFetchResultMutex, shouldFetch = { @@ -66,7 +60,7 @@ class ConferenceRepository @Inject constructor( conferenceDb.loadAll( diaryId = semester.diaryId, studentId = semester.studentId, - startDate = LocalDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC) + startDate = Instant.EPOCH, ) suspend fun updateConference(conference: List) = conferenceDb.updateAll(conference) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt index 6c574b48a..d539c14b9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt @@ -8,16 +8,12 @@ import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.mappers.mapToEntities import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.init -import io.github.wulkanowy.utils.networkBoundResource -import io.github.wulkanowy.utils.uniqueSubtract +import io.github.wulkanowy.utils.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.sync.Mutex -import java.time.LocalDateTime +import java.time.Instant import javax.inject.Inject import javax.inject.Singleton @@ -70,8 +66,8 @@ class GradeRepository @Inject constructor( newDetails: List, notify: Boolean ) { - val notifyBreakDate = oldGrades.maxByOrNull {it.date } - ?.date ?: student.registrationDate.toLocalDate() + val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date + ?: student.registrationDate.toLocalDate() gradeDb.deleteAll(oldGrades uniqueSubtract newDetails) gradeDb.insertAll((newDetails uniqueSubtract oldGrades).onEach { if (it.date >= notifyBreakDate) it.apply { @@ -101,13 +97,13 @@ class GradeRepository @Inject constructor( } summary.predictedGradeLastChange = when { - oldSummary == null -> LocalDateTime.now() - summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now() + oldSummary == null -> Instant.now() + summary.predictedGrade != oldSummary.predictedGrade -> Instant.now() else -> oldSummary.predictedGradeLastChange } summary.finalGradeLastChange = when { - oldSummary == null -> LocalDateTime.now() - summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now() + oldSummary == null -> Instant.now() + summary.finalGrade != oldSummary.finalGrade -> Instant.now() else -> oldSummary.finalGradeLastChange } }) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt index c1738b36e..121324d8b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt @@ -6,11 +6,7 @@ import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.mappers.mapToEntities import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.init -import io.github.wulkanowy.utils.networkBoundResource -import io.github.wulkanowy.utils.uniqueSubtract +import io.github.wulkanowy.utils.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.sync.Mutex import javax.inject.Inject diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt index e6437b167..4cd85586f 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt @@ -7,24 +7,16 @@ import com.fredporciuncula.flow.preferences.FlowSharedPreferences import com.fredporciuncula.flow.preferences.Preference import dagger.hilt.android.qualifiers.ApplicationContext import io.github.wulkanowy.R -import io.github.wulkanowy.data.enums.AppTheme -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.enums.GradeExpandMode -import io.github.wulkanowy.data.enums.GradeSortingMode -import io.github.wulkanowy.data.enums.TimetableMode -import io.github.wulkanowy.sdk.toLocalDate +import io.github.wulkanowy.data.enums.* import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import io.github.wulkanowy.ui.modules.grade.GradeAverageMode -import io.github.wulkanowy.utils.toLocalDateTime -import io.github.wulkanowy.utils.toTimestamp import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import java.time.LocalDate -import java.time.LocalDateTime +import java.time.Instant import javax.inject.Inject import javax.inject.Singleton @@ -208,10 +200,10 @@ class PreferencesRepository @Inject constructor( R.bool.pref_default_optional_arithmetic_average ) - var lasSyncDate: LocalDateTime + var lasSyncDate: Instant? get() = getLong(R.string.pref_key_last_sync_date, R.string.pref_default_last_sync_date) - .toLocalDateTime() - set(value) = sharedPref.edit().putLong("last_sync_date", value.toTimestamp()).apply() + .takeIf { it != 0L }?.let(Instant::ofEpochMilli) + set(value) = sharedPref.edit().putLong("last_sync_date", value?.toEpochMilli() ?: 0).apply() var dashboardItemsPosition: Map? get() { @@ -270,11 +262,12 @@ class PreferencesRepository @Inject constructor( get() = sharedPref.getInt(PREF_KEY_IN_APP_REVIEW_COUNT, 0) set(value) = sharedPref.edit().putInt(PREF_KEY_IN_APP_REVIEW_COUNT, value).apply() - var inAppReviewDate: LocalDate? + var inAppReviewDate: Instant? get() = sharedPref.getLong(PREF_KEY_IN_APP_REVIEW_DATE, 0).takeIf { it != 0L } - ?.toLocalDate() - set(value) = sharedPref.edit().putLong(PREF_KEY_IN_APP_REVIEW_DATE, value!!.toTimestamp()) - .apply() + ?.let(Instant::ofEpochMilli) + set(value) = sharedPref.edit { + putLong(PREF_KEY_IN_APP_REVIEW_DATE, value?.toEpochMilli() ?: 0) + } var isAppReviewDone: Boolean get() = sharedPref.getBoolean(PREF_KEY_IN_APP_REVIEW_DONE, false) diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt index b4786703a..c3ff1838e 100644 --- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt +++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt @@ -19,7 +19,6 @@ import io.github.wulkanowy.ui.modules.splash.SplashActivity import io.github.wulkanowy.utils.PendingIntentCompat import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.getCompatColor -import io.github.wulkanowy.utils.toLocalDateTime import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.launchIn @@ -95,7 +94,7 @@ class TimetableNotificationReceiver : BroadcastReceiver() { val nextSubject = intent.getStringExtra(LESSON_NEXT_TITLE) val nextRoom = intent.getStringExtra(LESSON_NEXT_ROOM) - Timber.d("TimetableNotification receive: type: $type, subject: $subject, start: ${start.toLocalDateTime()}, student: $studentId") + Timber.d("TimetableNotification receive: type: $type, subject: $subject, start: $start, student: $studentId") val notificationTitleResId = if (type == NOTIFICATION_TYPE_CURRENT) R.string.timetable_now else R.string.timetable_next diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt index dc9b8f1da..42078d03f 100644 --- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt @@ -28,12 +28,12 @@ import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companio import io.github.wulkanowy.utils.DispatchersProvider import io.github.wulkanowy.utils.PendingIntentCompat import io.github.wulkanowy.utils.nickOrName -import io.github.wulkanowy.utils.toTimestamp import kotlinx.coroutines.withContext import timber.log.Timber +import java.time.Duration.ofMinutes +import java.time.Instant +import java.time.Instant.now import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalDateTime.now import javax.inject.Inject class TimetableNotificationSchedulerHelper @Inject constructor( @@ -43,14 +43,14 @@ class TimetableNotificationSchedulerHelper @Inject constructor( private val dispatchersProvider: DispatchersProvider, ) { - private fun getRequestCode(time: LocalDateTime, studentId: Int) = - (time.toTimestamp() * studentId).toInt() + private fun getRequestCode(time: Instant, studentId: Int): Int = + (time.toEpochMilli() * studentId).toInt() private fun getUpcomingLessonTime( index: Int, day: List, lesson: Timetable - ) = day.getOrNull(index - 1)?.end ?: lesson.start.minusMinutes(30) + ): Instant = day.getOrNull(index - 1)?.end ?: lesson.start.minus(ofMinutes(30)) suspend fun cancelScheduled(lessons: List, student: Student) { val studentId = student.studentId @@ -71,7 +71,7 @@ class TimetableNotificationSchedulerHelper @Inject constructor( } } - private fun cancelScheduledTo(range: ClosedRange, requestCode: Int) { + private fun cancelScheduledTo(range: ClosedRange, requestCode: Int) { if (now() in range) cancelNotification() alarmManager.cancel( @@ -150,8 +150,8 @@ class TimetableNotificationSchedulerHelper @Inject constructor( putExtra(STUDENT_ID, student.studentId) putExtra(STUDENT_NAME, student.nickOrName) putExtra(LESSON_ROOM, lesson.room) - putExtra(LESSON_START, lesson.start.toTimestamp()) - putExtra(LESSON_END, lesson.end.toTimestamp()) + putExtra(LESSON_START, lesson.start.toEpochMilli()) + putExtra(LESSON_END, lesson.end.toEpochMilli()) putExtra(LESSON_TITLE, lesson.subject) putExtra(LESSON_NEXT_TITLE, nextLesson?.subject) putExtra(LESSON_NEXT_ROOM, nextLesson?.room) @@ -162,11 +162,11 @@ class TimetableNotificationSchedulerHelper @Inject constructor( intent: Intent, studentId: Int, notificationType: Int, - time: LocalDateTime + time: Instant ) { try { AlarmManagerCompat.setExactAndAllowWhileIdle( - alarmManager, RTC_WAKEUP, time.toTimestamp(), + alarmManager, RTC_WAKEUP, time.toEpochMilli(), PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also { it.putExtra(LESSON_TYPE, notificationType) }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE) diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt b/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt index 4a9bfd58d..5dddd9a78 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt @@ -23,7 +23,7 @@ import io.github.wulkanowy.utils.DispatchersProvider import io.github.wulkanowy.utils.getCompatColor import kotlinx.coroutines.withContext import timber.log.Timber -import java.time.LocalDateTime +import java.time.Instant import kotlin.random.Random @HiltWorker @@ -91,7 +91,7 @@ class SyncWorker @AssistedInject constructor( } errors.isNotEmpty() -> Result.retry() else -> { - preferencesRepository.lasSyncDate = LocalDateTime.now() + preferencesRepository.lasSyncDate = Instant.now() Result.success() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt index 6fd6c1602..7ac532aeb 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt @@ -18,7 +18,7 @@ import io.github.wulkanowy.utils.PendingIntentCompat import io.github.wulkanowy.utils.getCompatBitmap import io.github.wulkanowy.utils.getCompatColor import io.github.wulkanowy.utils.nickOrName -import java.time.LocalDateTime +import java.time.Instant import javax.inject.Inject import kotlin.random.Random @@ -169,7 +169,7 @@ class AppNotificationManager @Inject constructor( title = notificationData.title, content = notificationData.content, type = notificationType, - date = LocalDateTime.now() + date = Instant.now(), ) notificationRepository.saveNotification(notificationEntity) diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt index 7bfef96a4..b1f9a7b06 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt @@ -11,8 +11,8 @@ import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.splash.SplashActivity import io.github.wulkanowy.utils.getPlural import io.github.wulkanowy.utils.toFormattedString +import java.time.Instant import java.time.LocalDate -import java.time.LocalDateTime import javax.inject.Inject class ChangeTimetableNotification @Inject constructor( @@ -21,7 +21,7 @@ class ChangeTimetableNotification @Inject constructor( ) { suspend fun notify(items: List, student: Student) { - val currentTime = LocalDateTime.now() + val currentTime = Instant.now() val changedLessons = items.filter { (it.canceled || it.changes) && it.start > currentTime } val notificationDataList = changedLessons.groupBy { it.date } .map { (date, lessons) -> diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt index 8ef147886..d27c57285 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt @@ -11,7 +11,7 @@ import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.splash.SplashActivity import io.github.wulkanowy.utils.getPlural import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDateTime +import java.time.Instant import javax.inject.Inject class NewConferenceNotification @Inject constructor( @@ -20,7 +20,7 @@ class NewConferenceNotification @Inject constructor( ) { suspend fun notify(items: List, student: Student) { - val today = LocalDateTime.now() + val today = Instant.now() val lines = items.filter { !it.date.isBefore(today) } .map { "${it.date.toFormattedString("dd.MM")} - ${it.title}: ${it.subject}" diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt index 1bf5c7ad9..701656b55 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt @@ -13,13 +13,8 @@ import io.github.wulkanowy.ui.modules.about.license.LicenseFragment import io.github.wulkanowy.ui.modules.debug.DebugFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.getCompatDrawable -import io.github.wulkanowy.utils.openAppInMarket -import io.github.wulkanowy.utils.openEmailClient -import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.toFormattedString -import io.github.wulkanowy.utils.toLocalDateTime +import io.github.wulkanowy.utils.* +import java.time.Instant import javax.inject.Inject @AndroidEntryPoint @@ -38,7 +33,7 @@ class AboutFragment : BaseFragment(R.layout.fragment_about override val versionRes: Triple? get() = context?.run { val buildTimestamp = - appInfo.buildTimestamp.toLocalDateTime().toFormattedString("yyyy-MM-dd") + Instant.ofEpochMilli(appInfo.buildTimestamp).toFormattedString("yyyy-MM-dd") val versionSignature = "${appInfo.versionName}-${appInfo.buildFlavor} (${appInfo.versionCode}), $buildTimestamp" Triple( diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt index 12be144cd..3b6dc7298 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt @@ -37,9 +37,7 @@ import io.github.wulkanowy.utils.left import io.github.wulkanowy.utils.nickOrName import io.github.wulkanowy.utils.toFormattedString import timber.log.Timber -import java.time.Duration -import java.time.LocalDate -import java.time.LocalDateTime +import java.time.* import java.util.Timer import javax.inject.Inject import kotlin.concurrent.timer @@ -291,7 +289,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter= 50 && - LocalDate.now().minusDays(14).isAfter(prefRepository.inAppReviewDate) + Instant.now().minus(Duration.ofDays(14)).isAfter(prefRepository.inAppReviewDate) ) { view?.showInAppReview() prefRepository.isAppReviewDone = true diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt index fc47e29ab..1ecb4a6ef 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt @@ -79,9 +79,7 @@ class SyncPresenter @Inject constructor( } private fun setSyncDateInView() { - val lastSyncDate = preferencesRepository.lasSyncDate - - if (lastSyncDate.year == 1970) return + val lastSyncDate = preferencesRepository.lasSyncDate ?: return view?.setLastSyncDate(lastSyncDate.toFormattedString("dd.MM.yyyy HH:mm:ss")) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt index 422cc50e8..eacd12c69 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt @@ -15,15 +15,10 @@ import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.databinding.ItemTimetableBinding import io.github.wulkanowy.databinding.ItemTimetableSmallBinding -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.isJustFinished -import io.github.wulkanowy.utils.isShowTimeUntil -import io.github.wulkanowy.utils.left -import io.github.wulkanowy.utils.toFormattedString -import io.github.wulkanowy.utils.until +import io.github.wulkanowy.utils.* import timber.log.Timber -import java.time.LocalDateTime -import java.util.Timer +import java.time.Instant +import java.util.* import javax.inject.Inject import kotlin.concurrent.timer @@ -167,7 +162,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter i < position && !item.isStudentPlan }.size) ?.let { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt index 5bbaaa60f..c9243b12e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt @@ -16,7 +16,7 @@ import io.github.wulkanowy.utils.capitalise import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.lifecycleAwareVariable import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDateTime +import java.time.Instant class TimetableDialog : DialogFragment() { @@ -192,7 +192,7 @@ class TimetableDialog : DialogFragment() { } @SuppressLint("SetTextI18n") - private fun setTime(start: LocalDateTime, end: LocalDateTime) { + private fun setTime(start: Instant, end: Instant) { binding.timetableDialogTimeValue.text = "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}" } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt index 7bed5619e..c207165d3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt @@ -10,11 +10,9 @@ import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear import io.github.wulkanowy.utils.toLocalDate import kotlinx.coroutines.launch import timber.log.Timber -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime +import java.time.* import java.time.temporal.ChronoUnit -import java.util.UUID +import java.util.* import javax.inject.Inject class AdditionalLessonAddPresenter @Inject constructor( @@ -138,8 +136,8 @@ class AdditionalLessonAddPresenter @Inject constructor( TimetableAdditional( studentId = semester.studentId, diaryId = semester.diaryId, - start = LocalDateTime.of(date, start), - end = LocalDateTime.of(date, end), + start = ZonedDateTime.of(date, start, ZoneId.systemDefault()).toInstant(), + end = ZonedDateTime.of(date, end, ZoneId.systemDefault()).toInstant(), date = date.plusWeeks(it), subject = subject ).apply { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt index 411fa6625..18eefc5da 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt @@ -29,7 +29,6 @@ import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.runBlocking import timber.log.Timber import java.time.LocalDate -import java.time.ZoneOffset class TimetableWidgetFactory( private val timetableRepository: TimetableRepository, @@ -77,7 +76,7 @@ class TimetableWidgetFactory( if (date == LocalDate.now() && todayLastLessonEndTimestamp != null) { sharedPref.putLong( key = getTodayLastLessonEndDateTimeWidgetKey(appWidgetId), - value = todayLastLessonEndTimestamp.toEpochSecond(ZoneOffset.UTC), + value = todayLastLessonEndTimestamp.epochSecond, sync = true ) } diff --git a/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt index 14b5989b0..09ccda899 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt @@ -5,7 +5,6 @@ import com.google.android.material.datepicker.CalendarConstraints import com.google.android.material.datepicker.MaterialDatePicker import kotlinx.parcelize.Parcelize import java.time.LocalDate -import java.time.ZoneOffset import java.time.temporal.ChronoUnit fun Fragment.openMaterialDatePicker( @@ -16,17 +15,17 @@ fun Fragment.openMaterialDatePicker( ) { val constraintsBuilder = CalendarConstraints.Builder().apply { setValidator(CalendarDayRangeValidator(rangeStart, rangeEnd)) - setStart(rangeStart.toTimestamp(ZoneOffset.UTC)) - setEnd(rangeEnd.toTimestamp(ZoneOffset.UTC)) + setStart(rangeStart.toTimestamp()) + setEnd(rangeEnd.toTimestamp()) } val datePicker = MaterialDatePicker.Builder.datePicker() .setCalendarConstraints(constraintsBuilder.build()) - .setSelection(selected.toTimestamp(ZoneOffset.UTC)) + .setSelection(selected.toTimestamp()) .build() datePicker.addOnPositiveButtonClickListener { - val date = it.toLocalDateTime(ZoneOffset.UTC).toLocalDate() + val date = it.toLocalDateTime().toLocalDate() onDateSelected(date) } diff --git a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt index 6bf97bae7..c69fec65c 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt @@ -8,8 +8,9 @@ import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.enums.MessageFolder import timber.log.Timber +import java.time.Duration.ofMinutes +import java.time.Instant import java.time.LocalDate -import java.time.LocalDateTime import javax.inject.Inject fun getRefreshKey(name: String, semester: Semester, start: LocalDate, end: LocalDate): String { @@ -34,10 +35,10 @@ class AutoRefreshHelper @Inject constructor( ) { fun shouldBeRefreshed(key: String): Boolean { - val timestamp = sharedPref.getLong(key, 0).toLocalDateTime() + val timestamp = sharedPref.getLong(key, 0).let(Instant::ofEpochMilli) val servicesInterval = sharedPref.getString(context.getString(R.string.pref_key_services_interval), context.getString(R.string.pref_default_services_interval)).toLong() - val shouldBeRefreshed = timestamp < LocalDateTime.now().minusMinutes(servicesInterval) + val shouldBeRefreshed = timestamp < Instant.now().minus(ofMinutes(servicesInterval)) Timber.d("Check if $key need to be refreshed: $shouldBeRefreshed (last refresh: $timestamp, interval: $servicesInterval min)") @@ -45,6 +46,6 @@ class AutoRefreshHelper @Inject constructor( } fun updateLastRefreshTimestamp(key: String) { - sharedPref.putLong(key, LocalDateTime.now().toTimestamp()) + sharedPref.putLong(key, Instant.now().toEpochMilli()) } } diff --git a/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt index da5fd3dbb..71d3fd173 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt @@ -12,12 +12,17 @@ import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException import okhttp3.internal.http2.StreamResetException import java.io.InterruptedIOException import java.net.ConnectException +import java.net.SocketException import java.net.SocketTimeoutException import java.net.UnknownHostException fun Resources.getString(error: Throwable) = when (error) { is UnknownHostException -> getString(R.string.error_no_internet) - is SocketTimeoutException, is InterruptedIOException, is ConnectException, is StreamResetException -> getString(R.string.error_timeout) + is SocketException, + is SocketTimeoutException, + is InterruptedIOException, + is ConnectException, + is StreamResetException -> getString(R.string.error_timeout) is NotLoggedInException -> getString(R.string.error_login_failed) is PasswordChangeRequiredException -> getString(R.string.error_password_change_required) is ServiceUnavailableException -> getString(R.string.error_service_unavailable) diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt index 355f3ab49..e7a50d0c3 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt @@ -1,40 +1,34 @@ package io.github.wulkanowy.utils import java.text.SimpleDateFormat -import java.time.DayOfWeek.FRIDAY -import java.time.DayOfWeek.MONDAY -import java.time.DayOfWeek.SATURDAY -import java.time.DayOfWeek.SUNDAY -import java.time.Instant -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.Month -import java.time.ZoneId -import java.time.ZoneOffset +import java.time.* +import java.time.DayOfWeek.* import java.time.format.DateTimeFormatter -import java.time.temporal.TemporalAdjusters.firstInMonth -import java.time.temporal.TemporalAdjusters.next -import java.time.temporal.TemporalAdjusters.previous -import java.util.Locale +import java.time.temporal.TemporalAdjusters.* +import java.util.* private const val DEFAULT_DATE_PATTERN = "dd.MM.yyyy" +fun LocalDate.toTimestamp(): Long = atStartOfDay() + .toInstant(ZoneOffset.UTC) + .toEpochMilli() + +fun Long.toLocalDateTime(): LocalDateTime = LocalDateTime.ofInstant( + Instant.ofEpochMilli(this), ZoneOffset.UTC +) + +fun Instant.toLocalDate(): LocalDate = atZone(ZoneOffset.UTC).toLocalDate() + fun String.toLocalDate(format: String = DEFAULT_DATE_PATTERN): LocalDate = LocalDate.parse(this, DateTimeFormatter.ofPattern(format)) -fun LocalDateTime.toTimestamp(tz: ZoneId = ZoneId.systemDefault()) = - atZone(tz).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli() - -fun Long.toLocalDateTime(tz: ZoneId = ZoneId.systemDefault()): LocalDateTime = - LocalDateTime.ofInstant(Instant.ofEpochMilli(this), tz) - -fun LocalDate.toTimestamp(tz: ZoneId = ZoneId.systemDefault()) = atStartOfDay().toTimestamp(tz) - fun LocalDate.toFormattedString(pattern: String = DEFAULT_DATE_PATTERN): String = format(DateTimeFormatter.ofPattern(pattern)) -fun LocalDateTime.toFormattedString(pattern: String = DEFAULT_DATE_PATTERN): String = - format(DateTimeFormatter.ofPattern(pattern)) +fun Instant.toFormattedString( + pattern: String = DEFAULT_DATE_PATTERN, + tz: ZoneId = ZoneId.systemDefault() +): String = atZone(tz).format(DateTimeFormatter.ofPattern(pattern)) fun Month.getFormattedName(): String { val formatter = SimpleDateFormat("LLLL", Locale.getDefault()) diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt index 9d15216c6..3e94463b9 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt @@ -3,10 +3,10 @@ package io.github.wulkanowy.utils import io.github.wulkanowy.data.db.entities.Timetable import java.time.Duration import java.time.Duration.between -import java.time.LocalDateTime -import java.time.LocalDateTime.now +import java.time.Instant +import java.time.Instant.now -fun Timetable.isShowTimeUntil(previousLessonEnd: LocalDateTime?) = when { +fun Timetable.isShowTimeUntil(previousLessonEnd: Instant?) = when { !isStudentPlan -> false canceled -> false now().isAfter(start) -> false diff --git a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt index a0fa209fd..89ccade1b 100644 --- a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt +++ b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt @@ -4,7 +4,7 @@ import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.sdk.Sdk import java.time.LocalDate -import java.time.LocalDateTime.now +import java.time.Instant.now import io.github.wulkanowy.sdk.pojo.Semester as SdkSemester fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate = LocalDate.now(), end: LocalDate = LocalDate.now(), semesterName: Int = 1) = Semester( diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt index 2350da459..261a6c1cf 100644 --- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt +++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt @@ -153,23 +153,25 @@ class Migration13Test : AbstractMigrationTest() { private fun getSemesters(db: SupportSQLiteDatabase, query: String): List> { val semesters = mutableListOf>() - val cursor = db.query(query) - if (cursor.moveToFirst()) { - do { - semesters.add(Semester( - studentId = cursor.getInt(1), - diaryId = cursor.getInt(2), - diaryName = cursor.getString(3), - semesterId = cursor.getInt(4), - semesterName = cursor.getInt(5), - classId = cursor.getInt(7), - unitId = cursor.getInt(8), - schoolYear = cursor.getInt(9), - start = Converters().timestampToDate(cursor.getLong(10))!!, - end = Converters().timestampToDate(cursor.getLong(11))!! - ) to (cursor.getInt(6) == 1)) - } while (cursor.moveToNext()) + db.query(query).use { + if (it.moveToFirst()) { + do { + semesters.add(Semester( + studentId = it.getInt(1), + diaryId = it.getInt(2), + diaryName = it.getString(3), + semesterId = it.getInt(4), + semesterName = it.getInt(5), + classId = it.getInt(7), + unitId = it.getInt(8), + schoolYear = it.getInt(9), + start = Converters().timestampToLocalDate(it.getLong(10))!!, + end = Converters().timestampToLocalDate(it.getLong(11))!! + ) to (it.getInt(6) == 1)) + } while (it.moveToNext()) + } } + return semesters.toList() } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt index 6dd30a579..f7968bc41 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/GradeRepositoryTest.kt @@ -8,23 +8,17 @@ import io.github.wulkanowy.getStudentEntity import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.utils.AutoRefreshHelper import io.github.wulkanowy.utils.toFirstResult -import io.mockk.MockKAnnotations -import io.mockk.Runs -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.SpyK -import io.mockk.just import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue +import org.junit.Assert.* import org.junit.Before import org.junit.Test import java.time.LocalDate import java.time.LocalDate.of +import java.time.ZoneOffset import io.github.wulkanowy.sdk.pojo.Grade as SdkGrade class GradeRepositoryTest { @@ -57,7 +51,11 @@ class GradeRepositoryTest { coEvery { gradeDb.deleteAll(any()) } just Runs coEvery { gradeDb.insertAll(any()) } returns listOf() - coEvery { gradeSummaryDb.loadAll(1, 1) } returnsMany listOf(flowOf(listOf()), flowOf(listOf()), flowOf(listOf())) + coEvery { gradeSummaryDb.loadAll(1, 1) } returnsMany listOf( + flowOf(listOf()), + flowOf(listOf()), + flowOf(listOf()) + ) coEvery { gradeSummaryDb.deleteAll(any()) } just Runs coEvery { gradeSummaryDb.insertAll(any()) } returns listOf() } @@ -65,7 +63,7 @@ class GradeRepositoryTest { @Test fun `mark grades older than registration date as read`() { // prepare - val boundaryDate = of(2019, 2, 27).atStartOfDay() + val boundaryDate = of(2019, 2, 27).atStartOfDay().toInstant(ZoneOffset.UTC) val remoteList = listOf( createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"), createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"), @@ -81,7 +79,13 @@ class GradeRepositoryTest { ) // execute - val res = runBlocking { gradeRepository.getGrades(student.copy(registrationDate = boundaryDate), semester, true).toFirstResult() } + val res = runBlocking { + gradeRepository.getGrades( + student = student.copy(registrationDate = boundaryDate), + semester = semester, + forceRefresh = true + ).toFirstResult() + } // verify assertEquals(null, res.error) @@ -101,9 +105,19 @@ class GradeRepositoryTest { fun `mitigate mark grades as unread when old grades changed`() { // prepare val remoteList = listOf( - createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"), + createGradeApi( + 5, + 2.0, + of(2019, 2, 25), + "Ocena ma datę, jest inna, ale nie zostanie powiadomiona" + ), createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"), - createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"), + createGradeApi( + 3, + 4.0, + of(2019, 2, 27), + "Ta jest z tego samego dnia co ostatnia lokalnie" + ), createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa") ) coEvery { sdk.getGrades(1) } returns (remoteList to emptyList()) @@ -111,7 +125,12 @@ class GradeRepositoryTest { val localList = listOf( createGradeApi(5, 3.0, of(2019, 2, 25), "Jedna ocena"), createGradeApi(4, 4.0, of(2019, 2, 26), "Druga"), - createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie") + createGradeApi( + 3, + 4.0, + of(2019, 2, 27), + "Ta jest z tego samego dnia co ostatnia lokalnie" + ) ) coEvery { gradeDb.loadAll(1, 1) } returnsMany listOf( flowOf(localList.mapToEntities(semester)), @@ -248,18 +267,19 @@ class GradeRepositoryTest { assertEquals(0, res.data?.first?.size) } - private fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String) = SdkGrade( - subject = "", - color = "", - comment = "", - date = date, - description = desc, - entry = "", - modifier = .0, - symbol = "", - teacher = "", - value = value.toDouble(), - weight = weight.toString(), - weightValue = weight - ) + private fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String) = + SdkGrade( + subject = "", + color = "", + comment = "", + date = date, + description = desc, + entry = "", + modifier = .0, + symbol = "", + teacher = "", + value = value.toDouble(), + weight = weight.toString(), + weightValue = weight + ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt index 052f08f00..f21fc1780 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt @@ -16,27 +16,25 @@ import io.github.wulkanowy.sdk.pojo.MessageDetails import io.github.wulkanowy.sdk.pojo.Sender import io.github.wulkanowy.utils.AutoRefreshHelper import io.github.wulkanowy.utils.toFirstResult -import io.mockk.MockKAnnotations -import io.mockk.Runs -import io.mockk.checkEquals -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.SpyK -import io.mockk.just +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import java.net.UnknownHostException -import java.time.LocalDateTime +import java.time.Instant +import java.time.ZoneOffset import kotlin.test.assertTrue +@OptIn(ExperimentalCoroutinesApi::class) class MessageRepositoryTest { @SpyK @@ -80,7 +78,7 @@ class MessageRepositoryTest { } @Test - fun `get messages when read by values was changed on already read message`() = runBlocking { + fun `get messages when read by values was changed on already read message`() = runTest { every { messageDb.loadAll(any(), any()) } returns flow { val dbMessage = getMessageEntity(3, "", false).apply { unreadBy = 10 @@ -239,7 +237,7 @@ class MessageRepositoryTest { senderId = 0, recipient = "Wielu adresatów", subject = "", - date = LocalDateTime.MAX, + date = Instant.EPOCH, folderId = 1, unread = unread, removed = false, @@ -261,7 +259,8 @@ class MessageRepositoryTest { recipients = listOf(), subject = "", content = content, - date = LocalDateTime.MAX, + date = Instant.EPOCH.atZone(ZoneOffset.UTC).toLocalDateTime(), + dateZoned = Instant.EPOCH.atZone(ZoneOffset.UTC), folderId = 1, unread = unread, unreadBy = 0, diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt index 52a076d3c..c5a7756ff 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/MobileDeviceRepositoryTest.kt @@ -22,6 +22,7 @@ import org.junit.Assert import org.junit.Before import org.junit.Test import java.time.LocalDateTime.of +import java.time.ZoneId class MobileDeviceRepositoryTest { @@ -137,6 +138,8 @@ class MobileDeviceRepositoryTest { name = "", deviceId = "", createDate = of(2019, 5, day, 0, 0, 0), - modificationDate = of(2019, 5, day, 0, 0, 0) + modificationDate = of(2019, 5, day, 0, 0, 0), + createDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault()), + modificationDateZoned = of(2019, 5, day, 0, 0, 0).atZone(ZoneId.systemDefault()) ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt index edb3125eb..adb4f33a1 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/TimetableRepositoryTest.kt @@ -27,6 +27,7 @@ import org.junit.Test import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalDateTime.of +import java.time.ZoneId import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable class TimetableRepositoryTest { @@ -107,6 +108,8 @@ class TimetableRepositoryTest { number = number, start = start, end = start.plusMinutes(45), + startZoned = start.atZone(ZoneId.systemDefault()), + endZoned = start.plusMinutes(45).atZone(ZoneId.systemDefault()), date = start.toLocalDate(), subject = subject, group = "", diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt index ec07e149f..f097cb845 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt @@ -23,9 +23,9 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test +import java.time.Instant import java.time.LocalDate.now import java.time.LocalDate.of -import java.time.LocalDateTime class GradeAverageProviderTest { @@ -63,7 +63,7 @@ class GradeAverageProviderTest { className = "", classId = 1, isCurrent = true, - registrationDate = LocalDateTime.now() + registrationDate = Instant.now() ) private val semesters = mutableListOf( diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt index 67d3e6266..9bcfb8b6c 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt @@ -6,18 +6,13 @@ import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import io.mockk.MockKAnnotations -import io.mockk.Runs -import io.mockk.coEvery -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.just -import io.mockk.verify import org.junit.Before import org.junit.Rule import org.junit.Test import java.io.IOException -import java.time.LocalDateTime.now +import java.time.Instant class LoginFormPresenterTest { @@ -121,7 +116,7 @@ class LoginFormPresenterTest { classId = 1, isCurrent = false, symbol = "", - registrationDate = now(), + registrationDate = Instant.now(), className = "", mobileBaseUrl = "", privateKey = "", diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt index 1ec885904..e52ec3ae2 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt @@ -7,18 +7,12 @@ import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import io.mockk.MockKAnnotations -import io.mockk.Runs -import io.mockk.clearMocks -import io.mockk.coEvery -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.just -import io.mockk.verify import org.junit.Before import org.junit.Rule import org.junit.Test -import java.time.LocalDateTime.now +import java.time.Instant class LoginStudentSelectPresenterTest { @@ -55,7 +49,7 @@ class LoginStudentSelectPresenterTest { schoolSymbol = "", classId = 1, studentName = "", - registrationDate = now(), + registrationDate = Instant.now(), className = "", loginMode = "", certificateKey = "", diff --git a/app/src/test/java/io/github/wulkanowy/utils/TimeExtensionTest.kt b/app/src/test/java/io/github/wulkanowy/utils/TimeExtensionTest.kt index 9a3bf9fea..70ad6d534 100644 --- a/app/src/test/java/io/github/wulkanowy/utils/TimeExtensionTest.kt +++ b/app/src/test/java/io/github/wulkanowy/utils/TimeExtensionTest.kt @@ -1,14 +1,13 @@ package io.github.wulkanowy.utils -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue +import org.junit.Assert.* import org.junit.Test +import java.time.Instant import java.time.LocalDate.of import java.time.LocalDateTime import java.time.Month.JANUARY import java.time.ZoneOffset -import java.util.Locale +import java.util.* class TimeExtensionTest { @@ -24,11 +23,15 @@ class TimeExtensionTest { } @Test - fun toFormattedStringLocalDateTimeTest() { - assertEquals("01.10.2018", LocalDateTime.of(2018, 10, 1, 10, 0, 0).toFormattedString()) + fun toFormattedStringFromInstantTest() { + assertEquals( + "01.10.2018", + LocalDateTime.of(2018, 10, 1, 10, 0, 0).toInstant(ZoneOffset.UTC).toFormattedString() + ) assertEquals( "2018-10-01 10:00:00", - LocalDateTime.of(2018, 10, 1, 10, 0, 0).toFormattedString("uuuu-MM-dd HH:mm:ss") + LocalDateTime.of(2018, 10, 1, 10, 0, 0).toInstant(ZoneOffset.UTC) + .toFormattedString("uuuu-MM-dd HH:mm:ss", ZoneOffset.UTC) ) } @@ -228,16 +231,23 @@ class TimeExtensionTest { } @Test - fun getLocalDateToTimestampUTC() { - assertEquals(0L, of(1970, 1, 1).toTimestamp(ZoneOffset.UTC)) - assertEquals(946684800000L, of(2000, 1, 1).toTimestamp(ZoneOffset.UTC)) - assertEquals(1640131200000L, of(2021, 12, 22).toTimestamp(ZoneOffset.UTC)) + fun getLocalDateToTimestamp() { + assertEquals(0L, of(1970, 1, 1).toTimestamp()) + assertEquals(946684800000L, of(2000, 1, 1).toTimestamp()) + assertEquals(1640131200000L, of(2021, 12, 22).toTimestamp()) } @Test - fun getLocalDateTimeToUtcTimestamp() { - assertEquals(0L, LocalDateTime.of(1970, 1, 1, 0, 0, 0).toTimestamp(ZoneOffset.UTC)) - assertEquals(946684800000L, LocalDateTime.of(2000, 1, 1, 0, 0, 0).toTimestamp(ZoneOffset.UTC)) - assertEquals(1640131200000L, LocalDateTime.of(2021, 12, 22, 0, 0, 0).toTimestamp(ZoneOffset.UTC)) + fun getLocalDateFromInstant() { + assertEquals(of(1970, 1, 1), Instant.ofEpochMilli(0).toLocalDate()) + assertEquals(of(2000, 1, 1), Instant.ofEpochMilli(946684800000).toLocalDate()) + assertEquals(of(2021, 12, 22), Instant.ofEpochMilli(1640131200000L).toLocalDate()) + } + + @Test + fun timestampToLocalDateTime() { + assertEquals(LocalDateTime.of(1970, 1, 1, 0, 0, 0), 0L.toLocalDateTime()) + assertEquals(LocalDateTime.of(2000, 1, 1, 0, 0, 0), 946684800000.toLocalDateTime()) + assertEquals(LocalDateTime.of(2021, 12, 22, 0, 0, 0), 1640131200000L.toLocalDateTime()) } } diff --git a/app/src/test/java/io/github/wulkanowy/utils/TimetableExtensionTest.kt b/app/src/test/java/io/github/wulkanowy/utils/TimetableExtensionTest.kt index b7fa58c6f..a4d649e26 100644 --- a/app/src/test/java/io/github/wulkanowy/utils/TimetableExtensionTest.kt +++ b/app/src/test/java/io/github/wulkanowy/utils/TimetableExtensionTest.kt @@ -6,9 +6,8 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals import org.junit.Assert.assertTrue import org.junit.Test -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalDateTime.now +import java.time.* +import java.time.Duration.ofMinutes class TimetableExtensionTest { @@ -17,52 +16,38 @@ class TimetableExtensionTest { assertFalse(getTimetableEntity().isShowTimeUntil(null)) assertFalse(getTimetableEntity(isStudentPlan = false).isShowTimeUntil(null)) assertFalse(getTimetableEntity(isStudentPlan = true, canceled = true).isShowTimeUntil(null)) - assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().minusSeconds(1)).isShowTimeUntil(null)) - assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(5)).isShowTimeUntil(now().plusMinutes(5))) - assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(61)).isShowTimeUntil(now().minusMinutes(5))) + assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().minusSeconds(1)).isShowTimeUntil(null)) + assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().plus(ofMinutes(5))).isShowTimeUntil(Instant.now().plus(ofMinutes(5)))) + assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().plus(ofMinutes(61))).isShowTimeUntil(Instant.now().minus(ofMinutes(5)))) - assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(60)).isShowTimeUntil(now().minusMinutes(5))) - assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(60)).isShowTimeUntil(null)) + assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().plus(ofMinutes(60))).isShowTimeUntil(Instant.now().minus(ofMinutes(5)))) + assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().plus(ofMinutes(60))).isShowTimeUntil(null)) - assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().minusSeconds(1)).isShowTimeUntil(null)) + assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = Instant.now().minusSeconds(1)).isShowTimeUntil(null)) } @Test fun getLeft() { assertEquals(null, getTimetableEntity(canceled = true).left) - assertEquals(null, getTimetableEntity(start = now().plusMinutes(5), end = now().plusMinutes(50)).left) - assertEquals(null, getTimetableEntity(start = now().minusMinutes(1), end = now().plusMinutes(44), isStudentPlan = false).left) - assertNotEquals( - null, - getTimetableEntity( - start = now().minusMinutes(1), - end = now().plusMinutes(44), - isStudentPlan = true - ).left - ) - assertNotEquals( - null, - getTimetableEntity( - start = now(), - end = now().plusMinutes(45), - isStudentPlan = true - ).left - ) + assertEquals(null, getTimetableEntity(start = Instant.now().plus(ofMinutes(5)), end = Instant.now().plus(ofMinutes(50))).left) + assertEquals(null, getTimetableEntity(start = Instant.now().minus(ofMinutes(1)), end = Instant.now().plus(ofMinutes(44)), isStudentPlan = false).left) + assertNotEquals(null, getTimetableEntity(start = Instant.now().minus(ofMinutes(1)), end = Instant.now().plus(ofMinutes(44)), isStudentPlan = true).left) + assertNotEquals(null, getTimetableEntity(start = Instant.now(), end = Instant.now().plus(ofMinutes(45)), isStudentPlan = true).left) } @Test fun isJustFinished() { - assertFalse(getTimetableEntity(end = now().minusSeconds(16)).isJustFinished) - assertTrue(getTimetableEntity(end = now().minusSeconds(14)).isJustFinished) - assertTrue(getTimetableEntity(end = now().minusSeconds(1)).isJustFinished) - assertFalse(getTimetableEntity(end = now().plusSeconds(1)).isJustFinished) + assertFalse(getTimetableEntity(end = Instant.now().minusSeconds(16)).isJustFinished) + assertTrue(getTimetableEntity(end = Instant.now().minusSeconds(14)).isJustFinished) + assertTrue(getTimetableEntity(end = Instant.now().minusSeconds(1)).isJustFinished) + assertFalse(getTimetableEntity(end = Instant.now().plusSeconds(1)).isJustFinished) } private fun getTimetableEntity( isStudentPlan: Boolean = false, canceled: Boolean = false, - start: LocalDateTime = now(), - end: LocalDateTime = now() + start: Instant = Instant.now(), + end: Instant = Instant.now() ) = Timetable( studentId = 0, subject = "",