Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to SQLite implementation of EntitiesRepository #6290

Merged
merged 44 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7a0812b
Add database implementation for entities with list management
seadowg Jul 24, 2024
1b03dd7
Move database specific code to shared
seadowg Jul 24, 2024
dc0cdf6
Add extensions for working with SQLite
seadowg Jul 24, 2024
b0b0ea8
Flesh out DatabaseEntitiesRepository implementation
seadowg Jul 24, 2024
bb52a63
Handle getEntities before any are added
seadowg Jul 24, 2024
96c86e5
Use database repository implementation
seadowg Jul 24, 2024
ea61916
Use nested query to get index
seadowg Jul 25, 2024
06dc4a8
Fix empty db cases
seadowg Jul 25, 2024
64025e1
Check table exists before trying to create
seadowg Jul 25, 2024
aeab0e0
Create list row and table in transaction to prevent one existing with…
seadowg Jul 25, 2024
a9c8f83
Only create list once and add index to id
seadowg Jul 29, 2024
7acc306
Avoid existing checks when creating a new list
seadowg Jul 29, 2024
794bb85
Just create one index
seadowg Jul 29, 2024
1b08ace
Use rowid table instead of nested query
seadowg Jul 29, 2024
095f930
Use one transaction to speed up large entity list inserts
seadowg Jul 29, 2024
80581ba
Use sized ArrayList to speed up all entities queries
seadowg Jul 29, 2024
dc737f8
Use forEach to speed up processing CSV entities
seadowg Jul 30, 2024
c82aff0
Rename test class
seadowg Jul 31, 2024
69ab128
Split saved and blank form reset tests
seadowg Jul 31, 2024
780b52b
Reduce actions in test
seadowg Jul 31, 2024
7166f31
Reset entities with saved forms
seadowg Jul 31, 2024
1899256
Update string
seadowg Jul 31, 2024
9b9b0ac
Remvoe deprecated dependeny lookups in ProjectResetter
seadowg Jul 31, 2024
7a45b7e
Remove experimental entities Clear All
seadowg Jul 31, 2024
37ae67f
Remove Json entities implementation
seadowg Aug 5, 2024
3cf7776
Always create entities locally
seadowg Aug 5, 2024
e9d381a
Parse forms without using configured XFormParser to avoid problems
seadowg Aug 5, 2024
47d24fb
Enable local entities by default
seadowg Aug 5, 2024
17f84c9
Correct typo
seadowg Aug 7, 2024
13ddce3
Make onUpgrade a no-op
seadowg Aug 7, 2024
014008d
Improve tests to make sure that entities are deleted when calling #clear
seadowg Aug 7, 2024
605558a
Remove debug println
seadowg Aug 7, 2024
c818abf
Rename method
seadowg Aug 7, 2024
0f417b6
Make class private
seadowg Aug 8, 2024
47d4176
Extract constant for rowid
seadowg Aug 8, 2024
b4e1055
Pull out helpers for querying with rowid table
seadowg Aug 8, 2024
53e1ce5
Move class to database package
seadowg Aug 8, 2024
727cc07
Simplify #first
seadowg Aug 8, 2024
ad54d8e
Remove logs
seadowg Aug 8, 2024
31efad7
Update test name
seadowg Aug 8, 2024
65a1f9d
Move SQLiteUtils to shared
seadowg Aug 8, 2024
e35cd63
Move test for SQLiteUtils
seadowg Aug 8, 2024
31aa8c1
Remove unused dependency
seadowg Aug 8, 2024
8e69198
Move enum conversion to repo implementation
seadowg Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.odk.collect.android.database
package org.odk.collect.androidshared.sqlite

import android.content.Context
import android.content.ContextWrapper
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.odk.collect.androidshared.sqlite

import android.database.Cursor
import androidx.core.database.getIntOrNull
import androidx.core.database.getStringOrNull

