tweak upgrades

This commit is contained in:
dgtlmoon
2026-02-07 16:30:59 +01:00
parent 80bb640c91
commit 181ffa3bb4
2 changed files with 16 additions and 44 deletions
+12 -6
View File
@@ -347,22 +347,28 @@ class ChangeDetectionStore(DatastoreUpdatesMixin, FileSavingDataStore):
"""
Build settings data structure for saving.
Tags are stored both in settings AND individual {uuid}/tag.json files.
This allows backwards compatibility while enabling atomic tag updates.
Tags behavior depends on schema version:
- Before update_28 (schema < 28): Tags saved in settings for migration
- After update_28 (schema >= 28): Tags excluded from settings (in individual files)
Returns:
dict: Settings data ready for serialization (with tags)
dict: Settings data ready for serialization
"""
import copy
# Deep copy settings to avoid modifying the original
settings_copy = copy.deepcopy(self.__data['settings'])
# Tags remain in settings for backwards compatibility and easy access
# They are ALSO stored in individual tag.json files (dual storage)
# Only exclude tags if we've already migrated them to individual files (schema >= 28)
# This ensures update_28 can migrate tags from settings
schema_version = self.__data['settings']['application'].get('schema_version', 0)
if schema_version >= 28:
# Tags are in individual tag.json files, don't save to settings
settings_copy['application']['tags'] = {}
# else: keep tags in settings for update_28 migration
return {
'note': 'Settings file - watches are in {uuid}/watch.json, tags are in both settings and {uuid}/tag.json',
'note': 'Settings file - watches are in {uuid}/watch.json, tags are in {uuid}/tag.json',
'app_guid': self.__data['app_guid'],
'settings': settings_copy,
'build_sha': self.__data.get('build_sha'),
+4 -38
View File
@@ -206,35 +206,11 @@ class DatastoreUpdatesMixin:
# Don't run any more updates
return
else:
# Bump the version, important
# Bump the version
self.data['settings']['application']['schema_version'] = update_n
self.commit()
# CRITICAL: Save all watches so changes are persisted
# Most updates modify watches, and in the new individual watch.json structure,
# we need to ensure those changes are saved
logger.info(f"Saving all {len(self.data['watching'])} watches after update_{update_n} (so that it saves them to disk)")
for uuid in self.data['watching'].keys():
self.data['watching'][uuid].commit()
# CRITICAL: Save all tags so changes are persisted
# After update_27, tags have individual tag.json files
# For updates before update_27, this will fail silently (tags don't have commit() yet)
tags = self.data['settings']['application'].get('tags', {})
if tags and update_n >= 27:
logger.info(f"Saving all {len(tags)} tags after update_{update_n}")
for uuid in tags.keys():
try:
tags[uuid].commit()
except AttributeError:
# Tag doesn't have commit() method yet (pre-update_27)
pass
# All changes already saved via individual .commit() calls:
# - Settings saved via self.commit() above
# - All watches saved via watch.commit() above
# - All tags saved via tag.commit() above
logger.success(f"Update {update_n} completed - all changes persisted")
logger.success(f"Update {update_n} completed")
# Track which updates ran
updates_ran.append(update_n)
@@ -664,16 +640,6 @@ class DatastoreUpdatesMixin:
logger.critical("Reloading datastore from new format...")
self._load_state() # Includes load_watches
logger.success("Datastore reloaded from new format successfully")
# Set schema version to latest available update
# This prevents re-running updates on next startup
updates_available = self.get_updates_available()
latest_schema = updates_available[-1] if updates_available else 26
self.data['settings']['application']['schema_version'] = latest_schema
self.commit()
logger.info(f"Set schema_version to {latest_schema} (migration complete, all watches already saved)")
logger.critical("=" * 80)
logger.critical("MIGRATION COMPLETED SUCCESSFULLY!")
logger.critical("=" * 80)
@@ -694,7 +660,7 @@ class DatastoreUpdatesMixin:
def update_26(self):
self.migrate_legacy_db_format()
def update_27(self):
def update_28(self):
"""
Migrate tags to individual tag.json files.
@@ -708,7 +674,7 @@ class DatastoreUpdatesMixin:
- Maintains backwards compatibility (tags stay in settings too)
"""
logger.critical("=" * 80)
logger.critical("Running migration: Individual tag persistence (update_27)")
logger.critical("Running migration: Individual tag persistence (update_28)")
logger.critical("Creating individual tag.json files (tags remain in settings too)")
logger.critical("=" * 80)