Java tutorial
/* * Copyright (C) 2015 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.opendatakit.utilities; import android.Manifest; import android.content.ContentValues; import android.database.Cursor; import android.support.test.filters.LargeTest; import android.support.test.rule.GrantPermissionRule; import com.fasterxml.jackson.core.JsonProcessingException; import org.apache.commons.lang3.CharEncoding; import org.junit.Rule; import org.junit.Test; import org.opendatakit.aggregate.odktables.rest.ConflictType; import org.opendatakit.aggregate.odktables.rest.ElementDataType; import org.opendatakit.aggregate.odktables.rest.ElementType; import org.opendatakit.aggregate.odktables.rest.KeyValueStoreConstants; import org.opendatakit.aggregate.odktables.rest.RFC4180CsvReader; import org.opendatakit.aggregate.odktables.rest.SavepointTypeManipulator; import org.opendatakit.aggregate.odktables.rest.SyncState; import org.opendatakit.aggregate.odktables.rest.TableConstants; import org.opendatakit.aggregate.odktables.rest.entity.Column; import org.opendatakit.aggregate.odktables.rest.entity.RowFilterScope; import org.opendatakit.database.DatabaseConstants; import org.opendatakit.database.RoleConsts; import org.opendatakit.database.data.BaseTable; import org.opendatakit.database.data.ColumnDefinition; import org.opendatakit.database.data.KeyValueStoreEntry; import org.opendatakit.database.data.OrderedColumns; import org.opendatakit.database.data.Row; import org.opendatakit.database.data.TableDefinitionEntry; import org.opendatakit.database.data.UserTable; import org.opendatakit.database.service.DbHandle; import org.opendatakit.database.utilities.CursorUtils; import org.opendatakit.database.utilities.KeyValueStoreUtils; import org.opendatakit.database.utilities.QueryUtil; import org.opendatakit.exception.ActionNotAuthorizedException; import org.opendatakit.logging.WebLogger; import org.opendatakit.provider.ChoiceListColumns; import org.opendatakit.provider.ColumnDefinitionsColumns; import org.opendatakit.provider.DataTableColumns; import org.opendatakit.provider.KeyValueStoreColumns; import org.opendatakit.provider.TableDefinitionsColumns; import org.opendatakit.services.database.AndroidConnectFactory; import org.opendatakit.services.database.OdkConnectionFactorySingleton; import org.opendatakit.services.database.OdkConnectionInterface; import org.opendatakit.services.database.utilities.ODKDatabaseImplUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Created by wrb on 9/21/2015. * * Put the actual unit tests in this Abstract class as there are two setups for running these tests * * In ODKDatabaseImplUtilsKeepState it keeps the database initalized between tests whereas * in ODKDatabaseImplUtilsResetState, it wipes the database from the file system between each test */ public abstract class AbstractODKDatabaseUtilsTest { private static final String TAG = "AbstractODKDatabaseUtilsTest"; private static final String localTestTable = "L_testTable"; private static final String testTable = "testTable"; private static final String elemKey = "_element_key"; private static final String elemName = "_element_name"; private static final String listChildElemKeys = "_list_child_element_keys"; private static final String activeUser = "anonymous"; private static final String currentLocale = "en_US"; protected OdkConnectionInterface db; protected abstract String getAppName(); protected void verifyNoTablesExistNCleanAllTables() { /* NOTE: if there is a problem it might be the fault of the previous test if the assertion failure is happening in the setUp function as opposed to the tearDown function */ List<String> tableIds = ODKDatabaseImplUtils.get().getAllTableIds(db); boolean tablesGone = (tableIds.size() == 0); // Drop any leftover table now that the test is done for (String id : tableIds) { ODKDatabaseImplUtils.get().deleteTableAndAllData(db, id); } assertTrue(tablesGone); } public void verifyNoTablesExist() { List<String> tableIds = ODKDatabaseImplUtils.get().getAllTableIds(db); assertTrue(tableIds.size() == 0); } /* * Check that the database is setup */ @Test public void testPreConditions() { assertNotNull(db); } /* * Test creation of user defined database table when table doesn't exist */ @Test public void testCreateOrOpenTableWhenTableDoesNotExist_ExpectPass() { verifyNoTablesExist(); // Create the database table String tableName = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableName, columns); // Check that the table exists Cursor cursor = db .rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "'", null); assertNotNull("Cursor is null", cursor); assertEquals("Cursor should only have 1 row", cursor.getCount(), 1); cursor.moveToFirst(); assertEquals("Name of user defined table does not match", cursor.getString(0), tableName); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableName); verifyNoTablesExist(); } @Rule public GrantPermissionRule writeRuntimePermissionRule = GrantPermissionRule .grant(Manifest.permission.WRITE_EXTERNAL_STORAGE); @Rule public GrantPermissionRule readtimePermissionRule = GrantPermissionRule .grant(Manifest.permission.READ_EXTERNAL_STORAGE); /* * Test query when there is no data */ @Test public void testQueryWithNoData_ExpectFail() { String tableId = testTable; boolean thrown = false; try { // this will not interact with the database if the // query string is found in the PreparedStatement cache. Cursor c = ODKDatabaseImplUtils.get().queryForTest(db, tableId, null, null, null, null, null, null, null); // we must get the count of rows to actually interact // with the database. c.getCount(); } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); } /* * Test query when there is data */ @Test public void testQueryWithData_ExpectPass() { String tableId = testTable; List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", "string", "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); // Check that the user defined rows are in the table Cursor cursor = ODKDatabaseImplUtils.get().queryForTest(db, tableId, null, null, null, null, null, null, null); Cursor refCursor = db.query(tableId, null, null, null, null, null, null, null); if (cursor != null && refCursor != null) { int index = 0; while (cursor.moveToNext() && refCursor.moveToNext()) { int testType = cursor.getType(index); int refType = refCursor.getType(index); assertEquals(testType, refType); switch (refType) { case Cursor.FIELD_TYPE_BLOB: byte[] byteArray = cursor.getBlob(index); byte[] refByteArray = refCursor.getBlob(index); assertEquals(byteArray, refByteArray); break; case Cursor.FIELD_TYPE_FLOAT: float valueFloat = cursor.getFloat(index); float refValueFloat = refCursor.getFloat(index); assertEquals(valueFloat, refValueFloat, 0.0); break; case Cursor.FIELD_TYPE_INTEGER: int valueInt = cursor.getInt(index); int refValueInt = refCursor.getInt(index); assertEquals(valueInt, refValueInt); break; case Cursor.FIELD_TYPE_STRING: String valueStr = cursor.getString(index); String refValueStr = refCursor.getString(index); assertEquals(valueStr, refValueStr); break; case Cursor.FIELD_TYPE_NULL: default: break; } } } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test raw query when there is data */ @Test public void testRawQueryWithNoData_ExpectFail() { String tableId = testTable; String query = "SELECT * FROM " + tableId; boolean thrown = false; try { ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // this will not interact with the database if the // query string is found in the PreparedStatement cache. Cursor c = ODKDatabaseImplUtils.get().rawQuery(db, query, null, null, accessContext); // we must get the count of rows to actually interact // with the database. c.getCount(); } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); } /* * Test raw query when there is no data */ @Test public void testRawQueryWithData_ExpectPass() { String tableId = testTable; String query = "SELECT * FROM " + tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", "string", "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Check that the user defined rows are in the table Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, query, null, null, accessContext); Cursor refCursor = db.rawQuery(query, null); if (cursor != null && refCursor != null) { int index = 0; while (cursor.moveToNext() && refCursor.moveToNext()) { int testType = cursor.getType(index); int refType = refCursor.getType(index); assertEquals(testType, refType); switch (refType) { case Cursor.FIELD_TYPE_BLOB: byte[] byteArray = cursor.getBlob(index); byte[] refByteArray = refCursor.getBlob(index); assertEquals(byteArray, refByteArray); break; case Cursor.FIELD_TYPE_FLOAT: float valueFloat = cursor.getFloat(index); float refValueFloat = refCursor.getFloat(index); assertEquals(valueFloat, refValueFloat, 0.0); break; case Cursor.FIELD_TYPE_INTEGER: int valueInt = cursor.getInt(index); int refValueInt = refCursor.getInt(index); assertEquals(valueInt, refValueInt); break; case Cursor.FIELD_TYPE_STRING: String valueStr = cursor.getString(index); String refValueStr = refCursor.getString(index); assertEquals(valueStr, refValueStr); break; case Cursor.FIELD_TYPE_NULL: default: break; } } } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when table does * not exist */ @Test public void testCreateOrOpenTableWithColumnWhenColumnDoesNotExist_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test updating the data in a local table with valid values when the id already exists */ @Test public void testUpdateDataInExistingLocalTableWithIdWhenIdAlreadyExists_ExpectPass() throws ActionNotAuthorizedException { String tableId = localTestTable; ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.USER_ROLES_LIST); String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); String testStrCol = "testStrColumn"; String testStrColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); columns.add(new Column(testStrCol, testStrCol, testStrColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createLocalOnlyTableWithColumns(db, tableId, columns); int testVal = 5; String testStrVal = "five"; boolean thrown = false; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); cvValues.put(testStrCol, testStrVal); ODKDatabaseImplUtils.get().insertLocalOnlyRow(db, tableId, cvValues); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; Object[] selArgs = new Object[1]; selArgs[0] = testVal; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; String valStr = null; while (cursor.moveToNext()) { { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } { int indStr = cursor.getColumnIndex(testStrCol); int typeStr = cursor.getType(indStr); assertEquals(typeStr, Cursor.FIELD_TYPE_STRING); valStr = cursor.getString(indStr); } } assertEquals(val, testVal); assertEquals(valStr, testStrVal); // Try updating that row in the database int testVal2 = 25; String testStrVal2 = "twenty-five"; ContentValues cvValues2 = new ContentValues(); cvValues2.put(testCol, testVal2); cvValues2.put(testStrCol, testStrVal2); ODKDatabaseImplUtils.get().updateLocalOnlyRow(db, tableId, cvValues2, testCol + "= ?", selArgs); // Select everything out of the table String sel2 = "SELECT * FROM " + tableId; Object[] selArgs2 = new Object[0]; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); int val2 = 0; String valStr2 = null; while (cursor2.moveToNext()) { { int ind = cursor2.getColumnIndex(testCol); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val2 = cursor2.getInt(ind); } { int indStr = cursor2.getColumnIndex(testStrCol); int typeStr = cursor2.getType(indStr); assertEquals(typeStr, Cursor.FIELD_TYPE_STRING); valStr2 = cursor2.getString(indStr); } } assertEquals(val2, testVal2); assertEquals(valStr2, testStrVal2); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteLocalOnlyTable(db, tableId); } /* * Test creation of user defined database table with column when table does * exist */ @Test public void testCreateOrOpenTableWithColumnWhenColumnDoesExist_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns orderedColumns2 = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * null */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsNull_ExpectFail() { String tableId = testTable; boolean thrown = false; OrderedColumns orderedColumns = null; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, null); } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * null */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsEmpty_ExpectPass() { String tableId = testTable; List<Column> columns = new ArrayList<Column>(); boolean thrown = false; OrderedColumns orderedColumns = null; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); } catch (Exception e) { thrown = true; e.printStackTrace(); } assertFalse(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is int */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsInt_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * array */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsArray_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String itemsStr = "items"; String testColItems = testCol + "_" + itemsStr; String testColType = ElementDataType.array.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColItems + "\"]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // no-op } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * array */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsArrayEmpty_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.array.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // no-op } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * array */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsArray_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String itemsStr = "items"; String testColItems = testCol + "_" + itemsStr; String testColType = ElementDataType.array.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColItems + "\"]")); columns.add(new Column(testColItems, itemsStr, ElementDataType.string.name(), "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 2); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); assertEquals(coldefs.getColumnDefinitions().get(1).getElementKey(), testColItems); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); if (key.equals(testCol)) { assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } else { assertTrue(key.equals(testColItems)); assertTrue(name.equals(itemsStr)); assertTrue(type.equals(ElementDataType.string.name())); } } // Select everything out of the table String[] selArgs = { "" + testCol }; Cursor cursor = ODKDatabaseImplUtils.get().queryForTest(db, DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, null, elemKey + " = ?", selArgs, null, null, null, null); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(listChildElemKeys); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String valStr = cursor.getString(ind); String testVal = "[\"" + testColItems + "\"]"; assertEquals(valStr, testVal); } // Select everything out of the table String[] selArgs2 = { testColItems }; cursor = ODKDatabaseImplUtils.get().queryForTest(db, DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, null, elemKey + " = ?", selArgs2, null, null, null, null); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(elemName); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String valStr = cursor.getString(ind); assertEquals(valStr, itemsStr); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * array */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsBoolean_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.bool.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * string */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsString_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * date */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsDate_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.DATE; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * datetime */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsDateTime_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.DATETIME; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * time */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsTime_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.TIME; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 1); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointLongMissing_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); columns.add(new Column(testColAcc, acc, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointAltMissing_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAcc, acc, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointAccMissing_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint and there is no list of children -- this is expected to succeed * because we do not have a separate table of data types. * * If we registered data types, we could detect the malformedness of the * geopoint data type (and we could even create the subelements based off of * the known definition of this datatype. */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointListMissing_ExpectSuccess() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertTrue(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointBadChildKey_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "d_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopointLatMissing_ExpectFail() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); columns.add(new Column(testColAcc, acc, testColResType, "[]")); boolean success = false; OrderedColumns orderedColumns; try { orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); success = true; } catch (IllegalArgumentException e) { // expected } assertFalse(success); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * geopoint */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsGeopoint_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String lat = "latitude"; String lng = "longitude"; String alt = "altitude"; String acc = "accuracy"; String testColLat = testCol + "_" + lat; String testColLng = testCol + "_" + lng; String testColAlt = testCol + "_" + alt; String testColAcc = testCol + "_" + acc; String testColType = ElementType.GEOPOINT; String testColResType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLng + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, lat, testColResType, "[]")); columns.add(new Column(testColLng, lng, testColResType, "[]")); columns.add(new Column(testColAlt, alt, testColResType, "[]")); columns.add(new Column(testColAcc, acc, testColResType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 5); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); assertEquals(coldefs.getColumnDefinitions().get(1).getElementKey(), testColAcc); assertEquals(coldefs.getColumnDefinitions().get(2).getElementKey(), testColAlt); assertEquals(coldefs.getColumnDefinitions().get(3).getElementKey(), testColLat); assertEquals(coldefs.getColumnDefinitions().get(4).getElementKey(), testColLng); List<String> cols = new ArrayList<String>(); cols.add(lat); cols.add(lng); cols.add(alt); cols.add(acc); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); if (key.equals(testCol)) { assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } else { assertTrue(key.equals(testCol + "_" + name)); assertTrue(cols.contains(name)); assertTrue(type.equals(testColResType)); } } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test creation of user defined database table with column when column is * mimeUri */ @Test public void testCreateOrOpenTableWithColumnWhenColumnIsMimeUri_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String uriFrag = "uriFragment"; String conType = "contentType"; String testColUriFrag = testCol + "_" + uriFrag; String testColContType = testCol + "_" + conType; String testColType = DataTypeNamesToRemove.MIMEURI; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColUriFrag + "\",\"" + testColContType + "\"]")); columns.add(new Column(testColUriFrag, "uriFragment", ElementDataType.rowpath.name(), "[]")); columns.add(new Column(testColContType, "contentType", ElementDataType.string.name(), "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns coldefs = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(coldefs.getColumnDefinitions().size(), 3); assertEquals(coldefs.getColumnDefinitions().get(0).getElementKey(), testCol); assertEquals(coldefs.getColumnDefinitions().get(1).getElementKey(), testColContType); assertEquals(coldefs.getColumnDefinitions().get(2).getElementKey(), testColUriFrag); List<String> cols = new ArrayList<String>(); cols.add(uriFrag); cols.add(conType); for (ColumnDefinition col : coldefs.getColumnDefinitions()) { String key = col.getElementKey(); String name = col.getElementName(); String type = col.getElementType(); if (key.equals(testCol)) { assertTrue(key.equals(testCol)); assertTrue(name.equals(testCol)); assertTrue(type.equals(testColType)); } else { assertTrue(key.equals(testCol + "_" + name)); assertTrue(cols.contains(name)); if (name.equals(uriFrag)) { assertTrue(type.equals(ElementDataType.rowpath.name())); } else { assertTrue(type.equals(ElementDataType.string.name())); } } } // Select everything out of the table for element key String[] selArgs = { "" + testCol }; Cursor cursor = ODKDatabaseImplUtils.get().queryForTest(db, DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, null, elemKey + " = ?", selArgs, null, null, null, null); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(listChildElemKeys); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String valStr = cursor.getString(ind); String testVal = "[\"" + testColUriFrag + "\",\"" + testColContType + "\"]"; assertEquals(valStr, testVal); } // Select everything out of the table for uriFragment String[] selArgs2 = { testColUriFrag }; cursor = ODKDatabaseImplUtils.get().queryForTest(db, DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, null, elemKey + " = ?", selArgs2, null, null, null, null); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(elemName); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String valStr = cursor.getString(ind); assertEquals(valStr, uriFrag); } // Select everything out of the table for contentType String[] selArgs3 = { testColContType }; cursor = ODKDatabaseImplUtils.get().queryForTest(db, DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, null, elemKey + " = ?", selArgs3, null, null, null, null); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(elemName); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String valStr = cursor.getString(ind); assertEquals(valStr, conType); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test getting all column names when columns exist */ @Test public void testGetAllColumnNamesWhenColumnsExist_ExpectPass() { String tableId = testTable; List<Column> columns = new ArrayList<Column>(); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); String[] colNames = ODKDatabaseImplUtils.get().getAllColumnNames(db, tableId); boolean colLength = (colNames.length > 0); assertTrue(colLength); Arrays.sort(colNames); List<String> defCols = ODKDatabaseImplUtils.get().getAdminColumns(); assertEquals(colNames.length, defCols.size()); for (int i = 0; i < colNames.length; i++) { assertEquals(colNames[i], defCols.get(i)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test getting all column names when table does not exist */ @Test public void testGetAllColumnNamesWhenTableDoesNotExist_ExpectFail() { String tableId = testTable; boolean thrown = false; try { String[] results = ODKDatabaseImplUtils.get().getAllColumnNames(db, tableId); } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); } /* * Test getting user defined column names when columns exist */ @Test public void testGetUserDefinedColumnNamesWhenColumnsExist_ExpectPass() { String tableId = testTable; List<Column> columns = new ArrayList<Column>(); columns.add(new Column("testCol", "testCol", "string", "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); OrderedColumns defns = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertEquals(defns.getColumnDefinitions().size(), 1); assertEquals(columns.size(), 1); Column cdref = ColumnDefinition.getColumns(defns.getColumnDefinitions()).get(0); Column cdalt = columns.get(0); assertEquals(cdref, cdalt); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test getting user defined column names when column does not exist */ @Test public void testGetUserDefinedColumnNamesWhenColumnDoesNotExist_ExpectPass() { String tableId = testTable; OrderedColumns defns = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertTrue(defns.getColumnDefinitions().isEmpty()); } /* * Test getting user defined column names when table does not exist */ @Test public void testGetUserDefinedColumnNamesWhenTableDoesNotExist_ExpectPass() { String tableId = testTable; OrderedColumns defns = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId); assertTrue(defns.getColumnDefinitions().isEmpty()); } /* * Test writing the data into the existing db table with all null values */ @Test public void testWriteDataIntoExistingTableWithAllNullValues_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); boolean thrown = false; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, null, null, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with valid values */ @Test public void testWriteDataIntoExistingTableWithValidValue_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with valid values and a * certain id */ @Test public void testWriteDataIntoExistingTableWithIdWhenIdDoesNotExist_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = UUID.randomUUID().toString(); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with valid values and an * existing id */ @Test public void testWriteDataIntoExistingTableWithIdWhenIdAlreadyExists_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; boolean thrown = false; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = UUID.randomUUID().toString(); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = null; try { cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } // Try updating that row in the database int testVal2 = 25; ContentValues cvValues2 = new ContentValues(); cvValues2.put(testCol, testVal2); try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues2, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (IllegalArgumentException e) { thrown = true; e.printStackTrace(); } assertEquals(thrown, true); /** * NOTE: we expect the log to report a failure to close this cursor. * It is GC'd and closed in its finalizer. This is confirming that * the finalizer is doing the right thing. */ // Select everything out of the table String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = {}; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); int val2 = 0; while (cursor2.moveToNext()) { int ind = cursor2.getColumnIndex(testCol); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val2 = cursor2.getInt(ind); } assertEquals(val2, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test updating the data in an existing db table with valid values when the * id does not exist */ @Test public void testUpdateDataInExistingTableWithIdWhenIdDoesNotExist_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = UUID.randomUUID().toString(); ODKDatabaseImplUtils.get().updateRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test updating the data in the existing db table with valid values when the * id already exists */ @Test public void testUpdateDataInExistingTableWithIdWhenIdAlreadyExists_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; boolean thrown = false; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = UUID.randomUUID().toString(); ODKDatabaseImplUtils.get().updateRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Try updating that row in the database int testVal2 = 25; ContentValues cvValues2 = new ContentValues(); cvValues2.put(testCol, testVal2); ODKDatabaseImplUtils.get().updateRowWithId(db, tableId, orderedColumns, cvValues2, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = {}; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); int val2 = 0; while (cursor2.moveToNext()) { int ind = cursor2.getColumnIndex(testCol); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val2 = cursor2.getInt(ind); } assertEquals(val2, testVal2); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with valid values and an * existing id */ @Test public void testWriteDataIntoExistingTableWithIdWhenIdIsNull_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); int testVal = 5; boolean thrown = false; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = null; try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data and metadata into the existing db table with valid * values */ @Test public void testWriteDataAndMetadataIntoExistingTableWithValidValue_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String uuid = UUID.randomUUID().toString(); String timeStamp = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); ContentValues cvValues = new ContentValues(); cvValues.put(DataTableColumns.ID, uuid); cvValues.putNull(DataTableColumns.ROW_ETAG); cvValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name()); cvValues.putNull(DataTableColumns.CONFLICT_TYPE); cvValues.putNull(DataTableColumns.DEFAULT_ACCESS); cvValues.putNull(DataTableColumns.ROW_OWNER); cvValues.putNull(DataTableColumns.GROUP_MODIFY); cvValues.putNull(DataTableColumns.GROUP_PRIVILEGED); cvValues.putNull(DataTableColumns.GROUP_READ_ONLY); cvValues.putNull(DataTableColumns.FORM_ID); cvValues.putNull(DataTableColumns.LOCALE); cvValues.putNull(DataTableColumns.SAVEPOINT_TYPE); cvValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP, timeStamp); cvValues.putNull(DataTableColumns.SAVEPOINT_CREATOR); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + DataTableColumns.ID + " = ?"; String[] selArgs = { uuid }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TIMESTAMP); String ts = cursor.getString(ind); assertEquals(ts, timeStamp); ind = cursor.getColumnIndex(DataTableColumns.SYNC_STATE); String ss = cursor.getString(ind); assertEquals(ss, SyncState.new_row.name()); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing writing metadata into an existing table when the rowID is null */ @Test public void testWriteDataAndMetadataIntoExistingTableWhenIDIsNull_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; boolean thrown = false; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); String timeStamp = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); ContentValues cvValues = new ContentValues(); cvValues.putNull(DataTableColumns.ID); cvValues.putNull(DataTableColumns.ROW_ETAG); cvValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name()); cvValues.putNull(DataTableColumns.CONFLICT_TYPE); cvValues.putNull(DataTableColumns.DEFAULT_ACCESS); cvValues.putNull(DataTableColumns.ROW_OWNER); cvValues.putNull(DataTableColumns.GROUP_MODIFY); cvValues.putNull(DataTableColumns.GROUP_PRIVILEGED); cvValues.putNull(DataTableColumns.GROUP_READ_ONLY); cvValues.putNull(DataTableColumns.FORM_ID); cvValues.putNull(DataTableColumns.LOCALE); cvValues.putNull(DataTableColumns.SAVEPOINT_TYPE); cvValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP, timeStamp); cvValues.putNull(DataTableColumns.SAVEPOINT_CREATOR); try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, null, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing metadata into the existing db table when sync state is null. * The sync state and other fields that should not be null will be silently * replaced with non-null values. */ @Test public void testWriteDataAndMetadataIntoExistingTableWhenSyncStateIsNull_ExpectSuccess() throws ActionNotAuthorizedException { String tableId = testTable; boolean thrown = false; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); String uuid = UUID.randomUUID().toString(); String timeStamp = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); ContentValues cvValues = new ContentValues(); cvValues.put(DataTableColumns.ID, uuid); cvValues.putNull(DataTableColumns.ROW_ETAG); cvValues.putNull(DataTableColumns.SYNC_STATE); cvValues.putNull(DataTableColumns.CONFLICT_TYPE); cvValues.putNull(DataTableColumns.DEFAULT_ACCESS); cvValues.putNull(DataTableColumns.ROW_OWNER); cvValues.putNull(DataTableColumns.GROUP_MODIFY); cvValues.putNull(DataTableColumns.GROUP_PRIVILEGED); cvValues.putNull(DataTableColumns.GROUP_READ_ONLY); cvValues.putNull(DataTableColumns.FORM_ID); cvValues.putNull(DataTableColumns.LOCALE); cvValues.putNull(DataTableColumns.SAVEPOINT_TYPE); cvValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP, timeStamp); cvValues.putNull(DataTableColumns.SAVEPOINT_CREATOR); try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertFalse(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing metadata into the existing db table when sync state is null */ @Test public void testWriteDataAndMetadataIntoExistingTableWhenTimeStampIsNull_ExpectFail() throws ActionNotAuthorizedException { // TODO: should this fail or succeed? String tableId = testTable; boolean thrown = false; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column("col1", "col1", testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); String uuid = UUID.randomUUID().toString(); ContentValues cvValues = new ContentValues(); cvValues.put(DataTableColumns.ID, uuid); cvValues.putNull(DataTableColumns.ROW_ETAG); cvValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name()); cvValues.putNull(DataTableColumns.CONFLICT_TYPE); cvValues.putNull(DataTableColumns.DEFAULT_ACCESS); cvValues.putNull(DataTableColumns.ROW_OWNER); cvValues.putNull(DataTableColumns.GROUP_MODIFY); cvValues.putNull(DataTableColumns.GROUP_PRIVILEGED); cvValues.putNull(DataTableColumns.GROUP_READ_ONLY); cvValues.putNull(DataTableColumns.FORM_ID); cvValues.putNull(DataTableColumns.LOCALE); cvValues.putNull(DataTableColumns.SAVEPOINT_TYPE); cvValues.putNull(DataTableColumns.SAVEPOINT_TIMESTAMP); cvValues.putNull(DataTableColumns.SAVEPOINT_CREATOR); try { ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } // TODO: should this fail or succeed? // assertTrue(thrown); assertFalse(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with array value */ @Test public void testWriteDataIntoExistingTableWithArray_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.array.name(); String testVal = "item"; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testCol + "_items\"]")); columns.add(new Column(testCol + "_items", "items", ElementDataType.string.name(), "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with boolean value */ @Test public void testWriteDataIntoExistingTableWithBoolean_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.bool.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 1; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with valid values */ @Test public void testWriteDataIntoExistingTableWithDate_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.DATE; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String testVal = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with datetime */ @Test public void testWriteDataIntoExistingTableWithDatetime_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.DATETIME; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String testVal = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with geopoint */ @Test public void testWriteDataIntoExistingTableWithGeopoint_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColLat = "testColumn_latitude"; String testColLong = "testColumn_longitude"; String testColAlt = "testColumn_altitude"; String testColAcc = "testColumn_accuracy"; double pos_lat = 5.55; double pos_long = 6.6; double pos_alt = 7.77; double pos_acc = 8.88; String testColType = ElementType.GEOPOINT; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColLat + "\",\"" + testColLong + "\",\"" + testColAlt + "\",\"" + testColAcc + "\"]")); columns.add(new Column(testColLat, "latitude", ElementDataType.number.name(), "[]")); columns.add(new Column(testColLong, "longitude", ElementDataType.number.name(), "[]")); columns.add(new Column(testColAlt, "altitude", ElementDataType.number.name(), "[]")); columns.add(new Column(testColAcc, "accuracy", ElementDataType.number.name(), "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testColLat, pos_lat); cvValues.put(testColLong, pos_long); cvValues.put(testColAlt, pos_alt); cvValues.put(testColAcc, pos_acc); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testColLat + " = ?"; String[] selArgs = { "" + pos_lat }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); double valLat = 0; double valLong = 0; double valAlt = 0; double valAcc = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testColLat); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_FLOAT); valLat = cursor.getDouble(ind); ind = cursor.getColumnIndex(testColLong); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_FLOAT); valLong = cursor.getDouble(ind); ind = cursor.getColumnIndex(testColAlt); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_FLOAT); valAlt = cursor.getDouble(ind); ind = cursor.getColumnIndex(testColAcc); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_FLOAT); valAcc = cursor.getDouble(ind); } assertEquals(valLat, pos_lat, 0.0); assertEquals(valLong, pos_long, 0.0); assertEquals(valAlt, pos_alt, 0.0); assertEquals(valAcc, pos_acc, 0.0); //cursor.close(); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with integer */ @Test public void testWriteDataIntoExistingTableWithInteger_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with mimeUri */ @Test public void testWriteDataIntoExistingTableWithMimeUri_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColUriFragment = "testColumn_uriFragment"; String testColContentType = "testColumn_contentType"; String testColType = DataTypeNamesToRemove.MIMEURI; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[\"" + testColUriFragment + "\",\"" + testColContentType + "\"]")); columns.add(new Column(testColUriFragment, "uriFragment", ElementDataType.rowpath.name(), "[]")); columns.add(new Column(testColContentType, "contentType", ElementDataType.string.name(), "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String uuid = UUID.randomUUID().toString(); String testUriFragment = "tables/example/instances/" + uuid + "/" + testCol + "-" + uuid + ".jpg"; String testContentType = "image/jpg"; ContentValues cvValues = new ContentValues(); cvValues.put(testColUriFragment, testUriFragment); cvValues.put(testColContentType, testContentType); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testColUriFragment + " = ?"; String[] selArgs = { "" + testUriFragment }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String valUriFragment = null; String valContentType = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testColUriFragment); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); valUriFragment = cursor.getString(ind); ind = cursor.getColumnIndex(testColContentType); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); valContentType = cursor.getString(ind); } assertEquals(valUriFragment, testUriFragment); assertEquals(valContentType, testContentType); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with number */ @Test public void testWriteDataIntoExistingTableWithNumber_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.number.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); double testVal = 5.5; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); double val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_FLOAT); val = cursor.getDouble(ind); } assertEquals(val, testVal, 0.0); // cursor.close(); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with string */ @Test public void testWriteDataIntoExistingTableWithString_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String testVal = "test"; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test writing the data into the existing db table with time */ @Test public void testWriteDataIntoExistingTableWithTime_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementType.TIME; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String interMed = TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()); int pos = interMed.indexOf('T'); String testVal = null; if (pos > -1) { testVal = interMed.substring(pos + 1); } else { fail("The conversion of the date time string to time is incorrect"); // Log.i(TAG, "Time string is " + interMed); } // Log.i(TAG, "Time string is " + testVal); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, LocalizationUtils.genUUID(), activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWhenRowAlreadyExists_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String testVal2 = "test2"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); ContentValues updatedCvValues = new ContentValues(); updatedCvValues.put(testCol, testVal2); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, updatedCvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 2); // Select everything out of the table sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; selArgs = new String[1]; selArgs[0] = "" + testVal2; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val2 = null; String saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val2 = cursor.getString(ind); // Get the savepoint_type ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); // Also make sure that the savepoint_type // is empty assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); assertNotSame(saveptType, SavepointTypeManipulator.complete()); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWhenRowDoesNotExist_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWhenRowIdNotProvided_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = null; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; String saveptType = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TIMESTAMP); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); saveptType = cursor.getString(ind); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, testVal); // Also make sure that the savepoint_type // is empty assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); assertNotSame(saveptType, SavepointTypeManipulator.complete()); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWithRowConflictType_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); cvValues.putNull(DataTableColumns.CONFLICT_TYPE); boolean thrown = true; try { ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWithRowSavepointType_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); cvValues.putNull(DataTableColumns.SAVEPOINT_TYPE); boolean thrown = true; try { ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdWithRowSavepointTimestamp_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); cvValues.putNull(DataTableColumns.SAVEPOINT_TIMESTAMP); boolean thrown = true; try { ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testInsertCheckpointRowIntoExistingTableWithIdAndNoData_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ContentValues cvValues = new ContentValues(); boolean thrown = true; try { ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test saving a checkpoint row in the database as complete */ @Test public void testSaveAsCompleteMostRecentCheckpointDataInTableWithId_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String testVal2 = "test2"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); ContentValues updatedCvValues = new ContentValues(); updatedCvValues.put(testCol, testVal2); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, updatedCvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 2); // Select everything out of the table sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; selArgs = new String[1]; selArgs[0] = "" + testVal2; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val2 = null; String saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val2 = cursor.getString(ind); // Get the savepoint_timestamp ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TIMESTAMP); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); saveptType = cursor.getString(ind); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); // Also make sure that the savepoint_type // is empty assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); assertNotSame(saveptType, SavepointTypeManipulator.complete()); ODKDatabaseImplUtils.get().saveAsCompleteMostRecentCheckpointRowWithId(db, tableId, rowId); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); val2 = null; saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val2 = cursor.getString(ind); // Get the savepoint_timestamp ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); saveptType = cursor.getString(ind); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); assertEquals(saveptType, SavepointTypeManipulator.complete()); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test saving a checkpoint row in the database as incomplete */ @Test public void testSaveAsIncompleteMostRecentCheckpointDataInTableWithId_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String testVal2 = "test2"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, testVal); ContentValues updatedCvValues = new ContentValues(); updatedCvValues.put(testCol, testVal2); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, updatedCvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 2); // Select everything out of the table sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; selArgs = new String[1]; selArgs[0] = "" + testVal2; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val2 = null; String saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val2 = cursor.getString(ind); // Get the savepoint_timestamp ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TIMESTAMP); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); saveptType = cursor.getString(ind); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); // Also make sure that the savepoint_type // is empty assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); assertNotSame(saveptType, SavepointTypeManipulator.complete()); ODKDatabaseImplUtils.get().saveAsIncompleteMostRecentCheckpointRowWithId(db, tableId, rowId); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); val2 = null; saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val2 = cursor.getString(ind); // Get the savepoint_timestamp ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); saveptType = cursor.getString(ind); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); assertEquals(saveptType, SavepointTypeManipulator.incomplete()); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test inserting a checkpoint row in the database */ @Test public void testDeleteLastCheckpointRowWithId_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, testVal); ODKDatabaseImplUtils.get().deleteLastCheckpointRowWithId(db, tableId, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 0); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test change data rows to new row state */ @Test public void testChangeDataRowsToNewRowState_ExpectPass() { // Test this after restructuring of the Sync code } // Added for the test below // Not sure if this needs to be public or not? private int countUpToLastNonNullElement(String[] row) { for (int i = row.length - 1; i >= 0; --i) { if (row[i] != null) { return (i + 1); } } return 0; } private void columnPropertiesHelper(String tableId, List<Column> columns, List<KeyValueStoreEntry> kvsEntries) { // reading data File file = null; FileInputStream in = null; InputStreamReader input = null; RFC4180CsvReader cr = null; try { file = new File(ODKFileUtils.getTableDefinitionCsvFile(getAppName(), tableId)); in = new FileInputStream(file); input = new InputStreamReader(in, CharEncoding.UTF_8); cr = new RFC4180CsvReader(input); String[] row; // Read ColumnDefinitions // get the column headers String[] colHeaders = cr.readNext(); int colHeadersLength = countUpToLastNonNullElement(colHeaders); // get the first row row = cr.readNext(); while (row != null && countUpToLastNonNullElement(row) != 0) { String elementKeyStr = null; String elementNameStr = null; String elementTypeStr = null; String listChildElementKeysStr = null; int rowLength = countUpToLastNonNullElement(row); for (int i = 0; i < rowLength; ++i) { if (i >= colHeadersLength) { throw new IllegalStateException("data beyond header row of ColumnDefinitions table"); } if (ColumnDefinitionsColumns.ELEMENT_KEY.equals(colHeaders[i])) { elementKeyStr = row[i]; } if (ColumnDefinitionsColumns.ELEMENT_NAME.equals(colHeaders[i])) { elementNameStr = row[i]; } if (ColumnDefinitionsColumns.ELEMENT_TYPE.equals(colHeaders[i])) { elementTypeStr = row[i]; } if (ColumnDefinitionsColumns.LIST_CHILD_ELEMENT_KEYS.equals(colHeaders[i])) { listChildElementKeysStr = row[i]; } } if (elementKeyStr == null || elementTypeStr == null) { throw new IllegalStateException("ElementKey and ElementType must be specified"); } columns.add(new Column(elementKeyStr, elementNameStr, elementTypeStr, listChildElementKeysStr)); // get next row or blank to end... row = cr.readNext(); } cr.close(); try { input.close(); } catch (IOException e) { } try { in.close(); } catch (IOException e) { } file = new File(ODKFileUtils.getTablePropertiesCsvFile(getAppName(), tableId)); in = new FileInputStream(file); input = new InputStreamReader(in, CharEncoding.UTF_8); cr = new RFC4180CsvReader(input); // Read KeyValueStore // read the column headers String[] kvsHeaders = cr.readNext(); // read the first row row = cr.readNext(); while (row != null && countUpToLastNonNullElement(row) != 0) { String partition = null; String aspect = null; String key = null; String type = null; String value = null; int rowLength = countUpToLastNonNullElement(row); for (int i = 0; i < rowLength; ++i) { if (KeyValueStoreColumns.PARTITION.equals(kvsHeaders[i])) { partition = row[i]; } if (KeyValueStoreColumns.ASPECT.equals(kvsHeaders[i])) { aspect = row[i]; } if (KeyValueStoreColumns.KEY.equals(kvsHeaders[i])) { key = row[i]; } if (KeyValueStoreColumns.VALUE_TYPE.equals(kvsHeaders[i])) { type = row[i]; } if (KeyValueStoreColumns.VALUE.equals(kvsHeaders[i])) { value = row[i]; } } KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), value); kvsEntries.add(kvsEntry); // get next row or blank to end... row = cr.readNext(); } cr.close(); try { input.close(); } catch (IOException e) { } try { in.close(); } catch (IOException e) { } } catch (Exception e) { e.printStackTrace(); } finally { try { if (input != null) { input.close(); } } catch (IOException e) { } } // Go through the KVS list and replace all the choiceList entries with their choiceListId for (KeyValueStoreEntry entry : kvsEntries) { if (entry.partition.equals(KeyValueStoreConstants.PARTITION_COLUMN) && entry.key.equals(KeyValueStoreConstants.COLUMN_DISPLAY_CHOICES_LIST)) { // stored type is a string -- the choiceListId entry.type = ElementDataType.string.name(); if ((entry.value != null) && (entry.value.trim().length() != 0)) { String choiceListId = ODKDatabaseImplUtils.get().setChoiceList(db, entry.value); entry.value = choiceListId; } else { entry.value = null; } } } } /* * Test create or open table with columns and properties */ @Test public void testCreateOrOpenTableWithColumnsAndProperties_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, KeyValueStoreConstants.PARTITION_TABLE, KeyValueStoreConstants.ASPECT_DEFAULT, KeyValueStoreConstants.COLUMN_DISPLAY_NAME, ElementDataType.valueOf(ElementDataType.object.name()), tableId); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } // Ensure that at least one of the expected properties is in the KVS table List<KeyValueStoreEntry> entries = ODKDatabaseImplUtils.get().getTableMetadata(db, null, KeyValueStoreConstants.PARTITION_TABLE, null, KeyValueStoreConstants.COLUMN_DISPLAY_NAME) .getEntries(); boolean found = false; for (KeyValueStoreEntry entry : entries) { if (entry.value != null && entry.value.equals(tableId)) { found = true; break; } } assertTrue("found at least one matching entry in KVS", found); // Now delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, null, null, null); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test delete checkpoint rows with id */ @Test public void testDeleteCheckpointRowsWithValidId_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, testVal); ODKDatabaseImplUtils.get().deleteAllCheckpointRowsWithId(db, tableId, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 0); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test delete checkpoint rows with id */ @Test public void testDeleteCheckpointRowsWithInvalidId_ExpectFail() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String testVal = "test"; String rowId = LocalizationUtils.genUUID(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, testVal); String invalidRowId = LocalizationUtils.genUUID(); boolean thrown = true; try { ODKDatabaseImplUtils.get().deleteAllCheckpointRowsWithId(db, tableId, invalidRowId, activeUser, RoleConsts.ADMIN_ROLES_LIST); } catch (ActionNotAuthorizedException ex) { throw ex; } catch (Exception e) { thrown = true; e.printStackTrace(); } assertTrue(thrown); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test delete db table metadata - delete all metadata */ @Test public void testDeleteTableMetadata_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.object.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } // Ensure that the expected properties is in the KVS table List<KeyValueStoreEntry> entries = ODKDatabaseImplUtils.get() .getTableMetadata(db, null, partition, null, key).getEntries(); assertEquals(entries.size(), 1); boolean found = false; for (KeyValueStoreEntry entry : entries) { if (entry.value != null && entry.value.equals(kvsValue)) { found = true; break; } } assertTrue("found the KVSEntry", found); // Now make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries, kvsEntries); // Now delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Ensure that the expected properties is in the KVS table entries = ODKDatabaseImplUtils.get().getTableMetadata(db, null, partition, null, key).getEntries(); assertEquals(entries.size(), 0); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test delete server conflict row with id * Place a row in conflict and then delete it */ @Test public void testDeleteServerConflictRowWithIdAndLocDelOldVals_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; // local record that is synced and pending deletion... ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); cvValues.put(DataTableColumns.ROW_ETAG, LocalizationUtils.genUUID()); cvValues.put(DataTableColumns.SYNC_STATE, SyncState.deleted.name()); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + DataTableColumns.ID + " = ? ORDER BY " + DataTableColumns.CONFLICT_TYPE + " ASC"; String[] selArgs = { rowId }; Cursor cursor = null; int val = 0; try { cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } } finally { cursor.close(); } assertEquals(val, testVal); // NOTE: all metadata fields need to be specified // server has a change... ContentValues updates = new ContentValues(); // data value updates.put(testCol, testVal + 6); // metadata fields updates.put(DataTableColumns.CONFLICT_TYPE, ConflictType.SERVER_UPDATED_UPDATED_VALUES); updates.put(DataTableColumns.SYNC_STATE, SyncState.in_conflict.name()); updates.put(DataTableColumns.ROW_ETAG, LocalizationUtils.genUUID()); // insert in_conflict server row updates.put(DataTableColumns.FORM_ID, "serverForm"); updates.put(DataTableColumns.LOCALE, currentLocale); updates.put(DataTableColumns.SAVEPOINT_TIMESTAMP, TableConstants.nanoSecondsFromMillis(System.currentTimeMillis())); updates.put(DataTableColumns.SAVEPOINT_TYPE, SavepointTypeManipulator.complete()); updates.put(DataTableColumns.SAVEPOINT_CREATOR, "mailto:server@gmail.com"); updates.put(DataTableColumns.DEFAULT_ACCESS, RowFilterScope.Access.FULL.name()); updates.put(DataTableColumns.ROW_OWNER, "mailto:server@gmail.com"); updates.putNull(DataTableColumns.GROUP_READ_ONLY); updates.putNull(DataTableColumns.GROUP_MODIFY); updates.putNull(DataTableColumns.GROUP_PRIVILEGED); // Place row in conflict int conflictType = ConflictType.LOCAL_DELETED_OLD_VALUES; ODKDatabaseImplUtils.get().privilegedPlaceRowIntoConflictWithId(db, tableId, orderedColumns, updates, rowId, conflictType, activeUser, currentLocale); // Run the query again and make sure that the place row in conflict worked as expected String whereClause = DataTableColumns.ID + "=?"; String[] selectionArgs = new String[] { rowId }; String[] orderByKeys = new String[] { DataTableColumns.CONFLICT_TYPE }; String[] orderByDirs = new String[] { "ASC" }; List<String> adminColumns = ODKDatabaseImplUtils.get().getAdminColumns(); String[] adminColArr = adminColumns.toArray(new String[adminColumns.size()]); BaseTable baseTable = ODKDatabaseImplUtils.get().query(db, tableId, QueryUtil.buildSqlStatement(tableId, whereClause, null, null, orderByKeys, orderByDirs), selectionArgs, null, accessContext); UserTable table = new UserTable(baseTable, orderedColumns, adminColArr); assertEquals(table.getNumberOfRows(), 2); Row first = table.getRowAtIndex(0); Row second = table.getRowAtIndex(1); String v; int conflictTypeVal; v = first.getDataByKey(DataTableColumns.CONFLICT_TYPE); assertNotNull(v); conflictTypeVal = Integer.valueOf(v); assertEquals(conflictType, conflictTypeVal); v = second.getDataByKey(DataTableColumns.CONFLICT_TYPE); assertNotNull(v); conflictTypeVal = Integer.valueOf(v); assertEquals(ConflictType.SERVER_UPDATED_UPDATED_VALUES, conflictTypeVal); // Now delete the row ODKDatabaseImplUtils.get().resolveServerConflictWithDeleteRowWithId(db, tableId, rowId, activeUser); // Run the query yet again to make sure that things worked as expected baseTable = ODKDatabaseImplUtils.get().query(db, tableId, QueryUtil.buildSqlStatement(tableId, whereClause, null, null, orderByKeys, orderByDirs), selectionArgs, null, accessContext); table = new UserTable(baseTable, orderedColumns, adminColArr); assertEquals(table.getNumberOfRows(), 0); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test delete server conflict row with id * Place a row in conflict and then delete it */ // @Test // public void testDeleteServerConflictRowWithIdAndLocUpdUpdVals_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.LOCAL_UPDATED_UPDATED_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoServerConflictWithId(db, tableId, orderedColumns, // cvValues, rowId, conflictType); // //ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 1); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Now delete the row // ODKDatabaseImplUtils.get().deleteServerConflictRowWithId(db, tableId, rowId); // // // Run the query yet again to make sure that things worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 1); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); //} /* * Test delete server conflict row with id * Place a row in conflict and then delete it */ // @Test // public void testDeleteServerConflictRowWithIdAndSrvDelOldValues_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.SERVER_DELETED_OLD_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 1); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Now delete the row // ODKDatabaseImplUtils.get().deleteServerConflictRowWithId(db, tableId, rowId); // // // Run the query yet again to make sure that things worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 0); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test delete server conflict row with id * Place a row in conflict and then delete it */ // @Test // public void testDeleteServerConflictRowWithIdAndSrvUpdUpdVals_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.SERVER_UPDATED_UPDATED_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 1); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Now delete the row // ODKDatabaseImplUtils.get().deleteServerConflictRowWithId(db, tableId, rowId); // // // Run the query yet again to make sure that things worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 0); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test enforce types table metadata */ @Test public void testEnforceTypesTableMetadata_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.integer.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); // createOrOpenTableWithColumnsAndProperties calls enforceTypesTableMetadata try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Ensure that the expected properties is in the KVS table String sel = "SELECT * FROM " + DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME + " WHERE " + KeyValueStoreColumns.PARTITION + " = ? AND " + KeyValueStoreColumns.KEY + " = ? AND " + KeyValueStoreColumns.VALUE + " = ?"; String[] selArgs = { partition, key, kvsValue }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Now make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries.size(), kvsEntries.size()); assertNotSame(retKVSEntries.get(0).type, kvsEntries.get(0).type); assertEquals(retKVSEntries.get(0).type, ElementDataType.object.name()); // Now make sure that the table has the right value for displayName cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(KeyValueStoreColumns.VALUE_TYPE); int resultType = cursor.getType(ind); assertEquals(resultType, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } // In this case the type should have been changed to string assertEquals(val, ElementDataType.object.name()); // Now delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get choice list */ @Test public void testGetChoiceList_ExpectPass() { ArrayList<Object> values = new ArrayList<Object>(); Map<String, Object> myMap = new TreeMap<String, Object>(); Map<String, Object> displayText = new TreeMap<String, Object>(); displayText.put("text", "displayText"); myMap.put("choice_list_name", "test_list"); myMap.put("data_value", "test"); myMap.put("display", displayText); values.add(myMap); String jsonChoiceList = null; try { jsonChoiceList = ODKFileUtils.mapper.writeValueAsString(values); } catch (JsonProcessingException e) { e.printStackTrace(); } // Set the choice list id String choiceListId = ODKDatabaseImplUtils.get().setChoiceList(db, jsonChoiceList); // Get the choice list String retJsonChoiceList = ODKDatabaseImplUtils.get().getChoiceList(db, choiceListId); assertEquals(jsonChoiceList, retJsonChoiceList); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select the _choice_list_id from the _choice_lists table String sel = "SELECT * FROM " + DatabaseConstants.CHOICE_LIST_TABLE_NAME + " WHERE " + ChoiceListColumns.CHOICE_LIST_ID + " = ?"; String[] selArgs = { "" + choiceListId }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(ChoiceListColumns.CHOICE_LIST_JSON); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, retJsonChoiceList); } /* * Test get table metadata */ @Test public void testGetTableMetadata_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.object.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Ensure that the expected properties is in the KVS table String sel = "SELECT * FROM " + DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME + " WHERE " + KeyValueStoreColumns.PARTITION + " = ? AND " + KeyValueStoreColumns.KEY + " = ? AND " + KeyValueStoreColumns.VALUE + " = ?"; String[] selArgs = { partition, key, kvsValue }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Now make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries.get(0), kvsEntries.get(0)); // Now delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get table definition entry */ @Test public void testGetTableDefinitionEntry_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); ODKDatabaseImplUtils.AccessContext accessContextNoTableId = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table String sel2 = "SELECT * FROM " + DatabaseConstants.TABLE_DEFS_TABLE_NAME + " WHERE " + TableDefinitionsColumns.TABLE_ID + " = ?"; String[] selArgs2 = { "" + tableId }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContextNoTableId); assertEquals(cursor.getCount(), 1); String syncTimeVal = null; String schemaETagVal = null; String lastDataETagVal = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(TableDefinitionsColumns.LAST_SYNC_TIME); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); syncTimeVal = cursor.getString(ind); ind = cursor.getColumnIndex(TableDefinitionsColumns.SCHEMA_ETAG); assertTrue(cursor.isNull(ind)); ind = cursor.getColumnIndex(TableDefinitionsColumns.LAST_DATA_ETAG); assertTrue(cursor.isNull(ind)); } // Now get the table definition entry TableDefinitionEntry tde = ODKDatabaseImplUtils.get().getTableDefinitionEntry(db, tableId); // Compare the table definition entry and the raw query results assertEquals(syncTimeVal, tde.getLastSyncTime()); assertEquals(schemaETagVal, tde.getSchemaETag()); assertEquals(lastDataETagVal, tde.getLastDataETag()); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get table health when table is healthy */ @Test public void testGetTableHealthWhenTableIsClean_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Test that the health of the table is CLEAN int health = ODKDatabaseImplUtils.get().getTableHealth(db, tableId); assertFalse(CursorUtils.getTableHealthHasConflictsOrCheckpoints(health)); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get table health when table is healthy */ @Test public void testVariousRawQueryFilters_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); Cursor c; String sel; sel = "SELECT * FROM " + DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); ODKDatabaseImplUtils.AccessContext accessContextPlainUser, accessContextAnonymousUser; accessContextPlainUser = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.USER_ROLES_LIST); accessContextAnonymousUser = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, "anonymous", null); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextPlainUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextAnonymousUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextPlainUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextAnonymousUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.ROW_OWNER + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextPlainUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextAnonymousUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.SYNC_STATE + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextPlainUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextAnonymousUser); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.ROW_OWNER + ", " + DataTableColumns.SYNC_STATE + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.ROW_OWNER + ", " + DataTableColumns.GROUP_READ_ONLY + ", " + DataTableColumns.GROUP_MODIFY + ", " + DataTableColumns.SYNC_STATE + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.ROW_OWNER + ", " + DataTableColumns.GROUP_PRIVILEGED + ", " + DataTableColumns.GROUP_MODIFY + ", " + DataTableColumns.SYNC_STATE + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("did not expect effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) == -1); } else { assertTrue("should not get here", false); } c.close(); sel = "SELECT testColumn, " + DataTableColumns.DEFAULT_ACCESS + ", " + DataTableColumns.ROW_OWNER + ", " + DataTableColumns.GROUP_READ_ONLY + ", " + DataTableColumns.GROUP_MODIFY + ", " + DataTableColumns.GROUP_PRIVILEGED + ", " + DataTableColumns.SYNC_STATE + " from " + testTable; c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContext); if (c.moveToFirst()) { assertTrue("expected effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) != -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextPlainUser); if (c.moveToFirst()) { assertTrue("expected effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) != -1); } else { assertTrue("should not get here", false); } c.close(); c = ODKDatabaseImplUtils.get().rawQuery(db, sel, null, null, accessContextAnonymousUser); if (c.moveToFirst()) { assertTrue("expected effective privileges column", c.getColumnIndex(DataTableColumns.EFFECTIVE_ACCESS) != -1); } else { assertTrue("should not get here", false); } c.close(); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get table health when table has checkpoints */ @Test public void testGetTableHealthWhenTableHasChkpts_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); int testVal2 = 200; ContentValues updatedCvValues = new ContentValues(); updatedCvValues.put(testCol, testVal2); ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, updatedCvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 2); // Select everything out of the table sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; selArgs = new String[1]; selArgs[0] = "" + testVal2; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val2 = 0; String saveptType = null; while (cursor.moveToNext()) { // Get the actual value int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val2 = cursor.getInt(ind); // Get the savepoint_type ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertTrue(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val2, testVal2); // Also make sure that the savepoint_type // is empty assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); assertNotSame(saveptType, SavepointTypeManipulator.complete()); // Test that the health of the table is CLEAN int health = ODKDatabaseImplUtils.get().getTableHealth(db, tableId); assertTrue(CursorUtils.getTableHealthHasChanges(health)); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test get table health when table is has conflicts */ // @Test // public void testGetTableHealthWhenTableHasConflicts_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.LOCAL_DELETED_OLD_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoServerConflictWithId(db, tableId,orderedColumns, // cvValues, rowId, conflictType); // //ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // // Test that the health of the table is CLEAN // int health = ODKDatabaseImplUtils.get().getTableHealth(db, tableId); // // assertEquals(health, CursorUtils.TABLE_HEALTH_HAS_CONFLICTS); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test get table health when table is has checkpoints and conflicts */ // @Test // public void testGetTableHealthWhenTableHasChkptsAndConflicts_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // int testVal2 = 200; // ContentValues updatedCvValues = new ContentValues(); // updatedCvValues.put(testCol, testVal2); // ODKDatabaseImplUtils.get().insertCheckpointRowWithId(db, tableId, orderedColumns, updatedCvValues, rowId); // // // Select everything out of the table // sel = "SELECT * FROM " + tableId; // selArgs = new String[0]; // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // assertEquals(cursor.getCount(), 2); // // // Select everything out of the table // sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // selArgs = new String[1]; // selArgs[0] = "" + testVal2; // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val2 = 0; // String saveptType = null; // while (cursor.moveToNext()) { // // Get the actual value // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val2 = cursor.getInt(ind); // // // Get the savepoint_type // ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); // assertTrue(cursor.isNull(ind)); // // // Get the conflict_type and make sure that it is null // ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // assertTrue(cursor.isNull(ind)); // } // // assertEquals(val2, testVal2); // // // Also make sure that the savepoint_type // // is empty // assertNotSame(saveptType, SavepointTypeManipulator.incomplete()); // assertNotSame(saveptType, SavepointTypeManipulator.complete()); // // // Place row in conflict // int conflictType = ConflictType.LOCAL_DELETED_OLD_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Test that the health of the table is CLEAN // int health = ODKDatabaseImplUtils.get().getTableHealth(db, tableId); // // assertEquals(health, CursorUtils.TABLE_HEALTH_HAS_CHECKPOINTS_AND_CONFLICTS); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test place row into conflict */ // @Test // public void testPlaceRowIntoConflict_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.LOCAL_DELETED_OLD_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test query distinct * Add two rows with the same data in a column * and make sure that only one is returned */ @Test public void testQueryDistinct_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; boolean thrown = false; ContentValues cvValues = new ContentValues(); cvValues.put(testCol, testVal); String uuid = UUID.randomUUID().toString(); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, uuid, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = null; try { cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } // Add another row in the database with the same value String uuid2 = UUID.randomUUID().toString(); ContentValues cvValues2 = new ContentValues(); cvValues2.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues2, uuid2, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = {}; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 2); System.out.println("testQueryDistinct_ExpectPass: after select * query"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Make sure the values are correct int val2 = 0; while (cursor2.moveToNext()) { int ind = cursor2.getColumnIndex(testCol); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val2 = cursor2.getInt(ind); assertEquals(val2, testVal); } // The moment of truth! test the queryDistinct // Get all of the rows of the database but only return testCol String[] retCols = { testCol }; Cursor cursor3 = ODKDatabaseImplUtils.get().queryDistinctForTest(db, tableId, retCols, null, null, null, null, null, null); assertEquals(cursor3.getCount(), 1); int val3 = 0; while (cursor3.moveToNext()) { int ind = cursor3.getColumnIndex(testCol); int type = cursor3.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val3 = cursor3.getInt(ind); } assertEquals(val3, testVal); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test replace metadata with KVS */ @Test public void testReplaceTableMetadataWithKVS_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.object.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Ensure that the expected properties is in the KVS table String sel = "SELECT * FROM " + DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME + " WHERE " + KeyValueStoreColumns.PARTITION + " = ? AND " + KeyValueStoreColumns.KEY + " = ? AND " + KeyValueStoreColumns.VALUE + " = ?"; String[] selArgs = { partition, key, kvsValue }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries.get(0), kvsEntries.get(0)); // Replace the metadata String newKVSValue = "newTestTable"; List<KeyValueStoreEntry> newKVSEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry newKVSEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), newKVSValue); newKVSEntries.add(newKVSEntry); ODKDatabaseImplUtils.get().replaceTableMetadata(db, tableId, newKVSEntries, true); String[] selArgs2 = { partition, key, newKVSValue }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs2, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> newRetKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(newRetKVSEntries.get(0), newKVSEntries.get(0)); // Delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test replace metadata */ @Test public void testReplaceTableMetadata_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.object.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Ensure that the expected properties is in the KVS table String sel = "SELECT * FROM " + DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME + " WHERE " + KeyValueStoreColumns.PARTITION + " = ? AND " + KeyValueStoreColumns.KEY + " = ? AND " + KeyValueStoreColumns.VALUE + " = ?"; String[] selArgs = { partition, key, kvsValue }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries.get(0), kvsEntries.get(0)); // Replace the metadata String newKVSValue = "newTestTable"; KeyValueStoreEntry newKVSEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), newKVSValue); ODKDatabaseImplUtils.get().replaceTableMetadata(db, newKVSEntry); String[] selArgs2 = { partition, key, newKVSValue }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs2, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> newRetKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(newRetKVSEntries.get(0), newKVSEntry); // Delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test replace metadata sub list */ @Test public void testReplaceTableMetadataSubList_ExpectPass() { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.string.name(); String partition = KeyValueStoreConstants.PARTITION_TABLE; String aspect = KeyValueStoreConstants.ASPECT_DEFAULT; String key = KeyValueStoreConstants.COLUMN_DISPLAY_NAME; String type = ElementDataType.object.name(); String kvsValue = tableId; List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); List<KeyValueStoreEntry> kvsEntries = new ArrayList<KeyValueStoreEntry>(); KeyValueStoreEntry kvsEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), kvsValue); kvsEntries.add(kvsEntry); try { ODKDatabaseImplUtils.get().createOrOpenTableWithColumnsAndProperties(db, tableId, columns, kvsEntries, true); } catch (Exception e) { e.printStackTrace(); } ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Ensure that the expected properties is in the KVS table String sel = "SELECT * FROM " + DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME + " WHERE " + KeyValueStoreColumns.PARTITION + " = ? AND " + KeyValueStoreColumns.KEY + " = ? AND " + KeyValueStoreColumns.VALUE + " = ?"; String[] selArgs = { partition, key, kvsValue }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> retKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(retKVSEntries.get(0), kvsEntries.get(0)); // Replace the metadata List<KeyValueStoreEntry> newKVSEntries = new ArrayList<KeyValueStoreEntry>(); String newKVSValue = "newTestTable"; KeyValueStoreEntry newKVSEntry = KeyValueStoreUtils.buildEntry(tableId, partition, aspect, key, ElementDataType.valueOf(type), newKVSValue); newKVSEntries.add(newKVSEntry); ODKDatabaseImplUtils.get().replaceTableMetadataSubList(db, tableId, partition, aspect, newKVSEntries); String[] selArgs2 = { partition, key, newKVSValue }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs2, null, accessContext); assertEquals(cursor.getCount(), 1); // Make sure that the returned value is equal to the original value ArrayList<KeyValueStoreEntry> newRetKVSEntries = ODKDatabaseImplUtils.get() .getTableMetadata(db, tableId, partition, aspect, key).getEntries(); assertEquals(newRetKVSEntries.get(0), newKVSEntry); // Delete the metadata ODKDatabaseImplUtils.get().deleteTableMetadata(db, tableId, partition, aspect, key); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test resolve server conflict with delete in existing table with id */ @Test public void testResolveServerConflictWithDeleteInExistingTableWithId_ExpectPass() { // Test this after restructuring of the Sync code } /* * Test resolve server conflict with update in existing table with id */ @Test public void testResolveServerConflictWithUpdateInExistingTableWithId_ExpectPass() { // Test this after restructuring of the Sync code } /* * Test restore row from conflict */ // @Test // public void testRestoreRowFromConflict_ExpectPass() { // String tableId = testTable; // String testCol = "testColumn"; // String testColType = ElementDataType.integer.name(); // List<Column> columns = new ArrayList<Column>(); // columns.add(new Column(testCol, testCol, testColType, "[]")); // OrderedColumns orderedColumns = ODKDatabaseImplUtils.get() // .createOrOpenTableWithColumns(db, tableId, columns); // int testVal = 5; // // ContentValues cvValues = new ContentValues(); // String rowId = LocalizationUtils.genUUID(); // cvValues.put(testCol, testVal); // ODKDatabaseImplUtils.get().insertDataIntoExistingTableWithId(db, tableId, orderedColumns, // cvValues, rowId); // // // Select everything out of the table // String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; // String[] selArgs = { "" + testVal }; // Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int val = 0; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(testCol); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // val = cursor.getInt(ind); // } // // assertEquals(val, testVal); // // // Place row in conflict // int conflictType = ConflictType.LOCAL_DELETED_OLD_VALUES; // ODKDatabaseImplUtils.get().placeRowIntoConflict(db, tableId, rowId, conflictType); // // // Run the query again and make sure that the place row in conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // // int conflictTypeVal = -1; // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // int type = cursor.getType(ind); // assertEquals(type, Cursor.FIELD_TYPE_INTEGER); // conflictTypeVal = cursor.getInt(ind); // } // // assertEquals(conflictType, conflictTypeVal); // // // Restore row from conflict // ODKDatabaseImplUtils.get().restoreRowFromConflict(db, tableId, rowId, SyncState.synced, conflictType); // // // Run the query again and make sure that the restore row // // from conflict worked as expected // cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs); // assertEquals(cursor.getCount(), 1); // // while (cursor.moveToNext()) { // int ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); // assertTrue(cursor.isNull(ind)); // // int indSyncState = cursor.getColumnIndex(DataTableColumns.SYNC_STATE); // int typeSyncState = cursor.getType(indSyncState); // assertEquals(typeSyncState, Cursor.FIELD_TYPE_STRING); // String syncStateVal = cursor.getString(indSyncState); // assertEquals(syncStateVal, SyncState.synced.name()); // } // // // Drop the table now that the test is done // ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); // } /* * Test server table schema eTag changed */ @Test public void testServerTableSchemaETagChanged_ExpectPass() { // Test this after restructuring of the Sync code } /* * Test set choice list */ @Test public void testSetChoiceList() { ArrayList<Object> values = new ArrayList<Object>(); Map<String, Object> myMap = new TreeMap<String, Object>(); Map<String, Object> displayText = new TreeMap<String, Object>(); displayText.put("text", "displayText"); myMap.put("choice_list_name", "test_list"); myMap.put("data_value", "test"); myMap.put("display", displayText); values.add(myMap); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); String jsonChoiceList = null; try { jsonChoiceList = ODKFileUtils.mapper.writeValueAsString(values); } catch (JsonProcessingException e) { e.printStackTrace(); } String choiceListId = ODKDatabaseImplUtils.get().setChoiceList(db, jsonChoiceList); // Select the _choice_list_id from the _choice_lists table String sel = "SELECT * FROM " + DatabaseConstants.CHOICE_LIST_TABLE_NAME + " WHERE " + ChoiceListColumns.CHOICE_LIST_ID + " = ?"; String[] selArgs = { "" + choiceListId }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(ChoiceListColumns.CHOICE_LIST_JSON); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); } assertEquals(val, jsonChoiceList); } /* * Test update table eTags */ @Test public void testUpdateTableETags() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); ODKDatabaseImplUtils.AccessContext accessContextNoTableId = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table String sel2 = "SELECT * FROM " + DatabaseConstants.TABLE_DEFS_TABLE_NAME + " WHERE " + TableDefinitionsColumns.TABLE_ID + " = ?"; String[] selArgs2 = { "" + tableId }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContextNoTableId); assertEquals(cursor.getCount(), 1); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(TableDefinitionsColumns.SCHEMA_ETAG); assertTrue(cursor.isNull(ind)); int ind2 = cursor.getColumnIndex(TableDefinitionsColumns.LAST_DATA_ETAG); assertTrue(cursor.isNull(ind2)); } // update db schema etag and last data etag String newSchemaETag = LocalizationUtils.genUUID(); String newLastDataETag = LocalizationUtils.genUUID(); ODKDatabaseImplUtils.get().privilegedUpdateTableETags(db, tableId, newSchemaETag, newLastDataETag); // Select everything out of the table cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContextNoTableId); assertEquals(cursor.getCount(), 1); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(TableDefinitionsColumns.SCHEMA_ETAG); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); assertEquals(newSchemaETag, cursor.getString(ind)); int ind2 = cursor.getColumnIndex(TableDefinitionsColumns.LAST_DATA_ETAG); int type2 = cursor.getType(ind2); assertEquals(type2, Cursor.FIELD_TYPE_STRING); assertEquals(newLastDataETag, cursor.getString(ind2)); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test update table last sync time */ @Test public void testUpdateTableLastSyncTime_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 1); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); ODKDatabaseImplUtils.AccessContext accessContextNoTableId = ODKDatabaseImplUtils.get().getAccessContext(db, null, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table String sel2 = "SELECT * FROM " + DatabaseConstants.TABLE_DEFS_TABLE_NAME + " WHERE " + TableDefinitionsColumns.TABLE_ID + " = ?"; String[] selArgs2 = { "" + tableId }; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContextNoTableId); assertEquals(cursor.getCount(), 1); String defaultSyncTime = "-1"; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(TableDefinitionsColumns.LAST_SYNC_TIME); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); assertEquals(cursor.getString(ind), defaultSyncTime); } // udpate db table last sync time ODKDatabaseImplUtils.get().privilegedUpdateTableLastSyncTime(db, tableId); // Select everything out of the table cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContextNoTableId); assertEquals(cursor.getCount(), 1); String syncTime = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(TableDefinitionsColumns.LAST_SYNC_TIME); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); syncTime = cursor.getString(ind); } // CAL: Should there be more checks here? assertNotSame(syncTime, defaultSyncTime); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test update row eTag and sync state */ @Test public void testUpdateRowETagAndSyncState_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String sel = "SELECT * FROM " + tableId + " WHERE " + testCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); int val = 0; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(testCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); val = cursor.getInt(ind); } assertEquals(val, testVal); // Update the row ETag and sync state String rowETag = LocalizationUtils.genUUID(); ODKDatabaseImplUtils.get().privilegedUpdateRowETagAndSyncState(db, tableId, rowId, rowETag, SyncState.synced, activeUser); // Run the query again and make sure that the place row in conflict worked as expected cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(DataTableColumns.ROW_ETAG); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); String rowETagVal = cursor.getString(ind); assertEquals(rowETag, rowETagVal); int indSyncState = cursor.getColumnIndex(DataTableColumns.SYNC_STATE); int typeSyncState = cursor.getType(indSyncState); assertEquals(typeSyncState, Cursor.FIELD_TYPE_STRING); String syncStateVal = cursor.getString(indSyncState); assertEquals(syncStateVal, SyncState.synced.name()); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /** * Generates sequential unique IDs starting with 1, 2, 3, and so on. * <p> * This class is thread-safe. * </p> */ static class UniqueIdGenerator { private final AtomicLong counter = new AtomicLong(0); public long nextId() { return counter.incrementAndGet(); } } private List<Long> threadTest(final int threadCount, final String tableId, final String rowId, final String colPrefix, final OrderedColumns orderedColumns, final boolean useNewDB, final boolean multipleWrites, final int numOfMultiWrites) throws InterruptedException, ExecutionException { final UniqueIdGenerator domainObject = new UniqueIdGenerator(); Callable<Long> task = new Callable<Long>() { @Override public synchronized Long call() { Long origVal = domainObject.nextId(); int testVal = origVal.intValue(); String testCol = colPrefix + testVal; ContentValues cvValues = null; OdkConnectionInterface dbToUse = db; if (useNewDB) { DbHandle uniqueKey = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + testVal + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); dbToUse = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), uniqueKey); } try { if (multipleWrites) { for (int i = 1; i <= numOfMultiWrites; i++) { cvValues = new ContentValues(); cvValues.put(testCol, i); ODKDatabaseImplUtils.get().updateRowWithId(dbToUse, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); try { Thread.sleep(0); } catch (Exception e) { e.printStackTrace(); } } } else { cvValues = new ContentValues(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().updateRowWithId(dbToUse, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); } } catch (ActionNotAuthorizedException ex) { WebLogger.getLogger(dbToUse.getAppName()).printStackTrace(ex); throw new IllegalStateException(ex); } if (dbToUse != null && useNewDB) { dbToUse.releaseReference(); } return origVal; } }; List<Callable<Long>> tasks = Collections.nCopies(threadCount, task); ExecutorService executorService = Executors.newFixedThreadPool(threadCount); List<Future<Long>> futures = executorService.invokeAll(tasks); List<Long> resultList = new ArrayList<Long>(futures.size()); // Check for exceptions for (Future<Long> future : futures) { // Throws an exception if an exception was thrown by the task. resultList.add(future.get()); } // Validate the IDs assertEquals(threadCount, futures.size()); List<Long> expectedList = new ArrayList<Long>(threadCount); for (long i = 1; i <= threadCount; i++) { expectedList.add(i); } Collections.sort(resultList); assertEquals(expectedList, resultList); return resultList; } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithoutClosingCursor_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } // Have the threads all update the corresponding column in the table try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, false, false, 0); } catch (Exception e) { e.printStackTrace(); } // Ensure that the row exists String sel2 = "SELECT * FROM " + tableId + " WHERE " + DataTableColumns.ID + " = ?"; String[] selArgs2 = { "" + rowId }; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithoutClosingCursor_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { for (int i = 0; i <= numOfThreads; i++) { String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithClosingCursor_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } List<Long> returnedResults = null; // Have the threads all update the corresponding column in the table try { returnedResults = threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, false, false, 0); } catch (Exception e) { e.printStackTrace(); } // Extra check to make sure that this has finished before // anything continues List<Long> expectedList = new ArrayList<Long>(numOfThreads); for (long i = 1; i <= numOfThreads; i++) { expectedList.add(i); } if (returnedResults != null) { Collections.sort(returnedResults); } assertEquals(expectedList, returnedResults); // Ensure that the row exists String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithClosingCursor_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { assertEquals(cursor2.getColumnIndex(colPrefix), -1); for (int i = 0; i <= numOfThreads; i++) { String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithClosingCursorAndOrigConn_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } String uniqueUUID = LocalizationUtils.genUUID(); DbHandle prevUniqueKey = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uniqueUUID + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); OdkConnectionInterface prevDb = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), prevUniqueKey); OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(prevDb, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(prevDb, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(prevDb, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } List<Long> returnedResults = null; // Have the threads all update the corresponding column in the table try { returnedResults = threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, false, 0); } catch (Exception e) { e.printStackTrace(); } // Extra check to make sure that this has finished before // anything continues List<Long> expectedList = new ArrayList<Long>(numOfThreads); for (long i = 1; i <= numOfThreads; i++) { expectedList.add(i); } if (returnedResults != null) { Collections.sort(returnedResults); } assertEquals(expectedList, returnedResults); // Ensure that the row exists String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(prevDb, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithClosingCursor_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { assertEquals(cursor2.getColumnIndex(colPrefix), -1); for (int i = 0; i <= numOfThreads; i++) { String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithDBIntPerThreadAndForQuery_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } // Have the threads all update the corresponding column in the table try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, false, 0); } catch (Exception e) { e.printStackTrace(); } // Ensure that the row exists String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; // Query with new connection to see if this gets all recent operations DbHandle uniqueKey = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + testVal + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); OdkConnectionInterface dbForQuery = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), uniqueKey); Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(dbForQuery, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadAndForQuery_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { for (int i = 1; i <= numOfThreads; i++) { System.out .println("testMultithreadedDBInsertionWithDBIntPerThreadAndForQuery_ExpectPass: assertion " + "for thread " + i); String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadAndForQuery_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Release the OdkConnectionInterface used for the query dbForQuery.releaseReference(); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } // Have the threads all update the corresponding column in the table try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, false, 0); } catch (Exception e) { e.printStackTrace(); } // Ensure that the row exists boolean dbWithinTrxn = db.inTransaction(); if (!dbWithinTrxn) { db.beginTransactionExclusive(); String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { for (int i = 1; i <= numOfThreads; i++) { System.out .println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: assertion " + "for thread " + i); String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } db.setTransactionSuccessful(); db.endTransaction(); } System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedDBInsertionWithDBIntPerThreadWithTxnOnUpdate_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 5; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } // Have the threads all update the corresponding column in the table try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, false, 0); } catch (Exception e) { e.printStackTrace(); } // Ensure that the row exists boolean dbWithinTrxn = db.inTransaction(); int testValAgain = 100; if (!dbWithinTrxn) { db.beginTransactionExclusive(); ContentValues cvValuesAgain = new ContentValues(); cvValuesAgain.put(setupTestCol, testValAgain); ODKDatabaseImplUtils.get().updateRowWithId(db, tableId, orderedColumns, cvValuesAgain, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); db.setTransactionSuccessful(); db.endTransaction(); } String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { int indAgain = cursor2.getColumnIndex(setupTestCol); int typeAgain = cursor2.getType(indAgain); assertEquals(typeAgain, Cursor.FIELD_TYPE_INTEGER); int valAgain = cursor2.getInt(indAgain); assertEquals(valAgain, testValAgain); for (int i = 1; i <= numOfThreads; i++) { System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: assertion " + "for thread " + i); String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, i); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } System.out.println("testMultithreadedDBInsertionWithDBIntPerThreadWithTxn_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedMultipleDBInsertionWithNewDBForQuery_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 20; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId + " WHERE " + setupTestCol + " = ?"; String[] selArgs = { "" + testVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } // Have the threads all update the corresponding column in the table int numOfWritesForThreads = 100; try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, true, numOfWritesForThreads); } catch (Exception e) { e.printStackTrace(); } // Ensure that the row exists Cursor cursor2 = null; // Try this to see if it makes a difference // Query with new connection to see if this gets all recent operations String uuid = LocalizationUtils.genUUID(); DbHandle uniqueKey = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); OdkConnectionInterface dbForQuery = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), uniqueKey); String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; cursor2 = ODKDatabaseImplUtils.get().rawQuery(dbForQuery, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedMultipleDBInsertion_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { int indAgain = cursor2.getColumnIndex(setupTestCol); int typeAgain = cursor2.getType(indAgain); assertEquals(typeAgain, Cursor.FIELD_TYPE_INTEGER); int valAgain = cursor2.getInt(indAgain); assertEquals(valAgain, testVal); for (int i = 1; i <= numOfThreads; i++) { System.out .println("testMultithreadedMultipleDBInsertion_ExpectPass: assertion " + "for thread " + i); String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, numOfWritesForThreads); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } System.out.println("testMultithreadedMultipleDBInsertion_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultithreadedMultipleDBInsertionWithSameSelect_ExpectPass() throws ActionNotAuthorizedException { int numOfThreads = 20; String tableId = testTable; String colPrefix = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); // Create table with the right number of columns for (int i = 0; i <= numOfThreads; i++) { String testCol = colPrefix + i; columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert data so that the threads can all just update int testVal = 0; String setupTestCol = colPrefix + 0; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(setupTestCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Ensure that the row exists String sel = "SELECT * FROM " + tableId; String[] selArgs = null; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(setupTestCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor.getInt(ind); assertEquals(val, testVal); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } // Have the threads all update the corresponding column in the table int numOfWritesForThreads = 100; try { threadTest(numOfThreads, tableId, rowId, colPrefix, orderedColumns, true, true, numOfWritesForThreads); } catch (Exception e) { e.printStackTrace(); } Cursor cursor2 = null; String sel2 = "SELECT * FROM " + tableId; String[] selArgs2 = null; cursor2 = ODKDatabaseImplUtils.get().rawQuery(db, sel2, selArgs2, null, accessContext); assertEquals(cursor2.getCount(), 1); System.out.println("testMultithreadedMultipleDBInsertionWithSameSelect_ExpectPass: before assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); while (cursor2.moveToNext()) { int indAgain = cursor2.getColumnIndex(setupTestCol); int typeAgain = cursor2.getType(indAgain); assertEquals(typeAgain, Cursor.FIELD_TYPE_INTEGER); int valAgain = cursor2.getInt(indAgain); assertEquals(valAgain, testVal); for (int i = 1; i <= numOfThreads; i++) { System.out.println("testMultithreadedMultipleDBInsertionWithSameSelect_ExpectPass: assertion " + "for thread " + i); String columnName = colPrefix + i; int ind = cursor2.getColumnIndex(columnName); int type = cursor2.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_INTEGER); int val = cursor2.getInt(ind); assertEquals(val, numOfWritesForThreads); } } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } System.out.println("testMultithreadedMultipleDBInsertionWithSameSelect_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test multi-threaded test for inserting data into the database */ @Test public void testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass() throws ActionNotAuthorizedException { String tableId = testTable; String testCol = "testColumn"; String testColType = ElementDataType.integer.name(); List<Column> columns = new ArrayList<Column>(); columns.add(new Column(testCol, testCol, testColType, "[]")); // Create two different db connections String uuid1 = LocalizationUtils.genUUID(); DbHandle uniqueKey1 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid1 + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); OdkConnectionInterface db1 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), uniqueKey1); String uuid2 = LocalizationUtils.genUUID(); DbHandle uniqueKey2 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid2 + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX); OdkConnectionInterface db2 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface() .getConnection(getAppName(), uniqueKey2); // Create a table on db1 OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Insert a row using db1 int testVal = 5; ContentValues cvValues = new ContentValues(); String rowId = LocalizationUtils.genUUID(); cvValues.put(testCol, testVal); ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Have both query the table // Query with db1 String sel = "SELECT * FROM " + tableId; String[] selArgs = null; Cursor cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext); while (cursor1.moveToNext()) { int ind1 = cursor1.getColumnIndex(testCol); int type1 = cursor1.getType(ind1); assertEquals(type1, Cursor.FIELD_TYPE_INTEGER); int val1 = cursor1.getInt(ind1); assertEquals(val1, testVal); } // Query with db2 Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext); while (cursor2.moveToNext()) { int ind2 = cursor2.getColumnIndex(testCol); int type2 = cursor2.getType(ind2); assertEquals(type2, Cursor.FIELD_TYPE_INTEGER); int val2 = cursor2.getInt(ind2); assertEquals(val2, testVal); } // Delete the table and recreate with a different row ODKDatabaseImplUtils.get().deleteTableAndAllData(db1, tableId); // Create a table on db1 String newTestCol = "testColumn0"; List<Column> newColumns = new ArrayList<Column>(); newColumns.add(new Column(newTestCol, newTestCol, testColType, "[]")); orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId, newColumns); // Re-create the same table with different row int newTestVal = 200; cvValues = new ContentValues(); rowId = LocalizationUtils.genUUID(); cvValues.put(newTestCol, newTestVal); ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Have both connections re-query the table // Query with db1 cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext); while (cursor1.moveToNext()) { int ind3 = cursor1.getColumnIndex(newTestCol); int type3 = cursor1.getType(ind3); assertEquals(type3, Cursor.FIELD_TYPE_INTEGER); int val3 = cursor1.getInt(ind3); assertEquals(val3, newTestVal); } // Query with db2 cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext); while (cursor2.moveToNext()) { int ind4 = cursor2.getColumnIndex(testCol); int type4 = cursor2.getType(ind4); assertEquals(type4, Cursor.FIELD_TYPE_INTEGER); int val4 = cursor2.getInt(ind4); assertEquals(val4, newTestVal); } // Close the cursor if (cursor1 != null && !cursor1.isClosed()) { cursor1.close(); } if (cursor2 != null && !cursor2.isClosed()) { cursor2.close(); } System.out.println("testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass: after assert"); OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); } /* * Test for memory leaks in the SQL interface. * * The general plan is to do a large loop where we create a table, insert a row, * select data from the table, drop the table, and create 2 x ( set of small byte[] * allocations ), every iteration, free 1x of the byte[] allocations. */ private void internalTestMemoryLeakCycling_ExpectPass(int maxIterations) throws ActionNotAuthorizedException { LinkedList<byte[]> byteQueue = new LinkedList<byte[]>(); String tableId = "memoryTest"; int maxBytes = 32; String testColType = ElementDataType.string.name(); for (int j = 0; j < maxIterations; ++j) { if (j % 10 == 0) { System.out.println("iteration " + j + " of " + maxIterations); } int maxCols = 10 + (j % 7); // construct table List<Column> columns = new ArrayList<Column>(); for (int i = 0; i < maxCols; ++i) { String testCol = "testColumn_" + Integer.toString(i); columns.add(new Column(testCol, testCol, testColType, "[]")); } OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db, tableId, columns); ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST); String rowId = LocalizationUtils.genUUID(); ContentValues cvValues = new ContentValues(); for (int i = 0; i < maxCols; ++i) { String testCol = "testColumn_" + Integer.toString(i); String testVal = "testVal_" + Integer.toString(i); cvValues.put(testCol, testVal); } ODKDatabaseImplUtils.get().insertRowWithId(db, tableId, orderedColumns, cvValues, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST, currentLocale); // Select everything out of the table String queryCol = "testColumn_" + Integer.toString(j % maxCols); String queryVal = "testVal_" + Integer.toString(j % maxCols); String sel = "SELECT * FROM " + tableId + " WHERE " + queryCol + " = ?"; String[] selArgs = { queryVal }; Cursor cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); String val = null; while (cursor.moveToNext()) { int ind = cursor.getColumnIndex(queryCol); int type = cursor.getType(ind); assertEquals(type, Cursor.FIELD_TYPE_STRING); val = cursor.getString(ind); ind = cursor.getColumnIndex(DataTableColumns.SAVEPOINT_TYPE); assertFalse(cursor.isNull(ind)); // Get the conflict_type and make sure that it is null ind = cursor.getColumnIndex(DataTableColumns.CONFLICT_TYPE); assertTrue(cursor.isNull(ind)); } assertEquals(val, queryVal); cursor.close(); ODKDatabaseImplUtils.get().deleteRowWithId(db, tableId, rowId, activeUser, RoleConsts.ADMIN_ROLES_LIST); // Select everything out of the table sel = "SELECT * FROM " + tableId; selArgs = new String[0]; cursor = ODKDatabaseImplUtils.get().rawQuery(db, sel, selArgs, null, accessContext); assertEquals(cursor.getCount(), 0); // Drop the table now that the test is done ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId); for (int len = 1; len < maxBytes; len += 4) { byte[] bytes = new byte[len]; for (int k = 0; k < len; ++k) { bytes[k] = (byte) k; } byteQueue.add(bytes); } for (int len = 1; len < maxBytes; len += 4) { byte[] bytes = new byte[len]; for (int k = 0; k < len; ++k) { bytes[k] = (byte) k; } byteQueue.add(bytes); } for (int len = 1; len < maxBytes; len += 4) { byte[] bytes = byteQueue.pop(); for (int k = 0; k < len; ++k) { assertEquals(bytes[k], (byte) k); } } } } @Test public void testMemoryLeakCyclingSubset_ExpectPass() throws ActionNotAuthorizedException { int maxIterations = 200; internalTestMemoryLeakCycling_ExpectPass(maxIterations); } @LargeTest public void testMemoryLeakCycling_ExpectPass() throws ActionNotAuthorizedException { int maxIterations = 1000; internalTestMemoryLeakCycling_ExpectPass(maxIterations); } }