Skip to content

Commit 9836682

Browse files
authored
Merge pull request #1567 from OneSignal/fix/sqlite_exception
Synchronize `OneSignalDbHelper` and throw the first exception encountered in retries
2 parents 6b45942 + 6c9e253 commit 9836682

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalDbHelper.java

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,19 @@ private SQLiteDatabase getSQLiteDatabase() {
168168
*/
169169
private SQLiteDatabase getSQLiteDatabaseWithRetries() {
170170
synchronized (LOCK) {
171+
// Throw the first exception as this may give more insight into the root cause of issue:
172+
// https://github.com/OneSignal/OneSignal-Android-SDK/issues/1432
173+
SQLiteException firstSQLiteException = null;
171174
int count = 0;
172175
while (true) {
173176
try {
174177
return getSQLiteDatabase();
175178
} catch (SQLiteCantOpenDatabaseException | SQLiteDatabaseLockedException e) {
179+
if (firstSQLiteException == null) {
180+
firstSQLiteException = e;
181+
}
176182
if (++count >= DB_OPEN_RETRY_MAX)
177-
throw e;
183+
throw firstSQLiteException;
178184
SystemClock.sleep(count * DB_OPEN_RETRY_BACKOFF);
179185
}
180186
}
@@ -311,28 +317,32 @@ public void delete(@NonNull String table, @Nullable String whereClause, @Nullabl
311317

312318
@Override
313319
public void onCreate(SQLiteDatabase db) {
314-
db.execSQL(SQL_CREATE_ENTRIES);
315-
db.execSQL(SQL_CREATE_OUTCOME_ENTRIES_V3);
316-
db.execSQL(SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2);
317-
db.execSQL(SQL_CREATE_IN_APP_MESSAGE_ENTRIES);
318-
for (String ind : SQL_INDEX_ENTRIES) {
319-
db.execSQL(ind);
320+
synchronized (LOCK) {
321+
db.execSQL(SQL_CREATE_ENTRIES);
322+
db.execSQL(SQL_CREATE_OUTCOME_ENTRIES_V3);
323+
db.execSQL(SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2);
324+
db.execSQL(SQL_CREATE_IN_APP_MESSAGE_ENTRIES);
325+
for (String ind : SQL_INDEX_ENTRIES) {
326+
db.execSQL(ind);
327+
}
320328
}
321329
}
322330

323331
@Override
324332
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
325333
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OneSignal Database onUpgrade from: " + oldVersion + " to: " + newVersion);
326-
try {
327-
internalOnUpgrade(db, oldVersion);
328-
} catch (SQLiteException e) {
329-
// This could throw if rolling back then forward again.
330-
// However this shouldn't happen as we clearing the database on onDowngrade
331-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error in upgrade, migration may have already run! Skipping!" , e);
334+
synchronized (LOCK) {
335+
try {
336+
internalOnUpgrade(db, oldVersion);
337+
} catch (SQLiteException e) {
338+
// This could throw if rolling back then forward again.
339+
// However this shouldn't happen as we clearing the database on onDowngrade
340+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error in upgrade, migration may have already run! Skipping!", e);
341+
}
332342
}
333343
}
334344

335-
private synchronized void internalOnUpgrade(SQLiteDatabase db, int oldVersion) {
345+
private void internalOnUpgrade(SQLiteDatabase db, int oldVersion) {
336346
if (oldVersion < 2)
337347
upgradeToV2(db);
338348

@@ -404,7 +414,7 @@ private static void upgradeToV7(SQLiteDatabase db) {
404414
safeExecSQL(db, SQL_CREATE_IN_APP_MESSAGE_ENTRIES);
405415
}
406416

407-
private synchronized void upgradeToV8(SQLiteDatabase db) {
417+
private void upgradeToV8(SQLiteDatabase db) {
408418
outcomeTableProvider.upgradeOutcomeTableRevision2To3(db);
409419
outcomeTableProvider.upgradeCacheOutcomeTableRevision1To2(db);
410420
}
@@ -420,24 +430,25 @@ private static void safeExecSQL(SQLiteDatabase db, String sql) {
420430
@Override
421431
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
422432
OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "SDK version rolled back! Clearing " + DATABASE_NAME + " as it could be in an unexpected state.");
433+
synchronized (LOCK) {
434+
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
435+
try {
436+
List<String> tables = new ArrayList<>(cursor.getCount());
423437

424-
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
425-
try {
426-
List<String> tables = new ArrayList<>(cursor.getCount());
427-
428-
while (cursor.moveToNext())
429-
tables.add(cursor.getString(0));
438+
while (cursor.moveToNext())
439+
tables.add(cursor.getString(0));
430440

431-
for (String table : tables) {
432-
if (table.startsWith("sqlite_"))
433-
continue;
434-
db.execSQL("DROP TABLE IF EXISTS " + table);
441+
for (String table : tables) {
442+
if (table.startsWith("sqlite_"))
443+
continue;
444+
db.execSQL("DROP TABLE IF EXISTS " + table);
445+
}
446+
} finally {
447+
cursor.close();
435448
}
436-
} finally {
437-
cursor.close();
438-
}
439449

440-
onCreate(db);
450+
onCreate(db);
451+
}
441452
}
442453

443454
static StringBuilder recentUninteractedWithNotificationsWhere() {

0 commit comments

Comments
 (0)