Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.commcare.engine.cases;

import org.commcare.cases.instance.IndexedFixtureInstanceTreeElement;
import org.commcare.cases.model.StorageIndexedTreeElementModel;
import org.commcare.core.interfaces.UserSandbox;
import org.commcare.utils.SerializationUtil;
import org.javarosa.core.model.IndexedFixtureIdentifier;
import org.javarosa.core.model.instance.AbstractTreeElement;
import org.javarosa.core.model.instance.InstanceBase;
import org.javarosa.core.model.instance.TreeElement;
import org.javarosa.core.services.storage.IStorageUtilityIndexed;
import org.javarosa.core.util.externalizable.DeserializationException;

/**
* The root element for an indexed fixture data instance
* with support for attributes lookup
*/

public class AndroidIndexedFixtureInstanceTreeElement extends IndexedFixtureInstanceTreeElement {

private TreeElement attributes;

public AndroidIndexedFixtureInstanceTreeElement(AbstractTreeElement instanceRoot,
IStorageUtilityIndexed<StorageIndexedTreeElementModel> storage,
IndexedFixtureIdentifier indexedFixtureIdentifier) {
super(instanceRoot, storage, indexedFixtureIdentifier);
}

public static IndexedFixtureInstanceTreeElement get(UserSandbox sandbox,
String instanceName,
InstanceBase instanceBase) {
IndexedFixtureIdentifier indexedFixtureIdentifier = sandbox.getIndexedFixtureIdentifier(instanceName);
if (indexedFixtureIdentifier == null) {
return null;
} else {
IStorageUtilityIndexed<StorageIndexedTreeElementModel> storage =
sandbox.getIndexedFixtureStorage(instanceName);
return new AndroidIndexedFixtureInstanceTreeElement(instanceBase, storage, indexedFixtureIdentifier);
}
}

@Override
public int getAttributeCount() {
return loadAttributes().getAttributeCount();
}

@Override
public String getAttributeNamespace(int index) {
return loadAttributes().getAttributeNamespace(index);
}

@Override
public String getAttributeName(int index) {
return loadAttributes().getAttributeName(index);
}

@Override
public String getAttributeValue(int index) {
return loadAttributes().getAttributeValue(index);
}

@Override
public AbstractTreeElement getAttribute(String namespace, String name) {
TreeElement attr = loadAttributes().getAttribute(namespace, name);
attr.setParent(this);
return attr;
}

@Override
public String getAttributeValue(String namespace, String name) {
return loadAttributes().getAttributeValue(namespace, name);
}

private synchronized TreeElement loadAttributes() {
if (attributes == null) {
try {
attributes = SerializationUtil.deserialize(attrHolder, TreeElement.class);
} catch (Exception e) {
if (e.getCause() instanceof DeserializationException) {
String newMessage = "Deserialization failed for indexed fixture root atrribute wrapper: " + e.getMessage();
throw new RuntimeException(newMessage);
}
}
}
return attributes;
}

}
11 changes: 6 additions & 5 deletions app/src/org/commcare/models/database/AndroidSandbox.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
import net.sqlcipher.database.SQLiteDatabase;

import org.commcare.CommCareApplication;
import org.commcare.android.database.user.models.ACase;
import org.commcare.cases.ledger.Ledger;
import org.commcare.cases.model.Case;
import org.commcare.cases.model.StorageIndexedTreeElementModel;
import org.commcare.core.interfaces.UserSandbox;
import org.commcare.android.database.user.models.ACase;
import org.commcare.models.database.user.DatabaseUserOpenHelper;
import org.commcare.modern.util.Pair;
import org.commcare.utils.SessionUnavailableException;
import org.javarosa.core.model.IndexedFixtureIdentifier;
import org.javarosa.core.model.User;
import org.javarosa.core.model.instance.FormInstance;
import org.javarosa.core.model.instance.TreeElement;
import org.javarosa.core.services.storage.IStorageUtilityIndexed;