object CursorExt {
seadowg marked this conversation as resolved.
Show resolved Hide resolved
fun <T> Cursor.foldAndClose(initial: T, operation: (T, Cursor) -> T): T {
return this.use {
it.moveToPosition(-1)

var accumulator = initial
while (it.moveToNext()) {
accumulator = operation(accumulator, it)
}

accumulator
}
}

fun <T> Cursor.foldAndClose(operation: (Cursor) -> T): List<T> {
return this.use {
it.moveToPosition(-1)

val accumulator = ArrayList<T>(it.count)
while (it.moveToNext()) {
accumulator.add(operation(it))
}

accumulator
}
}

fun <T> Cursor.first(map: (Cursor) -> T): T? {
return this.use {
if (it.moveToFirst()) {
map(it)
} else {
return null
}
}
}

fun Cursor.getString(column: String): String {
val columnIndex = this.getColumnIndex(column)
return this.getString(columnIndex)
}

fun Cursor.getStringOrNull(column: String): String? {
val columnIndex = this.getColumnIndex(column)
return this.getStringOrNull(columnIndex)
}

fun Cursor.getLong(column: String): Long {
val columnIndex = this.getColumnIndex(column)
return this.getLong(columnIndex)
}

fun Cursor.getInt(column: String): Int {
val columnIndex = this.getColumnIndex(column)
return this.getInt(columnIndex)
}

fun Cursor.getIntOrNull(column: String): Int? {
val columnIndex = this.getColumnIndex(column)
return this.getIntOrNull(columnIndex)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.odk.collect.android.utilities;
package org.odk.collect.androidshared.sqlite;

import org.odk.collect.shared.strings.StringUtils;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.odk.collect.android.utilities;
package org.odk.collect.androidshared.sqlite;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.odk.collect.android.database
package org.odk.collect.androidshared.sqlite
grzesiek2010 marked this conversation as resolved.
Show resolved Hide resolved

import android.content.Context
import android.database.sqlite.SQLiteDatabase
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.odk.collect.android.database;
package org.odk.collect.androidshared.sqlite;
seadowg marked this conversation as resolved.
Show resolved Hide resolved

import android.database.sqlite.SQLiteDatabase;

Expand All @@ -8,4 +8,4 @@ public interface DatabaseMigrator {
void onUpgrade(SQLiteDatabase db, int oldVersion);

void onDowngrade(SQLiteDatabase db);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.odk.collect.androidshared.sqlite

object SQLiteColumns {
const val ROW_ID = "rowid"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.odk.collect.androidshared.sqlite

import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteQueryBuilder

object SQLiteDatabaseExt {
grzesiek2010 marked this conversation as resolved.
Show resolved Hide resolved
fun SQLiteDatabase.query(
table: String,
selection: String? = null,
selectionArgs: Array<String?>? = null
): Cursor {
val qb = SQLiteQueryBuilder().apply {
tables = table
}

return qb.query(this, null, selection, selectionArgs, null, null, null)
}

fun SQLiteDatabase.delete(table: String) {
this.delete(table, null, null)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.odk.collect.android.utilities;
package org.odk.collect.androidshared.sqlite;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
* limitations under the License.
*/

package org.odk.collect.android.utilities;
package org.odk.collect.androidshared.sqlite;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class CustomSQLiteQueryBuilderTest {

private final String[] columns = {"_id", "col1", "col2", "col3"};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package org.odk.collect.android.utilities;
package org.odk.collect.androidshared.sqlite;

import static android.content.Context.MODE_PRIVATE;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;

import android.database.sqlite.SQLiteDatabase;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.odk.collect.android.application.Collect;

import java.util.ArrayList;
import java.util.List;

import static android.content.Context.MODE_PRIVATE;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;

@RunWith(AndroidJUnit4.class)
public class SQLiteUtilsTest {

@Test
public void doesColumnExistTest() {
String tableName = "testTable";

SQLiteDatabase db = Collect.getInstance().openOrCreateDatabase("testDatabase", MODE_PRIVATE, null);
SQLiteDatabase db = ApplicationProvider.getApplicationContext().openOrCreateDatabase("testDatabase", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE " + tableName + " (id integer, column1 text);");

assertTrue(SQLiteUtils.doesColumnExist(db, tableName, "id"));
Expand All @@ -36,7 +36,7 @@ public void doesTableExistTest() {
final String tableName = "testTable";
final String columnName = CustomSQLiteQueryBuilder.quoteIdentifier("col");

SQLiteDatabase db = Collect.getInstance().openOrCreateDatabase("testDatabase", MODE_PRIVATE, null);
SQLiteDatabase db = ApplicationProvider.getApplicationContext().openOrCreateDatabase("testDatabase", MODE_PRIVATE, null);

assertFalse(SQLiteUtils.doesTableExist(db, tableName));

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith
import org.odk.collect.android.support.StubOpenRosaServer.EntityListItem
import org.odk.collect.android.support.StubOpenRosaServer.MediaFileItem
import org.odk.collect.android.support.TestDependencies
import org.odk.collect.android.support.pages.FormEntryPage
import org.odk.collect.android.support.pages.MainMenuPage
Expand All @@ -23,26 +22,6 @@ class EntityFormTest {
val ruleChain: RuleChain = TestRuleChain.chain(testDependencies)
.around(rule)

@Test
fun fillingEntityRegistrationForm_doesNotShowEntitiesInNonEntityListForm() {
testDependencies.server.addForm("one-question-entity-registration.xml")
testDependencies.server.addForm(
"one-question-entity-update.xml",
listOf(MediaFileItem("people.csv"))
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Registration")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("Name", "Logan Roy"))

.startBlankForm("One Question Entity Update")
.assertQuestion("Select person")
.assertText("Roman Roy")
.assertTextDoesNotExist("Logan Roy")
}

@Test
fun fillingEntityRegistrationForm_createsEntityForFollowUpForms() {
testDependencies.server.addForm("one-question-entity-registration.xml")
Expand All @@ -52,8 +31,6 @@ class EntityFormTest {
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Registration")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("Name", "Logan Roy"))

Expand All @@ -72,8 +49,6 @@ class EntityFormTest {
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Update") // Open to create cached form def
.pressBackAndDiscardForm()

Expand All @@ -94,8 +69,6 @@ class EntityFormTest {
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Update")
.assertQuestion("Select person")
.clickOnText("Roman Roy")
Expand All @@ -118,8 +91,6 @@ class EntityFormTest {
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Registration")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("Name", "Logan Roy"))

Expand All @@ -137,8 +108,6 @@ class EntityFormTest {
)

rule.withMatchExactlyProject(testDependencies.server.url)
.enableLocalEntitiesInForms()

.startBlankForm("One Question Entity Update")
.assertQuestion("Select person")
.clickOnText("Roman Roy")
Expand Down Expand Up @@ -167,8 +136,6 @@ class EntityFormTest {
}

rule.withProject(testDependencies.server)
.enableLocalEntitiesInForms()

.clickGetBlankForm()
.clickClearAll()
.clickForm("One Question Entity Update")
Expand All @@ -185,4 +152,24 @@ class EntityFormTest {
.assertText("Ro-Ro Roy")
.assertTextDoesNotExist("Roman Roy")
}

@Test
fun disablingLocalEntities_stopsThemFromBeingShownInFollowUpForms() {
testDependencies.server.addForm("one-question-entity-registration.xml")
testDependencies.server.addForm(
"one-question-entity-update.xml",
listOf(EntityListItem("people.csv"))
)

rule.withMatchExactlyProject(testDependencies.server.url)
.startBlankForm("One Question Entity Registration")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("Name", "Logan Roy"))

.disableLocalEntitiesInForms()

.startBlankForm("One Question Entity Update")
.assertQuestion("Select person")
.assertText("Roman Roy")
.assertTextDoesNotExist("Logan Roy")
}
}
Loading