Skip to content

Commit e435af3

Browse files
committed
Fix IAM tracking DB migration
* Fix migration from 4 to 5, keep old SQL query to continue with v8 migration correctly
1 parent 282a3df commit e435af3

File tree

8 files changed

+321
-181
lines changed

8 files changed

+321
-181
lines changed

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

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
import java.util.ArrayList;
4444
import java.util.List;
4545

46+
import static com.onesignal.outcomes.OSOutcomeTableProvider.SQL_CREATE_OUTCOME_ENTRIES_V1;
47+
import static com.onesignal.outcomes.OSOutcomeTableProvider.SQL_CREATE_OUTCOME_ENTRIES_V3;
48+
import static com.onesignal.outcomes.OSOutcomeTableProvider.SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V1;
49+
import static com.onesignal.outcomes.OSOutcomeTableProvider.SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2;
50+
4651
class OneSignalDbHelper extends SQLiteOpenHelper implements OneSignalDb {
4752
static final int DATABASE_VERSION = 8;
4853
private static final String DATABASE_NAME = "OneSignal.db";
@@ -164,8 +169,8 @@ public synchronized SQLiteDatabase getSQLiteDatabaseWithRetries() {
164169
@Override
165170
public void onCreate(SQLiteDatabase db) {
166171
db.execSQL(SQL_CREATE_ENTRIES);
167-
db.execSQL(outcomeTableProvider.getSqlCreateOutcomeEntries());
168-
db.execSQL(outcomeTableProvider.getSqlCreateUniqueOutcomeEntries());
172+
db.execSQL(SQL_CREATE_OUTCOME_ENTRIES_V3);
173+
db.execSQL(SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2);
169174
db.execSQL(SQL_CREATE_IN_APP_MESSAGE_ENTRIES);
170175
for (String ind : SQL_INDEX_ENTRIES) {
171176
db.execSQL(ind);
@@ -235,21 +240,21 @@ private static void upgradeToV3(SQLiteDatabase db) {
235240
}
236241

237242
private static void upgradeToV4(SQLiteDatabase db) {
238-
safeExecSQL(db, outcomeTableProvider.getSqlCreateOutcomeEntries());
243+
safeExecSQL(db, SQL_CREATE_OUTCOME_ENTRIES_V1);
239244
}
240245

241246
private static void upgradeToV5(SQLiteDatabase db) {
242247
// Added for 3.12.1
243-
safeExecSQL(db, outcomeTableProvider.getSqlCreateUniqueOutcomeEntries());
248+
safeExecSQL(db, SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V1);
244249
// Added for 3.12.2
245-
upgradeOutcomeTableRevision1To2(db);
250+
upgradeFromV5ToV6(db);
246251
}
247252

248253
// We only want to run this if going from DB v5 to v6 specifically since
249-
// it was originally missed in upgradeToV5 in 3.12.1
254+
// it was originally missed in upgradeToV5 in 3.12.1
250255
// Added for 3.12.2
251256
private static void upgradeFromV5ToV6(SQLiteDatabase db) {
252-
upgradeOutcomeTableRevision1To2(db);
257+
outcomeTableProvider.upgradeOutcomeTableRevision1To2(db);
253258
}
254259

255260
private static void upgradeToV7(SQLiteDatabase db) {
@@ -261,33 +266,6 @@ private synchronized void upgradeToV8(SQLiteDatabase db) {
261266
outcomeTableProvider.upgradeCacheOutcomeTableRevision1To2(db);
262267
}
263268

264-
// On the outcome table this adds the new weight column and drops params column.
265-
private static void upgradeOutcomeTableRevision1To2(SQLiteDatabase db) {
266-
String commonColumns = "_id,name,session,timestamp,notification_ids";
267-
try {
268-
// Since SQLite does not support dropping a column we need to:
269-
// 1. Create a temptable
270-
// 2. Copy outcome table into it
271-
// 3. Drop the outcome table
272-
// 4. Recreate it with the correct fields
273-
// 5. Copy the temptable rows back into the new outcome table
274-
// 6. Drop the temptable.
275-
db.execSQL("BEGIN TRANSACTION;");
276-
db.execSQL("CREATE TEMPORARY TABLE outcome_backup(" + commonColumns + ");");
277-
db.execSQL("INSERT INTO outcome_backup SELECT " + commonColumns + " FROM outcome;");
278-
db.execSQL("DROP TABLE outcome;");
279-
db.execSQL(outcomeTableProvider.getSqlCreateOutcomeEntries());
280-
// Not converting weight from param here, just set to zero.
281-
// 3.12.1 quickly replaced 3.12.0 so converting cache isn't critical.
282-
db.execSQL("INSERT INTO outcome (" + commonColumns + ", weight) SELECT " + commonColumns + ", 0 FROM outcome_backup;");
283-
db.execSQL("DROP TABLE outcome_backup;");
284-
} catch (SQLiteException e) {
285-
e.printStackTrace();
286-
} finally {
287-
db.execSQL("COMMIT;");
288-
}
289-
}
290-
291269
private static void safeExecSQL(SQLiteDatabase db, String sql) {
292270
try {
293271
db.execSQL(sql);

OneSignalSDK/onesignal/src/main/java/com/onesignal/outcomes/OSOutcomeTableProvider.java

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,29 @@ public class OSOutcomeTableProvider {
2020
public static final String CACHE_UNIQUE_OUTCOME_COLUMN_CHANNEL_INFLUENCE_ID = CachedUniqueOutcomeTable.COLUMN_CHANNEL_INFLUENCE_ID;
2121
public static final String CACHE_UNIQUE_OUTCOME_COLUMN_CHANNEL_TYPE = CachedUniqueOutcomeTable.COLUMN_CHANNEL_TYPE;
2222

23-
private static final String SQL_CREATE_OUTCOME_ENTRIES =
23+
public static final String SQL_CREATE_OUTCOME_ENTRIES_V1 =
24+
"CREATE TABLE " + OutcomeEventsTable.TABLE_NAME + " (" +
25+
OutcomeEventsTable._ID + " INTEGER PRIMARY KEY," +
26+
OutcomeEventsTable.COLUMN_NAME_NOTIFICATION_IDS + TEXT_TYPE + "," +
27+
OutcomeEventsTable.COLUMN_NAME_NAME + TEXT_TYPE + "," +
28+
OutcomeEventsTable.COLUMN_NAME_SESSION + TEXT_TYPE + "," +
29+
OutcomeEventsTable.COLUMN_NAME_PARAMS + TEXT_TYPE + "," +
30+
OutcomeEventsTable.COLUMN_NAME_TIMESTAMP + " TIMESTAMP" +
31+
");";
32+
33+
public static final String SQL_CREATE_OUTCOME_ENTRIES_V2 =
34+
"CREATE TABLE " + OutcomeEventsTable.TABLE_NAME + " (" +
35+
OutcomeEventsTable._ID + INTEGER_PRIMARY_KEY_TYPE + "," +
36+
OutcomeEventsTable.COLUMN_NAME_SESSION + TEXT_TYPE + "," +
37+
OutcomeEventsTable.COLUMN_NAME_NOTIFICATION_IDS + TEXT_TYPE + "," +
38+
OutcomeEventsTable.COLUMN_NAME_NAME + TEXT_TYPE + "," +
39+
OutcomeEventsTable.COLUMN_NAME_TIMESTAMP + TIMESTAMP_TYPE + "," +
40+
// "params TEXT" Added in v4, removed in v5.
41+
OutcomeEventsTable.COLUMN_NAME_WEIGHT + FLOAT_TYPE + // New in v5, missing migration added in v6
42+
");";
43+
44+
45+
public static final String SQL_CREATE_OUTCOME_ENTRIES_V3 =
2446
"CREATE TABLE " + OutcomeEventsTable.TABLE_NAME + " (" +
2547
OutcomeEventsTable._ID + INTEGER_PRIMARY_KEY_TYPE + "," +
2648
OutcomeEventsTable.COLUMN_NAME_NOTIFICATION_INFLUENCE_TYPE + TEXT_TYPE + "," +
@@ -33,14 +55,55 @@ public class OSOutcomeTableProvider {
3355
OutcomeEventsTable.COLUMN_NAME_WEIGHT + FLOAT_TYPE + // New in v5, missing migration added in v6
3456
");";
3557

36-
private static final String SQL_CREATE_UNIQUE_OUTCOME_ENTRIES =
37-
"CREATE TABLE " + CachedUniqueOutcomeTable.TABLE_NAME + " (" +
58+
public static final String SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V1 =
59+
"CREATE TABLE " + CachedUniqueOutcomeTable.TABLE_NAME_V1 + " (" +
60+
CachedUniqueOutcomeTable._ID + INTEGER_PRIMARY_KEY_TYPE + "," +
61+
CachedUniqueOutcomeTable.COLUMN_NAME_NOTIFICATION_ID + TEXT_TYPE + "," +
62+
CachedUniqueOutcomeTable.COLUMN_NAME_NAME + TEXT_TYPE +
63+
");";
64+
65+
66+
public static final String SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2 =
67+
"CREATE TABLE " + CachedUniqueOutcomeTable.TABLE_NAME_V2 + " (" +
3868
CachedUniqueOutcomeTable._ID + INTEGER_PRIMARY_KEY_TYPE + "," +
3969
CachedUniqueOutcomeTable.COLUMN_CHANNEL_INFLUENCE_ID + TEXT_TYPE + "," +
4070
CachedUniqueOutcomeTable.COLUMN_CHANNEL_TYPE + TEXT_TYPE + "," +
4171
CachedUniqueOutcomeTable.COLUMN_NAME_NAME + TEXT_TYPE +
4272
");";
4373

74+
/**
75+
* On the outcome table this adds the new weight column and drops params column.
76+
*/
77+
public void upgradeOutcomeTableRevision1To2(SQLiteDatabase db) {
78+
String commonColumns = OutcomeEventsTable._ID + "," +
79+
OutcomeEventsTable.COLUMN_NAME_SESSION+ "," +
80+
OutcomeEventsTable.COLUMN_NAME_NOTIFICATION_IDS + "," +
81+
OutcomeEventsTable.COLUMN_NAME_NAME + "," +
82+
OutcomeEventsTable.COLUMN_NAME_TIMESTAMP;
83+
try {
84+
// Since SQLite does not support dropping a column we need to:
85+
// 1. Create a temptable
86+
// 2. Copy outcome table into it
87+
// 3. Drop the outcome table
88+
// 4. Recreate it with the correct fields
89+
// 5. Copy the temptable rows back into the new outcome table
90+
// 6. Drop the temptable.
91+
db.execSQL("BEGIN TRANSACTION;");
92+
db.execSQL("CREATE TEMPORARY TABLE outcome_backup(" + commonColumns + ");");
93+
db.execSQL("INSERT INTO outcome_backup SELECT " + commonColumns + " FROM outcome;");
94+
db.execSQL("DROP TABLE outcome;");
95+
db.execSQL(SQL_CREATE_OUTCOME_ENTRIES_V2);
96+
// Not converting weight from param here, just set to zero.
97+
// 3.12.1 quickly replaced 3.12.0 so converting cache isn't critical.
98+
db.execSQL("INSERT INTO outcome (" + commonColumns + ", weight) SELECT " + commonColumns + ", 0 FROM outcome_backup;");
99+
db.execSQL("DROP TABLE outcome_backup;");
100+
} catch (SQLiteException e) {
101+
e.printStackTrace();
102+
} finally {
103+
db.execSQL("COMMIT;");
104+
}
105+
}
106+
44107
/**
45108
* On the outcome table rename session column to notification influence type
46109
* Add columns for iam ids and iam influence type
@@ -66,7 +129,7 @@ public void upgradeOutcomeTableRevision2To3(SQLiteDatabase db) {
66129
// 4. Drop altered table
67130
db.execSQL("BEGIN TRANSACTION;");
68131
db.execSQL("ALTER TABLE " + OutcomeEventsTable.TABLE_NAME + " RENAME TO " + auxOutcomeTableName + ";");
69-
db.execSQL(getSqlCreateOutcomeEntries());
132+
db.execSQL(SQL_CREATE_OUTCOME_ENTRIES_V3);
70133
db.execSQL("INSERT INTO " + OutcomeEventsTable.TABLE_NAME + "(" + commonColumnsWithNewSessionColumn + ")" +
71134
" SELECT " + commonColumnsWithSessionColumn + " FROM " + auxOutcomeTableName + ";");
72135
db.execSQL("DROP TABLE " + auxOutcomeTableName + ";");
@@ -89,7 +152,7 @@ public void upgradeCacheOutcomeTableRevision1To2(SQLiteDatabase db) {
89152
String commonColumnsWithNotificationIdColumn = commonColumns + "," + CachedUniqueOutcomeTable.COLUMN_NAME_NOTIFICATION_ID;
90153
String commonColumnsWithNewInfluenceIdColumn = commonColumns + "," + CachedUniqueOutcomeTable.COLUMN_CHANNEL_INFLUENCE_ID;
91154

92-
String oldCacheUniqueOutcomeTable = CachedUniqueOutcomeTable.OLD_TABLE_NAME;
155+
String oldCacheUniqueOutcomeTable = CachedUniqueOutcomeTable.TABLE_NAME_V1;
93156
try {
94157
// Since SQLite does not support dropping a column we need to:
95158
// See https://www.techonthenet.com/sqlite/tables/alter_table.php
@@ -98,10 +161,10 @@ public void upgradeCacheOutcomeTableRevision1To2(SQLiteDatabase db) {
98161
// 3. Copy data to new table
99162
// 4. Drop altered table
100163
db.execSQL("BEGIN TRANSACTION;");
101-
db.execSQL(getSqlCreateUniqueOutcomeEntries());
102-
db.execSQL("INSERT INTO " + CachedUniqueOutcomeTable.TABLE_NAME + "(" + commonColumnsWithNewInfluenceIdColumn + ")" +
164+
db.execSQL(SQL_CREATE_UNIQUE_OUTCOME_ENTRIES_V2);
165+
db.execSQL("INSERT INTO " + CachedUniqueOutcomeTable.TABLE_NAME_V2 + "(" + commonColumnsWithNewInfluenceIdColumn + ")" +
103166
" SELECT " + commonColumnsWithNotificationIdColumn + " FROM " + oldCacheUniqueOutcomeTable + ";");
104-
db.execSQL("UPDATE " + CachedUniqueOutcomeTable.TABLE_NAME +
167+
db.execSQL("UPDATE " + CachedUniqueOutcomeTable.TABLE_NAME_V2 +
105168
" SET " + CachedUniqueOutcomeTable.COLUMN_CHANNEL_TYPE + " = \'" + OSInfluenceChannel.NOTIFICATION.toString() + "\';");
106169
db.execSQL("DROP TABLE " + oldCacheUniqueOutcomeTable + ";");
107170
} catch (SQLiteException e) {
@@ -111,17 +174,4 @@ public void upgradeCacheOutcomeTableRevision1To2(SQLiteDatabase db) {
111174
}
112175
}
113176

114-
/**
115-
* Testing mock purposes
116-
*/
117-
public String getSqlCreateOutcomeEntries() {
118-
return SQL_CREATE_OUTCOME_ENTRIES;
119-
}
120-
121-
/**
122-
* Testing mock purposes
123-
*/
124-
public String getSqlCreateUniqueOutcomeEntries() {
125-
return SQL_CREATE_UNIQUE_OUTCOME_ENTRIES;
126-
}
127177
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/outcomes/OSOutcomesDbContract.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@
55
class OSOutcomesDbContract {
66

77
public static class OutcomeEventsTable implements BaseColumns {
8-
static final String TABLE_NAME = "outcome";
8+
static final String TABLE_NAME = "outcome"; // Added on DB v4 SDK v3.12.0
99
// Influence ids
10-
static final String COLUMN_NAME_NOTIFICATION_IDS = "notification_ids"; // OneSignal Notification Ids
11-
static final String COLUMN_NAME_IAM_IDS = "iam_ids"; // OneSignal iam Ids
10+
static final String COLUMN_NAME_NOTIFICATION_IDS = "notification_ids"; // Added on DB v4 SDK v3.12.0
11+
static final String COLUMN_NAME_IAM_IDS = "iam_ids"; // Added on DB v8 SDK v3.14.0
1212
// Influence type
13-
static final String COLUMN_NAME_SESSION = "session"; // Old column name
14-
static final String COLUMN_NAME_NOTIFICATION_INFLUENCE_TYPE = "notification_influence_type";
15-
static final String COLUMN_NAME_IAM_INFLUENCE_TYPE = "iam_influence_type";
13+
static final String COLUMN_NAME_SESSION = "session"; // Added on DB v4 SDK v3.12.0 replaced with notification_influence_type on DB v8 SDK v3.14.0
14+
static final String COLUMN_NAME_NOTIFICATION_INFLUENCE_TYPE = "notification_influence_type"; // Added on DB v8 SDK v3.14.0
15+
static final String COLUMN_NAME_IAM_INFLUENCE_TYPE = "iam_influence_type"; // Added on DB v8 SDK v3.14.0
1616
// Outcome data
17-
static final String COLUMN_NAME_NAME = "name";
18-
static final String COLUMN_NAME_WEIGHT = "weight";
19-
static final String COLUMN_NAME_TIMESTAMP = "timestamp";
17+
static final String COLUMN_NAME_NAME = "name"; // Added on DB v4 SDK v3.12.0
18+
static final String COLUMN_NAME_WEIGHT = "weight"; // Added on DB v5 SDK v3.12.1, migration added on DB v6 SDK v3.12.2
19+
static final String COLUMN_NAME_TIMESTAMP = "timestamp"; // Added on DB v4 SDK v3.12.0
20+
static final String COLUMN_NAME_PARAMS = "params"; // Added on DB v4 SDK v3.12.0 replaced with weight on DB v5 SDK v3.12.1, migration added on DB v6 SDK v3.12.2
2021
}
2122

2223
static class CachedUniqueOutcomeTable implements BaseColumns {
23-
static final String OLD_TABLE_NAME = "cached_unique_outcome_notification"; // Old table name
24-
static final String TABLE_NAME = "cached_unique_outcome";
25-
static final String COLUMN_NAME_NOTIFICATION_ID = "notification_id"; // Old column name
26-
static final String COLUMN_CHANNEL_INFLUENCE_ID = "channel_influence_id"; // OneSignal Channel influence Id
27-
static final String COLUMN_CHANNEL_TYPE = "channel_type"; // OneSignal Channel Type
28-
static final String COLUMN_NAME_NAME = "name";
24+
static final String TABLE_NAME = CachedUniqueOutcomeTable.TABLE_NAME_V2;
25+
static final String TABLE_NAME_V1 = "cached_unique_outcome_notification"; // Added on DB v5 SDK v3.12.1 until DB v8 renamed with cached_unique_outcome SDK v3.14.0
26+
static final String TABLE_NAME_V2 = "cached_unique_outcome"; // Added on DB v8 SDK v3.14.0
27+
static final String COLUMN_NAME_NOTIFICATION_ID = "notification_id"; // Added on DB v5 SDK v3.12.1 until DB v8 renamed with channel_influence_id SDK v3.14.0
28+
static final String COLUMN_CHANNEL_INFLUENCE_ID = "channel_influence_id"; // Added on DB v8 SDK v3.14.0
29+
static final String COLUMN_CHANNEL_TYPE = "channel_type"; // Added on DB v8 SDK v3.14.0
30+
static final String COLUMN_NAME_NAME = "name"; // Added on DB v5 SDK v3.12.1
2931
}
3032
}

OneSignalSDK/unittest/src/test/java/com/onesignal/MockOneSignalDBHelper.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ public MockOneSignalDBHelper(Context context) {
1313
this.context = context;
1414
}
1515

16-
public void setOutcomeTableProvider(OSOutcomeTableProvider outcomeTableProvider) {
17-
OneSignalDbHelper.getInstance(context).setOutcomeTableProvider(outcomeTableProvider);
18-
}
19-
2016
@Override
2117
public SQLiteDatabase getSQLiteDatabaseWithRetries() {
2218
return OneSignalDbHelper.getInstance(context).getSQLiteDatabaseWithRetries();

OneSignalSDK/unittest/src/test/java/com/onesignal/outcomes/MockOSCachedUniqueOutcomeTable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
public class MockOSCachedUniqueOutcomeTable extends OSOutcomesDbContract.CachedUniqueOutcomeTable {
44

5-
public static final String OLD_TABLE_NAME = OSOutcomesDbContract.CachedUniqueOutcomeTable.OLD_TABLE_NAME;
6-
public static final String TABLE_NAME = OSOutcomesDbContract.CachedUniqueOutcomeTable.TABLE_NAME;
5+
public static final String TABLE_NAME_V1 = OSOutcomesDbContract.CachedUniqueOutcomeTable.TABLE_NAME_V1;
6+
public static final String TABLE_NAME_V2 = OSOutcomesDbContract.CachedUniqueOutcomeTable.TABLE_NAME_V2;
77
public static final String COLUMN_NAME_NOTIFICATION_ID = OSOutcomesDbContract.CachedUniqueOutcomeTable.COLUMN_NAME_NOTIFICATION_ID;
88
public static final String COLUMN_CHANNEL_INFLUENCE_ID = OSOutcomesDbContract.CachedUniqueOutcomeTable.COLUMN_CHANNEL_INFLUENCE_ID;
99
public static final String COLUMN_CHANNEL_TYPE = OSOutcomesDbContract.CachedUniqueOutcomeTable.COLUMN_CHANNEL_TYPE;

OneSignalSDK/unittest/src/test/java/com/onesignal/outcomes/MockOSOutcomeTableProvider.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)