Skip to content

Commit 167aa5c

Browse files
committed
Added tests for upgrade
1 parent d92ef7c commit 167aa5c

File tree

8 files changed

+291
-31
lines changed

8 files changed

+291
-31
lines changed

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/TransportContext.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.android.datatransport.runtime;
1616

17+
import androidx.annotation.Nullable;
1718
import androidx.annotation.RestrictTo;
1819
import com.google.android.datatransport.Priority;
1920
import com.google.auto.value.AutoValue;
@@ -26,6 +27,9 @@ public abstract class TransportContext {
2627
/** Backend events are sent to. */
2728
public abstract String getBackendName();
2829

30+
@Nullable
31+
public abstract byte[] getExtras();
32+
2933
/**
3034
* Priority of the event.
3135
*
@@ -39,7 +43,9 @@ public abstract class TransportContext {
3943

4044
/** Returns a new builder for {@link TransportContext}. */
4145
public static Builder builder() {
42-
return new AutoValue_TransportContext.Builder().setPriority(Priority.DEFAULT);
46+
return new AutoValue_TransportContext.Builder()
47+
.setPriority(Priority.DEFAULT)
48+
.setExtras("sd".getBytes());
4349
}
4450

4551
/**
@@ -58,6 +64,8 @@ public abstract static class Builder {
5864

5965
public abstract Builder setBackendName(String name);
6066

67+
public abstract Builder setExtras(@Nullable byte[] extras);
68+
6169
/** @hide */
6270
@RestrictTo(RestrictTo.Scope.LIBRARY)
6371
public abstract Builder setPriority(Priority priority);

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/scheduling/persistence/DatabaseBootstrapClient.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,28 @@ class DatabaseBootstrapClient {
2525
private final String createEventBackendIndex;
2626
private final String createContextBackedPriorityIndex;
2727

28+
private final String dropEventsSql;
29+
private final String dropEventMetadataSql;
30+
private final String dropContextsSql;
31+
2832
@Inject
2933
DatabaseBootstrapClient(
3034
@Named("CREATE_EVENTS_SQL") String createEventsSql,
3135
@Named("CREATE_EVENT_METADATA_SQL") String createEventMetadataSql,
3236
@Named("CREATE_CONTEXTS_SQL") String createContextsSql,
3337
@Named("CREATE_EVENT_BACKEND_INDEX") String createEventBackendIndex,
34-
@Named("CREATE_CONTEXT_BACKEND_PRIORITY_INDEX") String createContextBackendPriorityIndex) {
38+
@Named("CREATE_CONTEXT_BACKEND_PRIORITY_INDEX") String createContextBackendPriorityIndex,
39+
@Named("DROP_EVENTS_SQL") String dropEventsSql,
40+
@Named("DROP_EVENT_METADATA_SQL") String dropEventMetadataSql,
41+
@Named("DROP_CONTEXTS_SQL") String dropContextsSql) {
3542
this.createEventsSql = createEventsSql;
3643
this.createEventMetadataSql = createEventMetadataSql;
3744
this.createContextsSql = createContextsSql;
3845
this.createEventBackendIndex = createEventBackendIndex;
3946
this.createContextBackedPriorityIndex = createContextBackendPriorityIndex;
47+
this.dropEventsSql = dropEventsSql;
48+
this.dropEventMetadataSql = dropEventMetadataSql;
49+
this.dropContextsSql = dropContextsSql;
4050
}
4151

4252
void bootstrap(SQLiteDatabase db) {
@@ -46,4 +56,11 @@ void bootstrap(SQLiteDatabase db) {
4656
db.execSQL(createEventBackendIndex);
4757
db.execSQL(createContextBackedPriorityIndex);
4858
}
59+
60+
void teardown(SQLiteDatabase db) {
61+
db.execSQL(dropEventsSql);
62+
db.execSQL(dropEventMetadataSql);
63+
db.execSQL(dropContextsSql);
64+
// Indices are dropped automatically when the tables are dropped
65+
}
4966
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.google.android.datatransport.runtime.scheduling.persistence;
2+
3+
import android.database.sqlite.SQLiteDatabase;
4+
import java.util.List;
5+
6+
class DatabaseMigrationClient {
7+
private final List<Migration> incrementalMigrations;
8+
9+
DatabaseMigrationClient(List<Migration> incrementalMigrations) {
10+
this.incrementalMigrations = incrementalMigrations;
11+
}
12+
13+
void upgrade(SQLiteDatabase db, int fromVersion, int toVersion) {
14+
for (Migration m : incrementalMigrations) {
15+
m.upgrade(db, fromVersion, toVersion);
16+
}
17+
}
18+
19+
public interface Migration {
20+
void upgrade(SQLiteDatabase db, int fromVersion, int toVersion);
21+
}
22+
}

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/scheduling/persistence/EventStoreModule.java

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import dagger.Binds;
1919
import dagger.Module;
2020
import dagger.Provides;
21+
import java.util.Collections;
2122
import javax.inject.Named;
2223

2324
@Module
2425
public abstract class EventStoreModule {
25-
static final String CREATE_EVENTS_SQL_V1 =
26+
27+
static final String CREATE_EVENTS_SQL_V2 =
2628
"CREATE TABLE events "
2729
+ "(_id INTEGER PRIMARY KEY,"
2830
+ " context_id INTEGER NOT NULL,"
@@ -34,26 +36,43 @@ public abstract class EventStoreModule {
3436
+ " num_attempts INTEGER NOT NULL,"
3537
+ "FOREIGN KEY (context_id) REFERENCES transport_contexts(_id) ON DELETE CASCADE)";
3638

37-
static final String CREATE_EVENT_METADATA_SQL_V1 =
39+
static final String CREATE_EVENT_METADATA_SQL_V2 =
3840
"CREATE TABLE event_metadata "
3941
+ "(_id INTEGER PRIMARY KEY,"
4042
+ " event_id INTEGER NOT NULL,"
4143
+ " name TEXT NOT NULL,"
4244
+ " value TEXT NOT NULL,"
4345
+ "FOREIGN KEY (event_id) REFERENCES events(_id) ON DELETE CASCADE)";
4446

45-
static final String CREATE_CONTEXTS_SQL_V1 =
47+
static final String CREATE_CONTEXTS_SQL_V2 =
4648
"CREATE TABLE transport_contexts "
4749
+ "(_id INTEGER PRIMARY KEY,"
4850
+ " backend_name TEXT NOT NULL,"
4951
+ " priority INTEGER NOT NULL,"
50-
+ " next_request_ms INTEGER NOT NULL)";
52+
+ " next_request_ms INTEGER NOT NULL,"
53+
+ " extras BLOB)";
5154

52-
static final String CREATE_EVENT_BACKEND_INDEX_V1 =
55+
static final String CREATE_EVENT_BACKEND_INDEX_V2 =
5356
"CREATE INDEX events_backend_id on events(context_id)";
5457

55-
static final String CREATE_CONTEXT_BACKEND_PRIORITY_INDEX_V1 =
56-
"CREATE UNIQUE INDEX contexts_backend_priority on transport_contexts(backend_name, priority)";
58+
static final String CREATE_CONTEXT_BACKEND_PRIORITY_EXTRAS_INDEX_V2 =
59+
"CREATE UNIQUE INDEX contexts_backend_priority_extras on transport_contexts(backend_name, priority, extras)";
60+
61+
static final String DROP_EVENTS_SQL = "DROP TABLE events";
62+
63+
static final String DROP_EVENT_METADATA_SQL = "DROP TABLE event_metadata";
64+
65+
static final String DROP_CONTEXTS_SQL = "DROP TABLE transport_contexts";
66+
67+
static final DatabaseMigrationClient.Migration migrateToV2 =
68+
(db, fromVersion, toVersion) -> {
69+
if (fromVersion == 1 && toVersion == 2) {
70+
db.execSQL("ALTER TABLE transport_contexts ADD COLUMN extras BLOB");
71+
db.execSQL(
72+
"CREATE UNIQUE INDEX contexts_backend_priority_extras on transport_contexts(backend_name, priority, extras)");
73+
db.execSQL("DROP INDEX contexts_backend_priority");
74+
}
75+
};
5776

5877
@Provides
5978
static EventStoreConfig storeConfig() {
@@ -69,30 +88,53 @@ static EventStoreConfig storeConfig() {
6988
@Provides
7089
@Named("CREATE_EVENTS_SQL")
7190
static String createEventsSql() {
72-
return CREATE_EVENTS_SQL_V1;
91+
return CREATE_EVENTS_SQL_V2;
7392
}
7493

7594
@Provides
7695
@Named("CREATE_EVENT_METADATA_SQL")
7796
static String createEventMetadataSql() {
78-
return CREATE_EVENT_METADATA_SQL_V1;
97+
return CREATE_EVENT_METADATA_SQL_V2;
7998
}
8099

81100
@Provides
82101
@Named("CREATE_CONTEXTS_SQL")
83102
static String createContextsSql() {
84-
return CREATE_CONTEXTS_SQL_V1;
103+
return CREATE_CONTEXTS_SQL_V2;
85104
}
86105

87106
@Provides
88107
@Named("CREATE_EVENT_BACKEND_INDEX")
89108
static String getCreateEventBackendIndex() {
90-
return CREATE_EVENT_BACKEND_INDEX_V1;
109+
return CREATE_EVENT_BACKEND_INDEX_V2;
91110
}
92111

93112
@Provides
94113
@Named("CREATE_CONTEXT_BACKEND_PRIORITY_INDEX")
95114
static String createEventBackendPriorityIndex() {
96-
return CREATE_CONTEXT_BACKEND_PRIORITY_INDEX_V1;
115+
return CREATE_CONTEXT_BACKEND_PRIORITY_EXTRAS_INDEX_V2;
116+
}
117+
118+
@Provides
119+
@Named("DROP_EVENTS_SQL")
120+
static String dropEventsSQL() {
121+
return DROP_EVENTS_SQL;
122+
}
123+
124+
@Provides
125+
@Named("DROP_EVENT_METADATA_SQL")
126+
static String dropEventMetadataSql() {
127+
return DROP_EVENT_METADATA_SQL;
128+
}
129+
130+
@Provides
131+
@Named("DROP_CONTEXTS_SQL")
132+
static String dropContextsSql() {
133+
return DROP_CONTEXTS_SQL;
134+
}
135+
136+
@Provides
137+
static DatabaseMigrationClient createDatabaseMigrationClient() {
138+
return new DatabaseMigrationClient(Collections.singletonList(migrateToV2));
97139
}
98140
}

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/scheduling/persistence/SQLiteEventStore.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ private long ensureTransportContext(SQLiteDatabase db, TransportContext transpor
127127
record.put("backend_name", transportContext.getBackendName());
128128
record.put("priority", transportContext.getPriority().ordinal());
129129
record.put("next_request_ms", 0);
130+
record.put("extras", transportContext.getExtras());
131+
130132
return db.insert("transport_contexts", null, record);
131133
}
132134

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/scheduling/persistence/SchemaManager.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@ final class SchemaManager extends SQLiteOpenHelper {
2424
// upgrades work as expected, e.g. `up+down+up` is equivalent to `up`.
2525
private static int SCHEMA_VERSION = 1;
2626
private static final String DB_NAME = "com.google.android.datatransport.events";
27-
private final DatabaseBootstrapClient databaseBootstrapClient;
27+
private final DatabaseBootstrapClient bootstrapClient;
28+
private final DatabaseMigrationClient migrationClient;
2829
private boolean configured = false;
2930

3031
@Inject
31-
SchemaManager(Context context, DatabaseBootstrapClient databaseBootstrapClient) {
32+
SchemaManager(
33+
Context context,
34+
DatabaseBootstrapClient bootstrapClient,
35+
DatabaseMigrationClient migrationClient) {
3236
super(context, DB_NAME, null, SCHEMA_VERSION);
33-
this.databaseBootstrapClient = databaseBootstrapClient;
37+
this.bootstrapClient = bootstrapClient;
38+
this.migrationClient = migrationClient;
3439
}
3540

3641
@Override
@@ -55,17 +60,19 @@ private void ensureConfigured(SQLiteDatabase db) {
5560
@Override
5661
public void onCreate(SQLiteDatabase db) {
5762
ensureConfigured(db);
58-
databaseBootstrapClient.bootstrap(db);
63+
bootstrapClient.bootstrap(db);
5964
}
6065

6166
@Override
6267
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
6368
ensureConfigured(db);
69+
migrationClient.upgrade(db, oldVersion, newVersion);
6470
}
6571

6672
@Override
6773
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
68-
ensureConfigured(db);
74+
bootstrapClient.teardown(db);
75+
onCreate(db);
6976
}
7077

7178
@Override

transport/transport-runtime/src/test/java/com/google/android/datatransport/runtime/scheduling/persistence/SQLiteEventStoreTest.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.android.datatransport.runtime.scheduling.persistence;
1616

17+
import static com.google.android.datatransport.runtime.scheduling.persistence.EventStoreModule.*;
1718
import static com.google.common.truth.Truth.assertThat;
1819

1920
import com.google.android.datatransport.Priority;
@@ -60,11 +61,15 @@ private static SQLiteEventStore newStoreWithConfig(Clock clock, EventStoreConfig
6061
new SchemaManager(
6162
RuntimeEnvironment.application,
6263
new DatabaseBootstrapClient(
63-
EventStoreModule.CREATE_EVENTS_SQL_V1,
64-
EventStoreModule.CREATE_EVENT_METADATA_SQL_V1,
65-
EventStoreModule.CREATE_CONTEXTS_SQL_V1,
66-
EventStoreModule.CREATE_EVENT_BACKEND_INDEX_V1,
67-
EventStoreModule.CREATE_CONTEXT_BACKEND_PRIORITY_INDEX_V1)));
64+
CREATE_EVENTS_SQL_V2,
65+
CREATE_EVENT_METADATA_SQL_V2,
66+
CREATE_CONTEXTS_SQL_V2,
67+
CREATE_EVENT_BACKEND_INDEX_V2,
68+
CREATE_CONTEXT_BACKEND_PRIORITY_EXTRAS_INDEX_V2,
69+
DROP_EVENTS_SQL,
70+
DROP_EVENT_METADATA_SQL,
71+
DROP_CONTEXTS_SQL),
72+
new DatabaseMigrationClient(Collections.singletonList(migrateToV2))));
6873
}
6974

7075
@Test

0 commit comments

Comments
 (0)