diff --git a/api/src/main/java/io/github/wulkanowy/api/attendance/AttendanceTable.java b/api/src/main/java/io/github/wulkanowy/api/attendance/AttendanceTable.java index c45cbe6a4..d81a30b2f 100644 --- a/api/src/main/java/io/github/wulkanowy/api/attendance/AttendanceTable.java +++ b/api/src/main/java/io/github/wulkanowy/api/attendance/AttendanceTable.java @@ -63,7 +63,7 @@ public class AttendanceTable { for (int i = 1; i < size; i++) { Lesson lesson = new Lesson(); lesson.setDate(days.get(i - 1).getDate()); - lesson.setNumber(hours.get(0).text()); + lesson.setNumber(Integer.valueOf(hours.get(0).text())); addLessonDetails(lesson, hours.get(i)); diff --git a/api/src/main/java/io/github/wulkanowy/api/generic/Lesson.java b/api/src/main/java/io/github/wulkanowy/api/generic/Lesson.java index 8dd653277..27bf9bf0b 100644 --- a/api/src/main/java/io/github/wulkanowy/api/generic/Lesson.java +++ b/api/src/main/java/io/github/wulkanowy/api/generic/Lesson.java @@ -2,7 +2,7 @@ package io.github.wulkanowy.api.generic; public class Lesson { - private String number = ""; + private int number = 0; private String subject = ""; @@ -48,12 +48,13 @@ public class Lesson { private boolean isExemption = false; - public String getNumber() { + public int getNumber() { return number; } - public void setNumber(String number) { + public Lesson setNumber(int number) { this.number = number; + return this; } public String getSubject() { diff --git a/api/src/main/java/io/github/wulkanowy/api/timetable/Timetable.java b/api/src/main/java/io/github/wulkanowy/api/timetable/Timetable.java index 4e9cc18ef..77ca41bd6 100644 --- a/api/src/main/java/io/github/wulkanowy/api/timetable/Timetable.java +++ b/api/src/main/java/io/github/wulkanowy/api/timetable/Timetable.java @@ -81,7 +81,7 @@ public class Timetable { lesson.setStartTime(startEndEnd[0]); lesson.setEndTime(startEndEnd[1]); lesson.setDate(days.get(i - 2).getDate()); - lesson.setNumber(hours.get(0).text()); + lesson.setNumber(Integer.valueOf(hours.get(0).text())); addLessonDetails(lesson, hours.get(i).select("div")); diff --git a/api/src/test/java/io/github/wulkanowy/api/timetable/TimetableTest.java b/api/src/test/java/io/github/wulkanowy/api/timetable/TimetableTest.java index 818745f7b..8939b10fd 100644 --- a/api/src/test/java/io/github/wulkanowy/api/timetable/TimetableTest.java +++ b/api/src/test/java/io/github/wulkanowy/api/timetable/TimetableTest.java @@ -83,11 +83,11 @@ public class TimetableTest extends StudentAndParentTestCase { @Test public void getLessonNumberTest() throws Exception { - Assert.assertEquals("2", std.getWeekTable().getDay(0).getLesson(1).getNumber()); - Assert.assertEquals("5", std.getWeekTable().getDay(2).getLesson(4).getNumber()); - Assert.assertEquals("0", full.getWeekTable().getDay(0).getLesson(0).getNumber()); - Assert.assertEquals("13", full.getWeekTable().getDay(4).getLesson(13).getNumber()); - Assert.assertEquals("3", holidays.getWeekTable().getDay(3).getLesson(3).getNumber()); + Assert.assertEquals(2, std.getWeekTable().getDay(0).getLesson(1).getNumber()); + Assert.assertEquals(5, std.getWeekTable().getDay(2).getLesson(4).getNumber()); + Assert.assertEquals(0, full.getWeekTable().getDay(0).getLesson(0).getNumber()); + Assert.assertEquals(13, full.getWeekTable().getDay(4).getLesson(13).getNumber()); + Assert.assertEquals(3, holidays.getWeekTable().getDay(3).getLesson(3).getNumber()); } @Test diff --git a/app/build.gradle b/app/build.gradle index b9f3cdd83..78df5c91e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,7 +91,7 @@ play { } greendao { - schemaVersion 27 + schemaVersion 28 generateTests = true } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/DbHelper.java b/app/src/main/java/io/github/wulkanowy/data/db/dao/DbHelper.java index 8aa9b1dfb..97bb75598 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/DbHelper.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/DbHelper.java @@ -19,6 +19,7 @@ import io.github.wulkanowy.data.db.dao.entities.DaoMaster; import io.github.wulkanowy.data.db.dao.migrations.Migration23; import io.github.wulkanowy.data.db.dao.migrations.Migration26; import io.github.wulkanowy.data.db.dao.migrations.Migration27; +import io.github.wulkanowy.data.db.dao.migrations.Migration28; import io.github.wulkanowy.data.db.shared.SharedPrefContract; import io.github.wulkanowy.di.annotations.ApplicationContext; import io.github.wulkanowy.di.annotations.DatabaseInfo; @@ -78,6 +79,7 @@ public class DbHelper extends DaoMaster.OpenHelper { migrations.add(new Migration23()); migrations.add(new Migration26()); migrations.add(new Migration27()); + migrations.add(new Migration28()); // Sorting just to be safe, in case other people add migrations in the wrong order. Comparator migrationComparator = new Comparator() { diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/Day.java b/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/Day.java index 434affb03..c4857bc92 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/Day.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/Day.java @@ -5,6 +5,7 @@ import org.greenrobot.greendao.annotation.Entity; import org.greenrobot.greendao.annotation.Generated; import org.greenrobot.greendao.annotation.Id; import org.greenrobot.greendao.annotation.Index; +import org.greenrobot.greendao.annotation.OrderBy; import org.greenrobot.greendao.annotation.Property; import org.greenrobot.greendao.annotation.ToMany; @@ -35,9 +36,11 @@ public class Day { @Property(nameInDb = "free_day_name") private String freeDayName = ""; + @OrderBy("number ASC") @ToMany(referencedJoinProperty = "dayId") private List timetableLessons; + @OrderBy("number ASC") @ToMany(referencedJoinProperty = "dayId") private List attendanceLessons; @@ -50,9 +53,7 @@ public class Day { @Generated(hash = 2040040024) private transient DaoSession daoSession; - /** - * Used for active entity operations. - */ + /** Used for active entity operations. */ @Generated(hash = 312167767) private transient DayDao myDao; @@ -185,6 +186,36 @@ public class Day { attendanceLessons = null; } + /** + * To-many relationship, resolved on first access (and after reset). + * Changes to to-many relations are not persisted, make changes to the target entity. + */ + @Generated(hash = 1231531946) + public List getExams() { + if (exams == null) { + final DaoSession daoSession = this.daoSession; + if (daoSession == null) { + throw new DaoException("Entity is detached from DAO context"); + } + ExamDao targetDao = daoSession.getExamDao(); + List examsNew = targetDao._queryDay_Exams(id); + synchronized (this) { + if (exams == null) { + exams = examsNew; + } + } + } + return exams; + } + + /** + * Resets a to-many relationship, making the next get call to query for a fresh result. + */ + @Generated(hash = 841969952) + public synchronized void resetExams() { + exams = null; + } + /** * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Entity must attached to an entity context. @@ -222,39 +253,13 @@ public class Day { } /** - * To-many relationship, resolved on first access (and after reset). - * Changes to to-many relations are not persisted, make changes to the target entity. + * called by internal mechanisms, do not call yourself. */ - @Generated(hash = 1231531946) - public List getExams() { - if (exams == null) { - final DaoSession daoSession = this.daoSession; - if (daoSession == null) { - throw new DaoException("Entity is detached from DAO context"); - } - ExamDao targetDao = daoSession.getExamDao(); - List examsNew = targetDao._queryDay_Exams(id); - synchronized (this) { - if (exams == null) { - exams = examsNew; - } - } - } - return exams; - } - - /** - * Resets a to-many relationship, making the next get call to query for a fresh result. - */ - @Generated(hash = 841969952) - public synchronized void resetExams() { - exams = null; - } - - /** called by internal mechanisms, do not call yourself. */ @Generated(hash = 1409317752) public void __setDaoSession(DaoSession daoSession) { this.daoSession = daoSession; myDao = daoSession != null ? daoSession.getDayDao() : null; } + + } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/TimetableLesson.java b/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/TimetableLesson.java index 28761b6b7..f3fdf6a83 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/TimetableLesson.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/entities/TimetableLesson.java @@ -1,5 +1,7 @@ package io.github.wulkanowy.data.db.dao.entities; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.greenrobot.greendao.DaoException; import org.greenrobot.greendao.annotation.Entity; import org.greenrobot.greendao.annotation.Generated; @@ -12,7 +14,7 @@ import java.io.Serializable; @Entity( nameInDb = "TimetableLessons", active = true, - indexes = {@Index(value = "dayId,date,startTime,endTime", unique = true)} + indexes = {@Index(value = "dayId,date,number,startTime,endTime", unique = true)} ) public class TimetableLesson implements Serializable { @@ -25,7 +27,7 @@ public class TimetableLesson implements Serializable { private Long dayId; @Property(nameInDb = "number") - private String number; + private int number = 0; @Property(nameInDb = "subject") private String subject = ""; @@ -75,18 +77,15 @@ public class TimetableLesson implements Serializable { @Generated(hash = 2040040024) private transient DaoSession daoSession; - /** - * Used for active entity operations. - */ + /** Used for active entity operations. */ @Generated(hash = 1119360138) private transient TimetableLessonDao myDao; - @Generated(hash = 1955911128) - public TimetableLesson(Long id, Long dayId, String number, String subject, - String teacher, String room, String description, String group, - String startTime, String endTime, String date, boolean empty, - boolean divisionIntoGroups, boolean planning, boolean realized, - boolean movedOrCanceled, boolean newMovedInOrChanged) { + @Generated(hash = 1665905034) + public TimetableLesson(Long id, Long dayId, int number, String subject, String teacher, + String room, String description, String group, String startTime, String endTime, + String date, boolean empty, boolean divisionIntoGroups, boolean planning, + boolean realized, boolean movedOrCanceled, boolean newMovedInOrChanged) { this.id = id; this.dayId = dayId; this.number = number; @@ -109,7 +108,7 @@ public class TimetableLesson implements Serializable { @Generated(hash = 1878030142) public TimetableLesson() { } - + public Long getId() { return this.id; } @@ -127,11 +126,11 @@ public class TimetableLesson implements Serializable { return this; } - public String getNumber() { + public int getNumber() { return this.number; } - public TimetableLesson setNumber(String number) { + public TimetableLesson setNumber(int number) { this.number = number; return this; } @@ -262,6 +261,32 @@ public class TimetableLesson implements Serializable { return this; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + TimetableLesson lesson = (TimetableLesson) o; + + return new EqualsBuilder() + .append(number, lesson.number) + .append(startTime, lesson.startTime) + .append(endTime, lesson.endTime) + .append(date, lesson.date) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(number) + .append(startTime) + .append(endTime) + .append(date) + .toHashCode(); + } + /** * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Entity must attached to an entity context. diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/migrations/Migration28.java b/app/src/main/java/io/github/wulkanowy/data/db/dao/migrations/Migration28.java new file mode 100644 index 000000000..3970df4cf --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/migrations/Migration28.java @@ -0,0 +1,20 @@ +package io.github.wulkanowy.data.db.dao.migrations; + +import org.greenrobot.greendao.database.Database; + +import io.github.wulkanowy.api.Vulcan; +import io.github.wulkanowy.data.db.dao.DbHelper; +import io.github.wulkanowy.data.db.shared.SharedPrefContract; + +public class Migration28 implements DbHelper.Migration { + + @Override + public Integer getVersion() { + return 28; + } + + @Override + public void runMigration(final Database db, final SharedPrefContract sharedPref, final Vulcan vulcan) throws Exception { + throw new Exception("No migrations"); + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/sync/TimetableSync.java b/app/src/main/java/io/github/wulkanowy/data/sync/TimetableSync.java index 69ebafcf9..3fe22afff 100644 --- a/app/src/main/java/io/github/wulkanowy/data/sync/TimetableSync.java +++ b/app/src/main/java/io/github/wulkanowy/data/sync/TimetableSync.java @@ -1,5 +1,7 @@ package io.github.wulkanowy.data.sync; +import org.apache.commons.collections4.CollectionUtils; + import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; @@ -125,6 +127,16 @@ public class TimetableSync { List lessonsFromApiEntities = DataObjectConverter .lessonsToTimetableLessonsEntities(lessons); + List lessonsFromDbEntities = getLessonsFromDb(dayId); + + if (!lessonsFromDbEntities.isEmpty()) { + List lessonToRemove = new ArrayList<>(CollectionUtils.removeAll(lessonsFromDbEntities, lessonsFromApiEntities)); + + for (TimetableLesson timetableLesson : lessonToRemove) { + daoSession.getTimetableLessonDao().delete(timetableLesson); + } + } + for (TimetableLesson apiLessonEntity : lessonsFromApiEntities) { TimetableLesson lessonFromDb = getLessonFromDb(apiLessonEntity, dayId); @@ -148,4 +160,8 @@ public class TimetableSync { TimetableLessonDao.Properties.EndTime.eq(apiEntity.getEndTime())) .unique(); } + + private List getLessonsFromDb(long dayId) { + return daoSession.getDayDao().load(dayId).getTimetableLessons(); + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java index 8d65956e9..a3e84dfa2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java @@ -106,7 +106,7 @@ public class TimetableSubItem lessonName.setText(lesson.getSubject()); lessonTime.setText(getLessonTimeString()); - numberOfLesson.setText(lesson.getNumber()); + numberOfLesson.setText(String.valueOf(lesson.getNumber())); room.setText(getRoomString()); alert.setVisibility(lesson.getMovedOrCanceled() || lesson.getNewMovedInOrChanged() ? View.VISIBLE : View.INVISIBLE); diff --git a/app/src/main/java/io/github/wulkanowy/utils/DataObjectConverter.java b/app/src/main/java/io/github/wulkanowy/utils/DataObjectConverter.java index 3b599c8f7..3f733ad6d 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/DataObjectConverter.java +++ b/app/src/main/java/io/github/wulkanowy/utils/DataObjectConverter.java @@ -156,7 +156,7 @@ public final class DataObjectConverter { for (io.github.wulkanowy.api.generic.Lesson lesson : lessonList) { lessonEntityList.add(new AttendanceLesson() - .setNumber(Integer.valueOf(lesson.getNumber())) + .setNumber(lesson.getNumber()) .setSubject(lesson.getSubject()) .setDate(lesson.getDate()) .setPresence(lesson.isPresence())