From 32c69772ae1631fb81c0ebd0352bbad884ec1909 Mon Sep 17 00:00:00 2001 From: Dharanish Date: Tue, 9 Jul 2024 23:23:44 +0200 Subject: [PATCH] Make ids unique across both habits and groups --- .../uhabits/core/database/Repository.kt | 22 ++++++++++- .../models/sqlite/SQLiteHabitGroupList.kt | 2 +- .../core/models/sqlite/SQLiteHabitList.kt | 2 +- .../src/jvmMain/resources/migrations/26.sql | 38 ++++++++++++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt index 80f747cc9..1976c8115 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt @@ -22,8 +22,6 @@ import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.tuple.ImmutablePair import org.apache.commons.lang3.tuple.Pair import java.lang.reflect.Field -import java.util.ArrayList -import java.util.HashMap import java.util.LinkedList class Repository( @@ -130,6 +128,26 @@ class Repository( } } + /** + * Gets the shared id for tables that need to maintain unique ids across tables + * like habits and habit groups + */ + + fun getNextAvailableId(name: String): Long { + val query = "SELECT next_id FROM SharedIds WHERE name = ?" + val cursor = db.query(query, name) + val nextId: Long + cursor.use { c -> + if (cursor.moveToNext()) { + nextId = cursor.getLong(0) ?: throw IllegalStateException("Cannot fetch shared ID for $name") + execSQL("UPDATE SharedIds SET next_id = next_id + 1 WHERE name = ?", name) + } else { + throw IllegalStateException("Cannot fetch shared ID for $name") + } + } + return nextId + } + private fun cursorToMultipleRecords(c: Cursor): List { val records: MutableList = LinkedList() while (c.moveToNext()) records.add(cursorToSingleRecord(c)) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt index 4ec45595f..34cbab1e4 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt @@ -36,10 +36,10 @@ class SQLiteHabitGroupList @Inject constructor(private val modelFactory: ModelFa override fun add(habitGroup: HabitGroup) { loadRecords() habitGroup.position = size() + habitGroup.id = repository.getNextAvailableId("habitandgroup") val record = HabitGroupRecord() record.copyFrom(habitGroup) repository.save(record) - habitGroup.id = record.id habitGroup.habitList.groupID = record.id list.add(habitGroup) observable.notifyListeners() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.kt index 76f061a5a..2fb0b8a61 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.kt @@ -52,10 +52,10 @@ class SQLiteHabitList @Inject constructor(private val modelFactory: ModelFactory override fun add(habit: Habit) { loadRecords() habit.position = size() + habit.id = repository.getNextAvailableId("habitandgroup") val record = HabitRecord() record.copyFrom(habit) repository.save(record) - habit.id = record.id (habit.originalEntries as SQLiteEntryList).habitId = record.id list.add(habit) observable.notifyListeners() diff --git a/uhabits-core/src/jvmMain/resources/migrations/26.sql b/uhabits-core/src/jvmMain/resources/migrations/26.sql index 8d0c0f7df..c8bd3f2b2 100644 --- a/uhabits-core/src/jvmMain/resources/migrations/26.sql +++ b/uhabits-core/src/jvmMain/resources/migrations/26.sql @@ -1,5 +1,41 @@ +create table SharedIds ( + name text primary key, + next_id integer not null +); + +insert into SharedIds (name, next_id) values ('habitandgroup', (select coalesce(max(id),0) from Habits) + 1 ); + +alter table Habits rename to HabitsOld; + +create table Habits ( + id integer primary key, + archived integer, + color integer, + description text, + freq_den integer, + freq_num integer, + highlight integer, + name text, + position integer, + reminder_hour integer, + reminder_min integer, + reminder_days integer not null default 127, + type integer not null default 0, + target_type integer not null default 0, + target_value real not null default 0, + unit text not null default "", + question text, + uuid text +); + +insert into Habits (id, archived, color, description, freq_den, freq_num, highlight, name, position, reminder_min, reminder_days, type, target_type, target_value, unit, question, uuid) +select id, archived, color, description, freq_den, freq_num, highlight, name, position, reminder_min, reminder_days, type, target_type, target_value, unit, question, uuid +from HabitsOld; + +drop table HabitsOld; + create table HabitGroups ( - id integer primary key autoincrement, + id integer primary key, archived integer, color integer, description text not null default "",