Skip to content

Commit

Permalink
Migrate from "id" to "guid".
Browse files Browse the repository at this point in the history
!!! ATTENTION !!! This change is NOT compatible to UPDATE exiting apps!

+ As of this commit the "id" XML attribute is no longer used as the unique
  token because its value cannot be guaranteed to be unique by the provider
  of the schedule XML. See voc/schedule#63.
+ Instead the "guid" XML attribute is used which guarantees unique values.
+ To keep this migration to a minimum only the value of the Session#sessionId
  field is changed. The value of the new primary key (auto-incrementing,
  unique through the "guid" column) is written into the "sessionId" field
  when a Session is queried from the database. See SessionsDatabaseRepository.
+ By this the value of the "id" XML attribute becomes unused hence the
  deprecation of the SESSION_ID database column.

Reset all database tables.

!!! ATTENTION !!! This change is NOT compatible to UPDATE exiting apps!

+ This reset is possible and needed because the former commit is
  incompatible with current installations.
+ Improve a few table and column names.

Ensure sessions have unique "guid" values.

+ Non-unique session will be discarded without telling the user.

Change all session IDs to GUIDs
  • Loading branch information
johnjohndoe authored and autinerd committed Dec 22, 2024
1 parent d33c36e commit 11cc135
Show file tree
Hide file tree
Showing 110 changed files with 588 additions and 709 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ class AlarmReceiver : BroadcastReceiver() {
ALARM_DISMISSED -> onSessionAlarmNotificationDismissed(intent)
ALARM_UPDATE -> UpdateService.start(context)
ALARM_SESSION -> {
val sessionId = intent.getStringExtra(BundleKeys.ALARM_SESSION_ID)!!
val guid = intent.getStringExtra(BundleKeys.ALARM_GUID)!!
val day = intent.getIntExtra(BundleKeys.ALARM_DAY, 1)
val start = intent.getLongExtra(BundleKeys.ALARM_START_TIME, System.currentTimeMillis())
val title = intent.getStringExtra(BundleKeys.ALARM_TITLE)!!
logging.report(LOG_TAG, "sessionId = $sessionId, intent = $intent")
logging.report(LOG_TAG, "guid = $guid, intent = $intent")
//Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();

val uniqueNotificationId = AppRepository.createSessionAlarmNotificationId(sessionId)
val launchIntent = createLaunchIntent(context, sessionId, day, uniqueNotificationId)
val uniqueNotificationId = AppRepository.createSessionAlarmNotificationId(guid)
val launchIntent = createLaunchIntent(context, guid, day, uniqueNotificationId)
val contentIntent = PendingIntentProvider.getPendingIntentActivity(context, launchIntent)

val notificationHelper = NotificationHelper(context)
Expand All @@ -72,7 +72,7 @@ class AlarmReceiver : BroadcastReceiver() {
val isInsistentAlarmsEnabled = AppRepository.readInsistentAlarmsEnabled()
notificationHelper.notify(uniqueNotificationId, builder, isInsistentAlarmsEnabled)

AppRepository.deleteAlarmForSessionId(sessionId)
AppRepository.deleteAlarmForGuid(guid)
}
}
}
Expand All @@ -87,21 +87,21 @@ class AlarmReceiver : BroadcastReceiver() {

internal class AlarmIntentFactory(
val context: Context,
val sessionId: String,
val guid: String,
val title: String,
val day: Int,
val startTime: Long,
) {

fun getIntent(isAddAlarmIntent: Boolean) = Intent(context, AlarmReceiver::class.java)
.withExtras(
BundleKeys.ALARM_SESSION_ID to sessionId,
BundleKeys.ALARM_GUID to guid,
BundleKeys.ALARM_DAY to day,
BundleKeys.ALARM_TITLE to title,
BundleKeys.ALARM_START_TIME to startTime
).apply {
action = if (isAddAlarmIntent) ALARM_SESSION else ALARM_DELETE
data = "alarm://$sessionId".toUri()
data = "alarm://$guid".toUri()
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class AlarmServices @VisibleForTesting constructor(
* corresponding with the given [alarmTimesIndex].
*/
fun addSessionAlarm(session: Session, alarmTimesIndex: Int) {
logging.d(LOG_TAG, "Add alarm for session = ${session.sessionId}, alarmTimesIndex = $alarmTimesIndex.")
logging.d(LOG_TAG, "Add alarm for session = ${session.guid}, alarmTimesIndex = $alarmTimesIndex.")
val alarmTimeStrings = ArrayList(alarmTimeValues)
val alarmTimes = ArrayList<Int>(alarmTimeStrings.size)
for (alarmTimeString in alarmTimeStrings) {
Expand All @@ -78,13 +78,13 @@ class AlarmServices @VisibleForTesting constructor(
val alarmTime = sessionStartTime - alarmTimeOffset
val moment = Moment.ofEpochMilli(alarmTime)
logging.d(LOG_TAG, "Add alarm: Time = ${moment.toUtcDateTime()}, in seconds = $alarmTime.")
val sessionId = session.sessionId
val guid = session.guid
val sessionTitle = session.title
val alarmTimeInMin = alarmTimes[alarmTimesIndex]
val useDeviceTimeZone = repository.readUseDeviceTimeZoneEnabled()
val timeText = formattingDelegate.getFormattedDateTimeShort(useDeviceTimeZone, alarmTime, session.timeZoneOffset)
val day = session.dayIndex
val alarm = Alarm(alarmTimeInMin, day, sessionStartTime, sessionId, sessionTitle, alarmTime, timeText)
val alarm = Alarm(alarmTimeInMin, day, sessionStartTime, guid, sessionTitle, alarmTime, timeText)
val schedulableAlarm = alarm.toSchedulableAlarm()
scheduleSessionAlarm(schedulableAlarm, true)
repository.updateAlarm(alarm)
Expand All @@ -94,14 +94,14 @@ class AlarmServices @VisibleForTesting constructor(
* Deletes the alarm for the given [session].
*/
fun deleteSessionAlarm(session: Session) {
val sessionId = session.sessionId
val alarms = repository.readAlarms(sessionId)
val guid = session.guid
val alarms = repository.readAlarms(guid)
if (alarms.isNotEmpty()) {
// Delete any previous alarms of this session.
val alarm = alarms[0]
val schedulableAlarm = alarm.toSchedulableAlarm()
discardSessionAlarm(schedulableAlarm)
repository.deleteAlarmForSessionId(sessionId)
repository.deleteAlarmForGuid(guid)
}
}

Expand All @@ -122,7 +122,7 @@ class AlarmServices @VisibleForTesting constructor(
fun scheduleSessionAlarm(alarm: SchedulableAlarm, discardExisting: Boolean = false) {
val intent = AlarmReceiver.AlarmIntentFactory(
context = context,
sessionId = alarm.sessionId,
guid = alarm.guid,
title = alarm.sessionTitle,
day = alarm.day,
startTime = alarm.startTime
Expand All @@ -146,7 +146,7 @@ class AlarmServices @VisibleForTesting constructor(
fun discardSessionAlarm(alarm: SchedulableAlarm) {
val intent = AlarmReceiver.AlarmIntentFactory(
context = context,
sessionId = alarm.sessionId,
guid = alarm.guid,
title = alarm.sessionTitle,
day = alarm.day,
startTime = alarm.startTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class AlarmsActivity : BaseActivity(),
}
}

override fun onSessionItemClick(sessionId: String) {
if (AppRepository.updateSelectedSessionId(sessionId)) {
override fun onSessionItemClick(guid: String) {
if (AppRepository.updateSelectedGuid(guid)) {
SessionDetailsActivity.start(this)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ private fun AlarmsScreenPreview() {
Success(
listOf(
SessionAlarmParameter(
sessionId = "s1",
guid = "11111111-1111-1111-1111-111111111111",
title = "Some random title",
titleContentDescription = "",
subtitle = "A longer subtitle to be displayed",
Expand All @@ -222,7 +222,7 @@ private fun AlarmsScreenPreview() {
dayIndex = 0,
),
SessionAlarmParameter(
sessionId = "s2",
guid = "11111111-1111-1111-1111-111111111112",
title = "Second title",
titleContentDescription = "",
subtitle = "A longer subtitle to be displayed lorem ipsum",
Expand All @@ -235,7 +235,7 @@ private fun AlarmsScreenPreview() {
dayIndex = 0,
),
SessionAlarmParameter(
sessionId = "s3",
guid = "11111111-1111-1111-1111-111111111113",
title = "No subtitle present for this item",
titleContentDescription = "",
subtitle = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class AlarmsFragment : Fragment(), MenuProvider {
appRepository = AppRepository
resourceResolving = ResourceResolver(context)
alarmServices = AlarmServices.newInstance(context, appRepository)
viewModel.screenNavigation = ScreenNavigation { sessionId ->
onSessionItemClickListener?.onSessionItemClick(sessionId)
viewModel.screenNavigation = ScreenNavigation { guid ->
onSessionItemClickListener?.onSessionItemClick(guid)
}
onSessionItemClickListener = try {
context as OnSessionItemClickListener
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AlarmsStateFactory(
useDeviceTimeZone: Boolean,
): List<SessionAlarmParameter> = alarms.mapNotNull { alarm ->
sessions
.find { session -> session.sessionId == alarm.sessionId }
.find { session -> session.guid == alarm.guid }
?.let { found ->
val titleContentDescription = resourceResolving.getString(
R.string.session_list_item_title_content_description,
Expand Down Expand Up @@ -48,7 +48,7 @@ class AlarmsStateFactory(
)

SessionAlarmParameter(
sessionId = found.sessionId,
guid = found.guid,
title = found.title,
titleContentDescription = titleContentDescription,
subtitle = found.subtitle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ internal class AlarmsViewModel(
}

private fun navigateToSessionDetails(value: SessionAlarmParameter) {
screenNavigation?.navigateToSessionDetails(value.sessionId)
screenNavigation?.navigateToSessionDetails(value.guid)
}

private fun deleteSessionAlarm(value: SessionAlarmParameter) {
launch {
repository.deleteAlarmForSessionId(value.sessionId)
repository.deleteAlarmForGuid(value.guid)
val alarm = SchedulableAlarm(
day = value.dayIndex,
sessionId = value.sessionId,
guid = value.guid,
sessionTitle = value.title,
startTime = value.firesAt
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import nerd.tuxmobil.fahrplan.congress.alarms.AlarmsState.Success
* property in the [AlarmsViewModel] which is observed by the [AlarmsFragment].
*/
data class SessionAlarmParameter(
val sessionId: String,
val guid: String,
val title: String,
val titleContentDescription: String,
val subtitle: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ abstract class AbstractListFragment : ListFragment() {
* to the activity and potentially other fragments contained in that
* activity.
*
* @param sessionId The ID of the session which was clicked.
* @param guid The ID of the session which was clicked.
*/
fun onSessionListClick(sessionId: String)
fun onSessionListClick(guid: String)
}

protected lateinit var appRepository: AppRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package nerd.tuxmobil.fahrplan.congress.base

fun interface OnSessionItemClickListener {

fun onSessionItemClick(sessionId: String)
fun onSessionItemClick(guid: String)

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class ChangeListActivity :
supportActionBar!!.setBackgroundDrawable(ColorDrawable(actionBarColor))
}

override fun onSessionListClick(sessionId: String) {
if (AppRepository.updateSelectedSessionId(sessionId)) {
override fun onSessionListClick(guid: String) {
if (AppRepository.updateSelectedGuid(guid)) {
SessionDetailsActivity.start(this)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ class ChangeListFragment : Fragment() {
@CallSuper
override fun onAttach(context: Context) {
super.onAttach(context)
viewModel.screenNavigation = ScreenNavigation { sessionId ->
onSessionListClickListener?.onSessionListClick(sessionId)
viewModel.screenNavigation = ScreenNavigation { guid ->
onSessionListClickListener?.onSessionListClick(guid)
}
if (context is OnSessionListClick) {
onSessionListClickListener = context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class ChangeListViewModel(

fun onViewEvent(viewEvent: SessionChangeViewEvent) {
when (viewEvent) {
is OnSessionChangeItemClick -> screenNavigation?.navigateToSessionDetails(viewEvent.sessionId)
is OnSessionChangeItemClick -> screenNavigation?.navigateToSessionDetails(viewEvent.guid)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class SessionChangeParametersFactory(
val title = if (session.changedTitle && session.title.isEmpty()) dash else session.title

return SessionChange(
id = session.sessionId,
id = session.guid,
title = SessionChangeProperty(
value = title,
contentDescription = title,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package nerd.tuxmobil.fahrplan.congress.changes

sealed interface SessionChangeViewEvent {
data class OnSessionChangeItemClick(val sessionId: String) : SessionChangeViewEvent
data class OnSessionChangeItemClick(val guid: String) : SessionChangeViewEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package nerd.tuxmobil.fahrplan.congress.commons

fun interface ScreenNavigation {

fun navigateToSessionDetails(sessionId: String)
fun navigateToSessionDetails(guid: String)

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package nerd.tuxmobil.fahrplan.congress.contract
object BundleKeys {

// Add + delete alarm
const val ALARM_SESSION_ID = "nerd.tuxmobil.fahrplan.congress.ALARM_SESSION_ID"
const val ALARM_GUID = "nerd.tuxmobil.fahrplan.congress.ALARM_GUID"
const val ALARM_DAY = "nerd.tuxmobil.fahrplan.congress.ALARM_DAY"
const val ALARM_TITLE = "nerd.tuxmobil.fahrplan.congress.ALARM_TITLE"
const val ALARM_START_TIME = "nerd.tuxmobil.fahrplan.congress.ALARM_START_TIME"

// Session alarm notification
const val SESSION_ALARM_SESSION_ID =
"nerd.tuxmobil.fahrplan.congress.SESSION_ALARM_SESSION_ID"
const val SESSION_ALARM_GUID =
"nerd.tuxmobil.fahrplan.congress.SESSION_ALARM_GUID"
const val SESSION_ALARM_DAY_INDEX =
"nerd.tuxmobil.fahrplan.congress.SESSION_ALARM_DAY_INDEX"
const val SESSION_ALARM_NOTIFICATION_ID =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ fun Alarm.toAlarmDatabaseModel() = DatabaseAlarm(
alarmTimeInMin = alarmTimeInMin,
day = day,
displayTime = displayTime,
sessionId = sessionId,
guid = guid,
title = sessionTitle,
time = startTime,
timeText = timeText
)

fun Alarm.toSchedulableAlarm() = SchedulableAlarm(
day = day,
sessionId = sessionId,
guid = guid,
sessionTitle = sessionTitle,
startTime = startTime
)
Expand All @@ -29,7 +29,7 @@ fun DatabaseAlarm.toAlarmAppModel() = Alarm(
alarmTimeInMin = alarmTimeInMin,
day = day,
displayTime = displayTime,
sessionId = sessionId,
guid = guid,
sessionTitle = title,
startTime = time,
timeText = timeText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ fun SessionAppModel.toRoom() = Room(identifier = roomIdentifier, name = roomName
fun SessionDatabaseModel.toDateInfo(): DateInfo = DateInfo(dayIndex, Moment.parseDate(dateText))

fun SessionAppModel.toHighlightDatabaseModel() = HighlightDatabaseModel(
sessionId = Integer.parseInt(sessionId),
guid = guid,
isHighlight = isHighlight
)

fun SessionDatabaseModel.toSessionAppModel(): SessionAppModel {
return SessionAppModel(
sessionId = sessionId,
guid = guid,
abstractt = abstractt,
dateText = dateText,
dateUTC = dateUTC,
Expand Down Expand Up @@ -76,7 +76,7 @@ fun SessionDatabaseModel.toSessionAppModel(): SessionAppModel {

fun SessionDatabaseModel.toSessionNetworkModel(): SessionNetworkModel {
return SessionNetworkModel(
sessionId = sessionId,
guid = guid,
abstractt = abstractt,
dateText = dateText,
dateUTC = dateUTC,
Expand Down Expand Up @@ -121,7 +121,7 @@ fun SessionDatabaseModel.toSessionNetworkModel(): SessionNetworkModel {

fun SessionNetworkModel.toSessionDatabaseModel(): SessionDatabaseModel {
return SessionDatabaseModel(
sessionId = sessionId,
guid = guid,
abstractt = abstractt,
dateText = dateText,
dateUTC = dateUTC,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fun Shift.toSessionNetworkModel(
dayRanges: List<DayRange>

) = SessionNetworkModel(
sessionId = "${SHIFT_ID_OFFSET + sID}",
guid = "17363248-3847-${"%04x".format(sID)}-e734-2389e8437483", // Create GUID for Shifts
abstractt = "",
dateText = startsAtLocalDateString,
dateUTC = dateUtcMs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package nerd.tuxmobil.fahrplan.congress.details
data class SelectedSessionParameter(

// Details content
val sessionId: String,
val guid: String,

val hasDateUtc: Boolean,
val formattedZonedDateTimeShort: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class SessionDetailsFragment : Fragment(), MenuProvider {
textView.contentDescription = contentDescriptionFormatter
.getRoomNameContentDescription(model.roomName)
textView = view.requireViewByIdCompat(R.id.session_detailbar_session_id_view)
textView.text = if (model.sessionId.isEmpty()) "" else textView.context.getString(R.string.session_details_session_id, model.sessionId)
textView.text = if (model.guid.isEmpty()) "" else textView.context.getString(R.string.session_details_session_id, model.guid)

// Title
textView = view.requireViewByIdCompat(R.id.session_details_content_title_view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ internal class SessionDetailsViewModel(

return SelectedSessionParameter(
// Details content
sessionId = sessionId,
guid = guid,
hasDateUtc = dateUTC > 0,
formattedZonedDateTimeShort = formattedZonedDateTimeShort,
formattedZonedDateTimeLong = formattedZonedDateTimeLong,
Expand Down
Loading

0 comments on commit 11cc135

Please sign in to comment.