diff --git a/.travis.yml b/.travis.yml index 56c648589..b32619317 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,10 @@ cache: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ -#branches: -# only: -# - master -# - 0.7.x +branches: + only: + - master + - 0.7.x android: licenses: diff --git a/app/build.gradle b/app/build.gradle index 22af6e6bb..6b6a13018 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,7 +86,7 @@ play { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation('io.github.wulkanowy:api:0.7.4') { exclude module: "threetenbp" } + implementation('com.github.wulkanowy:api:383ff93') { exclude module: "threetenbp" } implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.appcompat:appcompat:1.0.2" diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/13.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/13.json new file mode 100644 index 000000000..ab554665e --- /dev/null +++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/13.json @@ -0,0 +1,1356 @@ +{ + "formatVersion": 1, + "database": { + "version": 13, + "identityHash": "18643bb64804b8268ec9395e3dd55ecb", + "entities": [ + { + "tableName": "Students", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `endpoint` TEXT NOT NULL, `loginType` TEXT NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `student_name` TEXT NOT NULL, `school_id` 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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endpoint", + "columnName": "endpoint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginType", + "columnName": "loginType", + "affinity": "TEXT", + "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": "studentName", + "columnName": "student_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolSymbol", + "columnName": "school_id", + "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 + } + ], + "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" + ], + "createSql": "CREATE UNIQUE INDEX `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}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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, `is_current` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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": "isCurrent", + "columnName": "is_current", + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Semesters_student_id_diary_id_semester_id", + "unique": true, + "columnNames": [ + "student_id", + "diary_id", + "semester_id" + ], + "createSql": "CREATE UNIQUE INDEX `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}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Timetable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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": "changes", + "columnName": "changes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canceled", + "columnName": "canceled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Attendance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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": "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AttendanceSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Grades", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` INTEGER 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)", + "fields": [ + { + "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 + }, + { + "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": "INTEGER", + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predictedGrade` TEXT NOT NULL, `finalGrade` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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": "predictedGrade", + "columnName": "predictedGrade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalGrade", + "columnName": "finalGrade", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `grade` INTEGER NOT NULL, `amount` INTEGER NOT NULL, `is_semester` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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": "grade", + "columnName": "grade", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semester", + "columnName": "is_semester", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT, `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, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `removed` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "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": "unreadBy", + "columnName": "unread_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readBy", + "columnName": "read_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "removed", + "columnName": "removed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `category` TEXT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "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 + }, + { + "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": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Homework", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Subjects", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "LuckyNumbers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "CompletedLesson", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ReportingUnits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Recipients", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "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 + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "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, \"18643bb64804b8268ec9395e3dd55ecb\")" + ] + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt new file mode 100644 index 000000000..507105f6d --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.Room +import androidx.room.testing.MigrationTestHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry +import io.github.wulkanowy.data.db.AppDatabase +import org.junit.Rule + +abstract class AbstractMigrationTest { + + val dbName = "migration-test" + + @get:Rule + val helper: MigrationTestHelper = MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + AppDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() + ) + + fun getMigratedRoomDatabase(): AppDatabase { + val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, dbName) + .addMigrations(Migration12(), Migration13()) + .build() + // close the database and release any stream resources when the test finishes + helper.closeWhenFinished(database) + return database + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt index c61e9305d..0bbcc4271 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt @@ -2,33 +2,17 @@ package io.github.wulkanowy.data.db.migrations import android.content.ContentValues import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL -import androidx.room.Room -import androidx.room.testing.MigrationTestHelper import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory -import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import io.github.wulkanowy.data.db.AppDatabase -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) -class Migration12Test { - - private val dbName = "migration-test" - - @get:Rule - val helper: MigrationTestHelper = MigrationTestHelper( - InstrumentationRegistry.getInstrumentation(), - AppDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory() - ) +class Migration12Test : AbstractMigrationTest() { @Test - fun migrate11To12_twoNotRelatedStudents() { + fun twoNotRelatedStudents() { helper.createDatabase(dbName, 11).apply { // user 1 createStudent(this, 1, true) @@ -61,7 +45,7 @@ class Migration12Test { } @Test - fun migrate11To12_removeStudentsWithoutClassId() { + fun removeStudentsWithoutClassId() { helper.createDatabase(dbName, 11).apply { // user 1 createStudent(this, 1, true) @@ -85,7 +69,7 @@ class Migration12Test { } @Test - fun migrate11To12_ensureThereIsOnlyOneCurrentStudent() { + fun ensureThereIsOnlyOneCurrentStudent() { helper.createDatabase(dbName, 11).apply { // user 1 createStudent(this, 1, true) @@ -146,14 +130,4 @@ class Migration12Test { put("unit_id", "99") }) } - - private fun getMigratedRoomDatabase(): AppDatabase { - val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(), - AppDatabase::class.java, dbName) - .addMigrations(Migration12()) - .build() - // close the database and release any stream resources when the test finishes - helper.closeWhenFinished(database) - return database - } } diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt new file mode 100644 index 000000000..eb9d02a59 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt @@ -0,0 +1,171 @@ +package io.github.wulkanowy.data.db.migrations + +import android.content.ContentValues +import android.database.sqlite.SQLiteDatabase +import androidx.sqlite.db.SupportSQLiteDatabase +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Test +import org.threeten.bp.LocalDate.of +import kotlin.test.assertTrue + +class Migration13Test : AbstractMigrationTest() { + + @Test + fun studentsWithSchoolNameWithClassName() { + helper.createDatabase(dbName, 12).apply { + createStudent(this, 1, "Klasa A - Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", 1, 1) + createStudent(this, 2, "Klasa B - Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", 2, 1) + createStudent(this, 2, "Klasa C - Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", 1, 2) + close() + } + + helper.runMigrationsAndValidate(dbName, 13, true, Migration13()) + + val db = getMigratedRoomDatabase() + val students = db.studentDao.loadAll().blockingGet() + + assertEquals(3, students.size) + + students[0].run { + assertEquals(1, studentId) + assertEquals("A", className) + assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", schoolName) + } + + students[1].run { + assertEquals(2, studentId) + assertEquals("B", className) + assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName) + } + + students[2].run { + assertEquals(2, studentId) + assertEquals("C", className) + assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName) + } + } + + @Test + fun studentsWithSchoolNameWithoutClassName() { + helper.createDatabase(dbName, 12).apply { + createStudent(this, 1, "Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", 1) + createStudent(this, 2, "Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", 1) + close() + } + + helper.runMigrationsAndValidate(dbName, 13, true, Migration13()) + + val db = getMigratedRoomDatabase() + val students = db.studentDao.loadAll().blockingGet() + + assertEquals(2, students.size) + + students[0].run { + assertEquals(1, studentId) + assertEquals("", className) + assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", schoolName) + } + + students[1].run { + assertEquals(2, studentId) + assertEquals("", className) + assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName) + } + } + + @Test + fun markAtLeastAndOnlyOneSemesterAtCurrent() { + helper.createDatabase(dbName, 12).apply { + createStudent(this, 1, "", 5) + createSemester(this, 1, 5, 1, 1, false) + createSemester(this, 1, 5, 2, 1, false) + createSemester(this, 1, 5, 3, 2, false) + createSemester(this, 1, 5, 4, 2, false) + + createStudent(this, 2, "", 5) + createSemester(this, 2, 5, 5, 5, true) + createSemester(this, 2, 5, 6, 5, true) + createSemester(this, 2, 5, 7, 55, true) + createSemester(this, 2, 5, 8, 55, true) + + createStudent(this, 3, "", 5) + createSemester(this, 3, 5, 11, 99, false) + createSemester(this, 3, 5, 12, 99, false) + createSemester(this, 3, 5, 13, 100, false) + createSemester(this, 3, 5, 14, 100, true) + close() + } + + helper.runMigrationsAndValidate(dbName, 13, true, Migration13()) + + val db = getMigratedRoomDatabase() + + val semesters1 = db.semesterDao.loadAll(1, 5).blockingGet() + assertTrue { semesters1.single { it.isCurrent }.isCurrent } + semesters1[0].run { + assertFalse(isCurrent) + assertEquals(1, semesterId) + assertEquals(1, diaryId) + } + semesters1[2].run { + assertFalse(isCurrent) + assertEquals(3, semesterId) + assertEquals(2, diaryId) + } + semesters1[3].run { + assertTrue(isCurrent) + assertEquals(4, semesterId) + assertEquals(2, diaryId) + } + + db.semesterDao.loadAll(2, 5).blockingGet().let { + assertTrue { it.single { it.isCurrent }.isCurrent } + assertEquals(1970, it[0].schoolYear) + assertEquals(of(1970, 1, 1), it[0].end) + assertEquals(of(1970, 1, 1), it[0].start) + assertFalse(it[0].isCurrent) + assertFalse(it[1].isCurrent) + assertFalse(it[2].isCurrent) + assertTrue(it[3].isCurrent) + } + + db.semesterDao.loadAll(2, 5).blockingGet().let { + assertTrue { it.single { it.isCurrent }.isCurrent } + assertFalse(it[0].isCurrent) + assertFalse(it[1].isCurrent) + assertFalse(it[2].isCurrent) + assertTrue(it[3].isCurrent) + } + } + + private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, schoolName: String = "", classId: Int = -1, schoolId: Int = 123) { + db.insert("Students", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { + put("endpoint", "https://fakelog.cf") + put("loginType", "STANDARD") + put("email", "jan@fakelog.cf") + put("password", "******") + put("symbol", "Default") + put("student_id", studentId) + put("class_id", classId) + put("student_name", "Jan Kowalski") + put("school_id", schoolId) + put("school_name", schoolName) + put("is_current", false) + put("registration_date", "0") + }) + } + + private fun createSemester(db: SupportSQLiteDatabase, studentId: Int, classId: Int, semesterId: Int, diaryId: Int, isCurrent: Boolean = false) { + db.insert("Semesters", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { + put("student_id", studentId) + put("diary_id", diaryId) + put("diary_name", "IA") + put("semester_id", semesterId) + put("semester_name", "1") + put("is_current", isCurrent) + put("class_id", classId) + put("unit_id", "99") + }) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt index ee65cf844..69502e742 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt @@ -11,6 +11,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.threeten.bp.LocalDate +import org.threeten.bp.LocalDate.now import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) @@ -40,7 +41,7 @@ class AttendanceLocalTest { )) val attendance = attendanceLocal - .getAttendance(Semester(1, 2, "", 1, 3, true, 1, 1), + .getAttendance(Semester(1, 2, "", 1, 3, 2019, true, now(), now(), 1, 1), LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 14) ) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt index 014f0b8bc..356073e8e 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt @@ -41,7 +41,7 @@ class CompletedLessonsLocalTest { )) val completed = completedLessonsLocal - .getCompletedLessons(Semester(1, 2, "", 1, 3, true, 1, 1), + .getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1), LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 14) ) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt index dc66fa428..fb76306d9 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt @@ -40,7 +40,7 @@ class ExamLocalTest { )) val exams = examLocal - .getExams(Semester(1, 2, "", 1, 3, true, 1, 1), + .getExams(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1), LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 14) ) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt index 36238f1b4..954d0eea2 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt @@ -10,6 +10,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.threeten.bp.LocalDate +import org.threeten.bp.LocalDate.now import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) @@ -39,8 +40,10 @@ class GradeLocalTest { createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2) )) + val semester = Semester(1, 2, "", 2019, 2, 1, true, now(), now(), 1, 1) + val grades = gradeLocal - .getGrades(Semester(1, 2, "", 2, 3, true, 1, 1)) + .getGrades(semester) .blockingGet() assertEquals(2, grades.size) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt index 5c0590e75..0057a26e5 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt @@ -10,6 +10,7 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.threeten.bp.LocalDate import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) @@ -39,7 +40,7 @@ class GradeStatisticsLocalTest { )) val stats = gradeStatisticsLocal.getGradesStatistics( - Semester(2, 2, "", 1, 2, true, 1, 1), false, + Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false, "Matematyka" ).blockingGet() assertEquals(1, stats.size) @@ -55,7 +56,7 @@ class GradeStatisticsLocalTest { )) val stats = gradeStatisticsLocal.getGradesStatistics( - Semester(2, 2, "", 1, 2, true, 1, 1), false, + Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false, "Wszystkie" ).blockingGet() assertEquals(1, stats.size) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt index a656ac058..77ddafb9c 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt @@ -36,7 +36,7 @@ class LuckyNumberLocalTest { fun saveAndReadTest() { luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14)) - val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, true, 1, 1), + val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1), LocalDate.of(2019, 1, 20) ).blockingGet() diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt index cc4dd9f31..6edaccdb4 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt @@ -42,7 +42,7 @@ class RecipientLocalTest { )) val recipients = recipientLocal.getRecipients( - Student("fakelog.cf", "AUTO", "", "", "", 1, "", "", "", 1, true, LocalDateTime.now()), + Student("fakelog.cf", "AUTO", "", "", "", 1, "", "", "", "", 1, true, LocalDateTime.now()), 2, ReportingUnit(1, 4, "", 0, "", emptyList()) ).blockingGet() diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt index f61c63742..b27446faf 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt @@ -39,7 +39,7 @@ class StudentLocalTest { @Test fun saveAndReadTest() { - studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now())) + studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = "")) .blockingGet() val student = studentLocal.getCurrentStudent(true).blockingGet() diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt index 0ecbcf92e..fe25e4e96 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt @@ -41,7 +41,7 @@ class TimetableLocalTest { )) val exams = timetableDb.getTimetable( - Semester(1, 2, "", 1, 1, true, 1, 1), + Semester(1, 2, "", 1, 1, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1), LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 14) ).blockingGet() 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 9ce62b187..d867583e4 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 @@ -43,6 +43,7 @@ import io.github.wulkanowy.data.db.entities.Timetable 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.Migration2 import io.github.wulkanowy.data.db.migrations.Migration3 import io.github.wulkanowy.data.db.migrations.Migration4 @@ -81,7 +82,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 12 + const val VERSION_SCHEMA = 13 fun newInstance(context: Context): AppDatabase { return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") @@ -99,7 +100,8 @@ abstract class AppDatabase : RoomDatabase() { Migration9(), Migration10(), Migration11(), - Migration12() + Migration12(), + Migration13() ) .build() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt index 0f44fa2d9..6c06be111 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt @@ -4,6 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey +import org.threeten.bp.LocalDate @Entity(tableName = "Semesters", indices = [Index(value = ["student_id", "diary_id", "semester_id"], unique = true)]) data class Semester( @@ -17,6 +18,9 @@ data class Semester( @ColumnInfo(name = "diary_name") val diaryName: String, + @ColumnInfo(name = "school_year") + val schoolYear: Int, + @ColumnInfo(name = "semester_id") val semesterId: Int, @@ -26,6 +30,10 @@ data class Semester( @ColumnInfo(name = "is_current") val isCurrent: Boolean, + val start: LocalDate, + + val end: LocalDate, + @ColumnInfo(name = "class_id") val classId: Int, 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 9cacf8358..13c5ee084 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 @@ -32,6 +32,9 @@ data class Student( @ColumnInfo(name = "school_name") val schoolName: String, + @ColumnInfo(name = "class_name") + val className: String, + @ColumnInfo(name = "class_id") val classId: Int, 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 new file mode 100644 index 000000000..83ab8609a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt @@ -0,0 +1,59 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration13 : Migration(12, 13) { + + override fun migrate(database: SupportSQLiteDatabase) { + addClassNameToStudents(database, getStudentsIds(database)) + updateSemestersTable(database) + markAtLeastAndOnlyOneSemesterAtCurrent(database, getStudentsAndClassIds(database)) + } + + private fun addClassNameToStudents(database: SupportSQLiteDatabase, students: List>) { + database.execSQL("ALTER TABLE Students ADD COLUMN class_name TEXT DEFAULT \"\" NOT NULL") + + students.forEach { (id, name) -> + val schoolName = name.substringAfter(" - ") + val className = name.substringBefore(" - ", "").replace("Klasa ", "") + database.execSQL("UPDATE Students SET class_name = '$className' WHERE id = '$id'") + database.execSQL("UPDATE Students SET school_name = '$schoolName' WHERE id = '$id'") + } + } + + 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()) + } + return students + } + + private fun updateSemestersTable(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Semesters ADD COLUMN school_year INTEGER DEFAULT 1970 NOT NULL") + database.execSQL("ALTER TABLE Semesters ADD COLUMN start INTEGER DEFAULT 0 NOT NULL") + database.execSQL("ALTER TABLE Semesters ADD COLUMN `end` INTEGER DEFAULT 0 NOT NULL") + } + + 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()) + } + return students + } + + private fun markAtLeastAndOnlyOneSemesterAtCurrent(database: SupportSQLiteDatabase, students: List>) { + students.forEach { (studentId, classId) -> + database.execSQL("UPDATE Semesters SET is_current = 0 WHERE student_id = '$studentId' AND class_id = '$classId'") + database.execSQL("UPDATE Semesters SET is_current = 1 WHERE id = (SELECT id FROM Semesters WHERE student_id = '$studentId' AND class_id = '$classId' ORDER BY semester_id DESC)") + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt index b25c8881b..c199c16c0 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt @@ -17,9 +17,12 @@ class SemesterRemote @Inject constructor(private val api: Api) { studentId = student.studentId, diaryId = semester.diaryId, diaryName = semester.diaryName, + schoolYear = semester.schoolYear, semesterId = semester.semesterId, semesterName = semester.semesterNumber, isCurrent = semester.current, + start = semester.start, + end = semester.end, classId = semester.classId, unitId = semester.unitId ) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt index f0692a534..251d38344 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt @@ -21,6 +21,7 @@ class StudentRemote @Inject constructor(private val api: Api) { studentName = student.studentName, schoolSymbol = student.schoolSymbol, schoolName = student.schoolName, + className = student.className, classId = student.classId, endpoint = endpoint, loginType = student.loginType.name, diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt index cb7aabda7..972d10a26 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.account +import android.annotation.SuppressLint import android.view.View import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -18,9 +19,10 @@ class AccountItem(val student: Student) : AbstractFlexibleItem>, holder: ViewHolder, position: Int, payloads: MutableList?) { holder.apply { - accountItemName.text = student.studentName + accountItemName.text = "${student.studentName} ${student.className}" accountItemSchool.text = student.schoolName accountItemImage.setBackgroundResource(if (student.isCurrent) R.drawable.ic_account_circular_border else 0) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt index 71a7d681e..65940a980 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.login.studentselect +import android.annotation.SuppressLint import android.view.View import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -18,9 +19,10 @@ class LoginStudentSelectItem(val student: Student) : AbstractFlexibleItem>, holder: ItemViewHolder, position: Int, payloads: MutableList?) { holder.run { - loginItemName.text = student.studentName + loginItemName.text = "${student.studentName} ${student.className}" loginItemSchool.text = student.schoolName } } diff --git a/app/src/main/res/layout/item_account.xml b/app/src/main/res/layout/item_account.xml index 844dd2c9c..56f553e54 100644 --- a/app/src/main/res/layout/item_account.xml +++ b/app/src/main/res/layout/item_account.xml @@ -30,8 +30,10 @@ android:layout_marginLeft="20dp" android:layout_toEndOf="@id/accountItemImage" android:layout_toRightOf="@id/accountItemImage" - android:text="@string/app_name" - android:textSize="16sp" /> + android:ellipsize="end" + android:maxLines="1" + android:textSize="16sp" + tools:text="@tools:sample/lorem/random" /> + android:textSize="12sp" + tools:text="@tools:sample/lorem/random" /> diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/semester/TestSemesterEnityCreator.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/semester/TestSemesterEnityCreator.kt index c3377ac51..f628710fc 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/semester/TestSemesterEnityCreator.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/semester/TestSemesterEnityCreator.kt @@ -1,6 +1,7 @@ package io.github.wulkanowy.data.repositories.semester import io.github.wulkanowy.data.db.entities.Semester +import org.threeten.bp.LocalDate.now fun createSemesterEntity(current: Boolean): Semester { return Semester( @@ -8,9 +9,12 @@ fun createSemesterEntity(current: Boolean): Semester { diaryId = 0, semesterId = 0, diaryName = "", + schoolYear = 1970, classId = 0, isCurrent = current, semesterName = 0, - unitId = 0 + unitId = 0, + start = now(), + end = now() ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt index 8bd819e21..4d7b23ebd 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt @@ -22,7 +22,7 @@ class StudentRemoteTest { @Test fun testRemoteAll() { - doReturn(Single.just(listOf(Student("", "", 1, "test", "", "", 1, Api.LoginType.AUTO)))) + doReturn(Single.just(listOf(Student("", "", 1, "test", "", "", "", 1, Api.LoginType.AUTO)))) .`when`(mockApi).getStudents() val students = StudentRemote(mockApi).getStudents("", "", "").blockingGet() 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 f1113f7bb..83047e02b 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 @@ -86,7 +86,7 @@ class LoginFormPresenterTest { @Test fun loginTest() { - val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO", studentName = "", schoolSymbol = "", schoolName = "", studentId = 0, classId = 1, isCurrent = false, symbol = "", registrationDate = now()) + val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO", studentName = "", schoolSymbol = "", schoolName = "", studentId = 0, classId = 1, isCurrent = false, symbol = "", registrationDate = now(), className = "") doReturn(Single.just(listOf(studentTest))) .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) 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 2de4e43a5..192602b78 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 @@ -32,7 +32,7 @@ class LoginStudentSelectPresenterTest { private lateinit var presenter: LoginStudentSelectPresenter - private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO", symbol = "", isCurrent = false, studentId = 0, schoolName = "", schoolSymbol = "", classId = 1, studentName = "", registrationDate = now()) } + private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO", symbol = "", isCurrent = false, studentId = 0, schoolName = "", schoolSymbol = "", classId = 1, studentName = "", registrationDate = now(), className = "") } private val testException by lazy { RuntimeException("Problem") }