@ -42,7 +42,8 @@ public class DailyNotificationMigration {
private static final String KEY_ADAPTIVE_SCHEDULING = "adaptive_scheduling" ;
private final Context context ;
private final DailyNotificationDatabase database ;
// Legacy SQLite helper reference (now removed). Keep as Object for compatibility; not used.
private final Object database ;
private final Gson gson ;
/ * *
@ -51,7 +52,7 @@ public class DailyNotificationMigration {
* @param context Application context
* @param database SQLite database instance
* /
public DailyNotificationMigration ( Context context , DailyNotificationDatabase database ) {
public DailyNotificationMigration ( Context context , Object database ) {
this . context = context ;
this . database = database ;
this . gson = new Gson ( ) ;
@ -63,51 +64,8 @@ public class DailyNotificationMigration {
* @return true if migration was successful
* /
public boolean migrateToSQLite ( ) {
try {
Log . d ( TAG , "Starting migration from SharedPreferences to SQLite" ) ;
// Check if migration is needed
if ( ! isMigrationNeeded ( ) ) {
Log . d ( TAG , "Migration not needed - SQLite already up to date" ) ;
return true ;
}
// Get writable database
SQLiteDatabase db = database . getWritableDatabase ( ) ;
// Start transaction for atomic migration
db . beginTransaction ( ) ;
try {
// Migrate notification content
int contentCount = migrateNotificationContent ( db ) ;
// Migrate settings
int settingsCount = migrateSettings ( db ) ;
// Mark migration as complete
markMigrationComplete ( db ) ;
// Commit transaction
db . setTransactionSuccessful ( ) ;
Log . i ( TAG , String . format ( "Migration completed successfully: %d notifications, %d settings" ,
contentCount , settingsCount ) ) ;
return true ;
} catch ( Exception e ) {
Log . e ( TAG , "Error during migration transaction" , e ) ;
db . endTransaction ( ) ;
return false ;
} finally {
db . endTransaction ( ) ;
}
} catch ( Exception e ) {
Log . e ( TAG , "Error during migration" , e ) ;
return false ;
}
Log . d ( TAG , "Migration skipped (legacy SQLite removed)" ) ;
return true ;
}
/ * *
@ -115,37 +73,7 @@ public class DailyNotificationMigration {
*
* @return true if migration is required
* /
private boolean isMigrationNeeded ( ) {
try {
// Check if SharedPreferences has data
SharedPreferences prefs = context . getSharedPreferences ( PREFS_NAME , Context . MODE_PRIVATE ) ;
String notificationsJson = prefs . getString ( KEY_NOTIFICATIONS , "[]" ) ;
// Check if SQLite already has data
SQLiteDatabase db = database . getReadableDatabase ( ) ;
android . database . Cursor cursor = db . rawQuery (
"SELECT COUNT(*) FROM " + DailyNotificationDatabase . TABLE_NOTIF_CONTENTS , null ) ;
int sqliteCount = 0 ;
if ( cursor . moveToFirst ( ) ) {
sqliteCount = cursor . getInt ( 0 ) ;
}
cursor . close ( ) ;
// Migration needed if SharedPreferences has data but SQLite doesn't
boolean hasPrefsData = ! notificationsJson . equals ( "[]" ) & & ! notificationsJson . isEmpty ( ) ;
boolean needsMigration = hasPrefsData & & sqliteCount = = 0 ;
Log . d ( TAG , String . format ( "Migration check: prefs_data=%s, sqlite_count=%d, needed=%s" ,
hasPrefsData , sqliteCount , needsMigration ) ) ;
return needsMigration ;
} catch ( Exception e ) {
Log . e ( TAG , "Error checking migration status" , e ) ;
return false ;
}
}
private boolean isMigrationNeeded ( ) { return false ; }
/ * *
* Migrate notification content from SharedPreferences to SQLite
@ -153,57 +81,7 @@ public class DailyNotificationMigration {
* @param db SQLite database instance
* @return Number of notifications migrated
* /
private int migrateNotificationContent ( SQLiteDatabase db ) {
try {
SharedPreferences prefs = context . getSharedPreferences ( PREFS_NAME , Context . MODE_PRIVATE ) ;
String notificationsJson = prefs . getString ( KEY_NOTIFICATIONS , "[]" ) ;
if ( notificationsJson . equals ( "[]" ) | | notificationsJson . isEmpty ( ) ) {
Log . d ( TAG , "No notification content to migrate" ) ;
return 0 ;
}
// Parse JSON to List<NotificationContent>
Type type = new TypeToken < ArrayList < NotificationContent > > ( ) { } . getType ( ) ;
List < NotificationContent > notifications = gson . fromJson ( notificationsJson , type ) ;
int migratedCount = 0 ;
for ( NotificationContent notification : notifications ) {
try {
// Create ContentValues for notif_contents table
ContentValues values = new ContentValues ( ) ;
values . put ( DailyNotificationDatabase . COL_CONTENTS_SLOT_ID , notification . getId ( ) ) ;
values . put ( DailyNotificationDatabase . COL_CONTENTS_PAYLOAD_JSON ,
gson . toJson ( notification ) ) ;
values . put ( DailyNotificationDatabase . COL_CONTENTS_FETCHED_AT ,
notification . getFetchedAt ( ) ) ;
// ETag is null for migrated data
values . putNull ( DailyNotificationDatabase . COL_CONTENTS_ETAG ) ;
// Insert into notif_contents table
long rowId = db . insert ( DailyNotificationDatabase . TABLE_NOTIF_CONTENTS , null , values ) ;
if ( rowId ! = - 1 ) {
migratedCount + + ;
Log . d ( TAG , "Migrated notification: " + notification . getId ( ) ) ;
} else {
Log . w ( TAG , "Failed to migrate notification: " + notification . getId ( ) ) ;
}
} catch ( Exception e ) {
Log . e ( TAG , "Error migrating notification: " + notification . getId ( ) , e ) ;
}
}
Log . i ( TAG , "Migrated " + migratedCount + " notifications to SQLite" ) ;
return migratedCount ;
} catch ( Exception e ) {
Log . e ( TAG , "Error migrating notification content" , e ) ;
return 0 ;
}
}
private int migrateNotificationContent ( SQLiteDatabase db ) { return 0 ; }
/ * *
* Migrate settings from SharedPreferences to SQLite
@ -211,144 +89,26 @@ public class DailyNotificationMigration {
* @param db SQLite database instance
* @return Number of settings migrated
* /
private int migrateSettings ( SQLiteDatabase db ) {
try {
SharedPreferences prefs = context . getSharedPreferences ( PREFS_NAME , Context . MODE_PRIVATE ) ;
int migratedCount = 0 ;
// Migrate last_fetch timestamp
long lastFetch = prefs . getLong ( KEY_LAST_FETCH , 0 ) ;
if ( lastFetch > 0 ) {
ContentValues values = new ContentValues ( ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_K , KEY_LAST_FETCH ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_V , String . valueOf ( lastFetch ) ) ;
long rowId = db . insert ( DailyNotificationDatabase . TABLE_NOTIF_CONFIG , null , values ) ;
if ( rowId ! = - 1 ) {
migratedCount + + ;
Log . d ( TAG , "Migrated last_fetch setting" ) ;
}
}
// Migrate adaptive_scheduling setting
boolean adaptiveScheduling = prefs . getBoolean ( KEY_ADAPTIVE_SCHEDULING , false ) ;
ContentValues values = new ContentValues ( ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_K , KEY_ADAPTIVE_SCHEDULING ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_V , String . valueOf ( adaptiveScheduling ) ) ;
long rowId = db . insert ( DailyNotificationDatabase . TABLE_NOTIF_CONFIG , null , values ) ;
if ( rowId ! = - 1 ) {
migratedCount + + ;
Log . d ( TAG , "Migrated adaptive_scheduling setting" ) ;
}
Log . i ( TAG , "Migrated " + migratedCount + " settings to SQLite" ) ;
return migratedCount ;
} catch ( Exception e ) {
Log . e ( TAG , "Error migrating settings" , e ) ;
return 0 ;
}
}
private int migrateSettings ( SQLiteDatabase db ) { return 0 ; }
/ * *
* Mark migration as complete in the database
*
* @param db SQLite database instance
* /
private void markMigrationComplete ( SQLiteDatabase db ) {
try {
ContentValues values = new ContentValues ( ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_K , "migration_complete" ) ;
values . put ( DailyNotificationDatabase . COL_CONFIG_V , String . valueOf ( System . currentTimeMillis ( ) ) ) ;
db . insert ( DailyNotificationDatabase . TABLE_NOTIF_CONFIG , null , values ) ;
Log . d ( TAG , "Migration marked as complete" ) ;
} catch ( Exception e ) {
Log . e ( TAG , "Error marking migration complete" , e ) ;
}
}
private void markMigrationComplete ( SQLiteDatabase db ) { }
/ * *
* Validate migration success
*
* @return true if migration was successful
* /
public boolean validateMigration ( ) {
try {
SQLiteDatabase db = database . getReadableDatabase ( ) ;
// Check if migration_complete flag exists
android . database . Cursor cursor = db . query (
DailyNotificationDatabase . TABLE_NOTIF_CONFIG ,
new String [ ] { DailyNotificationDatabase . COL_CONFIG_V } ,
DailyNotificationDatabase . COL_CONFIG_K + " = ?" ,
new String [ ] { "migration_complete" } ,
null , null , null
) ;
boolean migrationComplete = cursor . moveToFirst ( ) ;
cursor . close ( ) ;
if ( ! migrationComplete ) {
Log . w ( TAG , "Migration validation failed - migration_complete flag not found" ) ;
return false ;
}
// Check if we have notification content
cursor = db . rawQuery (
"SELECT COUNT(*) FROM " + DailyNotificationDatabase . TABLE_NOTIF_CONTENTS , null ) ;
int contentCount = 0 ;
if ( cursor . moveToFirst ( ) ) {
contentCount = cursor . getInt ( 0 ) ;
}
cursor . close ( ) ;
Log . i ( TAG , "Migration validation successful - " + contentCount + " notifications in SQLite" ) ;
return true ;
} catch ( Exception e ) {
Log . e ( TAG , "Error validating migration" , e ) ;
return false ;
}
}
public boolean validateMigration ( ) { return true ; }
/ * *
* Get migration statistics
*
* @return Migration statistics string
* /
public String getMigrationStats ( ) {
try {
SQLiteDatabase db = database . getReadableDatabase ( ) ;
// Count notifications
android . database . Cursor cursor = db . rawQuery (
"SELECT COUNT(*) FROM " + DailyNotificationDatabase . TABLE_NOTIF_CONTENTS , null ) ;
int notificationCount = 0 ;
if ( cursor . moveToFirst ( ) ) {
notificationCount = cursor . getInt ( 0 ) ;
}
cursor . close ( ) ;
// Count settings
cursor = db . rawQuery (
"SELECT COUNT(*) FROM " + DailyNotificationDatabase . TABLE_NOTIF_CONFIG , null ) ;
int settingsCount = 0 ;
if ( cursor . moveToFirst ( ) ) {
settingsCount = cursor . getInt ( 0 ) ;
}
cursor . close ( ) ;
return String . format ( "Migration stats: %d notifications, %d settings" ,
notificationCount , settingsCount ) ;
} catch ( Exception e ) {
Log . e ( TAG , "Error getting migration stats" , e ) ;
return "Migration stats: Error retrieving data" ;
}
}
public String getMigrationStats ( ) { return "Migration stats: 0 notifications, 0 settings" ; }
}