import java.util.Set;
Expand Down Expand Up @@ -63,15 +64,15 @@ public void setupIndexedFixtureStorage(String fixtureName,
}

@Override
public Pair<String, String> getIndexedFixturePathBases(String fixtureName) {
public IndexedFixtureIdentifier getIndexedFixtureIdentifier(String fixtureName) {
SQLiteDatabase db = app.getUserDbHandle();
return IndexedFixturePathUtils.lookupIndexedFixturePaths(db, fixtureName);
}

@Override
public void setIndexedFixturePathBases(String fixtureName, String baseName, String childName) {
public void setIndexedFixturePathBases(String fixtureName, String baseName, String childName, TreeElement attrs) {
SQLiteDatabase db = app.getUserDbHandle();
IndexedFixturePathUtils.insertIndexedFixturePathBases(db, fixtureName, baseName, childName);
IndexedFixturePathUtils.insertIndexedFixturePathBases(db, fixtureName, baseName, childName, attrs);
}

@Override
Expand Down
63 changes: 40 additions & 23 deletions app/src/org/commcare/models/database/IndexedFixturePathUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,62 @@

import android.content.ContentValues;

import org.commcare.modern.database.DatabaseIndexingUtils;
import org.commcare.modern.database.IndexedFixturePathsConstants;
import org.commcare.modern.util.Pair;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;

import org.commcare.modern.database.DatabaseIndexingUtils;
import org.commcare.utils.SerializationUtil;
import org.javarosa.core.model.IndexedFixtureIdentifier;
import org.javarosa.core.model.instance.TreeElement;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_INDEXING_STMT;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_BASE;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_CHILD;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_NAME;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE_STMT;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE_STMT_V15;

/**
* @author Phillip Mates (pmates@dimagi.com)
*/
public class IndexedFixturePathUtils {

public static Pair<String, String> lookupIndexedFixturePaths(SQLiteDatabase db,
String fixtureName) {
Cursor c = db.query(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE,
new String[]{IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_BASE, IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_CHILD},
IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_NAME + "=?", new String[]{fixtureName}, null, null, null);
public static IndexedFixtureIdentifier lookupIndexedFixturePaths(SQLiteDatabase db,
String fixtureName) {
Cursor c = db.query(INDEXED_FIXTURE_PATHS_TABLE,
new String[]{INDEXED_FIXTURE_PATHS_COL_BASE, INDEXED_FIXTURE_PATHS_COL_CHILD, INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES},
INDEXED_FIXTURE_PATHS_COL_NAME + "=?", new String[]{fixtureName}, null, null, null);
try {
if (c.getCount() == 0) {
return null;
} else {
c.moveToFirst();
return Pair.create(
c.getString(c.getColumnIndexOrThrow(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_BASE)),
c.getString(c.getColumnIndexOrThrow(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_CHILD)));
return new IndexedFixtureIdentifier(
c.getString(c.getColumnIndexOrThrow(INDEXED_FIXTURE_PATHS_COL_BASE)),
c.getString(c.getColumnIndexOrThrow(INDEXED_FIXTURE_PATHS_COL_CHILD)),
c.getBlob(c.getColumnIndexOrThrow(INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES)));
}
} finally {
c.close();
}
}

public static List<String> getAllIndexedFixtureNames(SQLiteDatabase db) {
Cursor c = db.query(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE,
new String[]{IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_NAME},
Cursor c = db.query(INDEXED_FIXTURE_PATHS_TABLE,
new String[]{INDEXED_FIXTURE_PATHS_COL_NAME},
null, null, null, null, null);
List<String> fixtureNames = new ArrayList<>();
try {
if (c.moveToFirst()) {
int desiredColumnIndex = c.getColumnIndexOrThrow(
IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_NAME);
INDEXED_FIXTURE_PATHS_COL_NAME);
while (!c.isAfterLast()) {
String name = c.getString(desiredColumnIndex);
fixtureNames.add(name);
Expand All @@ -68,17 +79,18 @@ public static Set<String> getAllIndexedFixtureNamesAsSet(SQLiteDatabase db) {
}

public static void insertIndexedFixturePathBases(SQLiteDatabase db, String fixtureName,
String baseName, String childName) {
String baseName, String childName, TreeElement attrs) {
ContentValues contentValues = new ContentValues();
contentValues.put(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_BASE, baseName);
contentValues.put(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_CHILD, childName);
contentValues.put(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_NAME, fixtureName);
contentValues.put(INDEXED_FIXTURE_PATHS_COL_BASE, baseName);
contentValues.put(INDEXED_FIXTURE_PATHS_COL_CHILD, childName);
contentValues.put(INDEXED_FIXTURE_PATHS_COL_NAME, fixtureName);
contentValues.put(INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES, SerializationUtil.serialize(attrs));

db.beginTransaction();
try {
long ret = db.insertWithOnConflict(
IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE,
IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_BASE,
INDEXED_FIXTURE_PATHS_TABLE,
INDEXED_FIXTURE_PATHS_COL_BASE,
contentValues,
SQLiteDatabase.CONFLICT_REPLACE);

Expand All @@ -93,8 +105,13 @@ public static void insertIndexedFixturePathBases(SQLiteDatabase db, String fixtu
}

public static void createStorageBackedFixtureIndexTable(SQLiteDatabase db) {
db.execSQL(IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE_STMT);
db.execSQL(IndexedFixturePathsConstants.INDEXED_FIXTURE_INDEXING_STMT);
db.execSQL(INDEXED_FIXTURE_PATHS_TABLE_STMT);
db.execSQL(INDEXED_FIXTURE_INDEXING_STMT);
}

public static void createStorageBackedFixtureIndexTableV15(SQLiteDatabase db) {
db.execSQL(INDEXED_FIXTURE_PATHS_TABLE_STMT_V15);
db.execSQL(INDEXED_FIXTURE_INDEXING_STMT);
}

public static void buildFixtureIndices(SQLiteDatabase database,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ public class DatabaseUserOpenHelper extends SQLiteOpenHelper {
* V.23 - Merges InstanceProvider to FormRecord (delete instanceUri, add displayName, filePath and canEditWhenComplete)
* v.24 - Adds and indexes column for Case external_id
* v.25 - No DB changes, validates SessionStateDescriptor records corrupted due to an earlier bug in v23 migration (In 2.44 and 2.44.1)
* v.26 - Adds a column for 'last_sync' in IndexedFixtureIndex
*/

private static final int USER_DB_VERSION = 25;
private static final int USER_DB_VERSION = 26;

private static final String USER_DB_LOCATOR = "database_sandbox_";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
import java.util.Set;
import java.util.Vector;

import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES;
import static org.commcare.modern.database.IndexedFixturePathsConstants.INDEXED_FIXTURE_PATHS_TABLE;

/**
* @author ctsims
*/
Expand Down Expand Up @@ -207,6 +210,12 @@ public void upgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
oldVersion = 25;
}
}

if (oldVersion == 25) {
if(upgradeTwentyFiveTwentySix(db)){
oldVersion = 26;
}
}
}

private boolean upgradeOneTwo(final SQLiteDatabase db) {
Expand Down Expand Up @@ -466,7 +475,7 @@ private boolean upgradeThirteenFourteen(SQLiteDatabase db) {
private boolean upgradeFourteenFifteen(SQLiteDatabase db) {
db.beginTransaction();
try {
IndexedFixturePathUtils.createStorageBackedFixtureIndexTable(db);
IndexedFixturePathUtils.createStorageBackedFixtureIndexTableV15(db);
db.setTransactionSuccessful();
return true;
} finally {
Expand Down Expand Up @@ -707,6 +716,21 @@ private boolean upgradeTwentyFourTwentyFive(SQLiteDatabase db) {
}
}

private boolean upgradeTwentyFiveTwentySix(SQLiteDatabase db) {
db.beginTransaction();
try {
db.execSQL(DbUtil.addColumnToTable(
INDEXED_FIXTURE_PATHS_TABLE,
INDEXED_FIXTURE_PATHS_COL_ATTRIBUTES,
"BLOB"));

db.setTransactionSuccessful();
return true;
} finally {
db.endTransaction();
}
}

private void migrateV2FormRecordsForSingleApp(String appId,
SqlStorage<FormRecordV2> oldStorage,
Vector<FormRecordV3> upgradedRecords) {
Expand Down
27 changes: 24 additions & 3 deletions app/src/org/commcare/utils/AndroidInstanceInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
import org.commcare.AppUtils;
import org.commcare.CommCareApplication;
import org.commcare.activities.DriftHelper;
import org.commcare.android.database.user.models.ACase;
import org.commcare.cases.ledger.Ledger;
import org.commcare.core.interfaces.UserSandbox;
import org.commcare.core.process.CommCareInstanceInitializer;
import org.commcare.engine.cases.AndroidCaseInstanceTreeElement;
import org.commcare.engine.cases.AndroidIndexedFixtureInstanceTreeElement;
import org.commcare.engine.cases.AndroidLedgerInstanceTreeElement;
import org.commcare.models.database.AndroidSandbox;
import org.commcare.models.database.SqlStorage;
import org.commcare.android.database.user.models.ACase;
import org.commcare.session.CommCareSession;
import org.commcare.util.CommCarePlatform;
import org.javarosa.core.model.instance.AbstractTreeElement;
import org.javarosa.core.model.instance.ExternalDataInstance;

Expand All @@ -24,11 +27,15 @@ public class AndroidInstanceInitializer extends CommCareInstanceInitializer {
* isn't present.
*/
public AndroidInstanceInitializer() {
super(null);
this(null, null, null);
}

public AndroidInstanceInitializer(CommCareSession session) {
super(session, new AndroidSandbox(CommCareApplication.instance()), CommCareApplication.instance().getCommCarePlatform());
this(session, new AndroidSandbox(CommCareApplication.instance()), CommCareApplication.instance().getCommCarePlatform());
}

public AndroidInstanceInitializer(CommCareSession session, UserSandbox sandbox, CommCarePlatform platform) {
super(session, sandbox, platform);
}

@Override
Expand Down Expand Up @@ -56,6 +63,20 @@ protected AbstractTreeElement setupCaseData(ExternalDataInstance instance) {
return casebase;
}

@Override
protected AbstractTreeElement setupFixtureData(ExternalDataInstance instance) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shubham1g5 We should make sure that we've also implemented anything we need to implement here for Formplayer.

This may require, for example, require us to bump the version DB (which requires us to clear out Incomplete Forms).

Unrelated to this PR structure, but useful for us to know whether we need to update the Formplayer DB Version # with the next commcare-core pull in that library before merging this one (let me know if this comment doesn't make sense).

AbstractTreeElement indexedFixture = AndroidIndexedFixtureInstanceTreeElement.get(
mSandbox,
getRefId(instance.getReference()),
instance.getBase());

if (indexedFixture != null) {
return indexedFixture;
} else {
return loadFixtureRoot(instance, instance.getReference());
}
}

@Override
public String getVersionString() {
return AppUtils.getCurrentVersionString();
Expand Down
2 changes: 1 addition & 1 deletion app/unit-tests/resources/indexed_fixture_restore.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<date>2014-03-22</date>
</Registration>
<fixture id="commtrack:products" user_id="a8f5a98c4ce767c35b9132bc75eb225c" indexed="true">
<products>
<products last_sync="2018-07-27T12:56:10.835570+00:00">
<product id="f895be4959f9a8a66f57c340aac461b4">
<name>Collier</name>
<unit/>
Expand Down
Loading