I have 2 tables that look like the following:
Table1
_id | _key | _mime_type | _hash
---------------------------
and
Table2
_id | _path | _mimetype
-------------------
I can get a valid cursor with the result set i'm trying to get by executing a UNION query via the following in my content providers query() method:
String unionQuery = " SELECT "
+ Table1._ID + " AS _id, "
+ Table1.QUICK_KEY + " AS _key, "
+ Table1.MIME_TYPE + " AS _mime,"
+ Table1.HASH + " AS _hash,"
+ "NULL as _path_to_file"
+ " FROM " + Table1
+ " UNION "
+ " SELECT "
+ Table2._ID + " AS _id, "
+ "NULL AS _key, "
+ Table2.MIME_TYPE + " AS _mime,"
+ "NULL AS _hash,"
+ Table2.PATH + " as _path_to_file"
+ " FROM " + Table2;
return db.rawQuery(unionQuery, null);
Rather than manually writing the statement above, I would like to use the buildUnionSubQuery() method from the SQLiteQueryBuilder class.
The buildUnionSubQuery() documentation is located at http://developer.android.com/reference/android/database/sqlite/SQLiteQueryBuilder.html
I have been trying to use the method, but with no luck in creating the SQL statement that I manually write.
An example (I've tried about 10 different things) of the code I have tried is: SQLiteQueryBuilder cloudQueryBuilder = new SQLiteQueryBuilder(); SQLiteQueryBuilder localQueryBuilder = new SQLiteQueryBuilder();
String typeDiscriminatorColumn = "_table";
Set<String> cloudColumns = new HashSet<String>();
cloudColumns.add(FileInfos.column(Table1._ID));
cloudColumns.add(FileInfos.column(Table1.QUICK_KEY));
cloudColumns.add(FileInfos.column(Table1.MIME_TYPE));
cloudColumns.add(FileInfos.column(Table1.HASH));
cloudQueryBuilder.setTables(Table1);
String cloudTableQuery = cloudQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, projection, cloudColumns, 0, Table1, selection, null, null);
with that code, this is the result I get when I log the query statement:
SELECT quickkey, NULL AS _id, NULL AS hash, NULL AS created, NULL AS mimetype, NULL AS _id, NULL AS _mimetype, NULL AS _path FROM Table1
A few other examples I've tried end up with the same result where nearly all table columns are "NULL AS "
But my goal is to have the query statement (for each SELECT statement in the UNION query) to match my manually written union statement.
Column order doesn't matter.
Any help is appreciated.
EDIT:
I know that buildUnionQueries() is used to add multiple SELECT statements, but the problem is that the SELECT statements are NOT being created as I expect them to (which means that I am using the buildUnionSubquery() method incorrectly which is what I am seeking assistance with)
EDIT:
The following code works for the most part, except that sorting does not seem to work:
SQLiteQueryBuilder cloudQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder localQueryBuilder = new SQLiteQueryBuilder();
String typeDiscriminatorColumn = "type";
String[] cloudUnionColumns = {
FileInfos._ID,
FileInfos.QUICK_KEY,
FileInfos.MIME_TYPE,
FileInfos.CREATED,
FileInfos.HASH,
LocalItems.PATH,
};
Set<String> cloudColumns = new HashSet<String>();
cloudColumns.add(FileInfos._ID);
cloudColumns.add(FileInfos.QUICK_KEY);
cloudColumns.add(FileInfos.MIME_TYPE);
cloudColumns.add(FileInfos.HASH);
cloudColumns.add(FileInfos.CREATED);
cloudQueryBuilder.setTables(Tables.FILE_INFOS);
String cloudTableQuery = cloudQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, cloudUnionColumns, cloudColumns, 0, "cloud", selection, null, null);
String[] localUnionColumns = {
LocalItems._ID,
FileInfos.QUICK_KEY,
LocalItems.MIME_TYPE,
LocalItems.CREATED,
FileInfos.HASH,
LocalItems.PATH,
};
Set<String> localColumns = new HashSet<String>();
localColumns.add(LocalItems._ID);
localColumns.add(LocalItems.PATH);
localColumns.add(LocalItems.MIME_TYPE);
localColumns.add(LocalItems.CREATED);
localQueryBuilder.setTables(Tables.LOCAL_ITEMS);
String localTableQuery = localQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, localUnionColumns, localColumns, 0, "local", selection, null, null);
Log.i(TAG, "cloud sub query - " + cloudTableQuery);
Log.i(TAG, "local sub query - " + localTableQuery);
String[] subQueries = {
cloudTableQuery,
localTableQuery,
};
sortOrder = "created DESC";
String unionQuery = cloudQueryBuilder.buildUnionQuery(subQueries, sortOrder, null);
Log.i(TAG, "query - " + unionQuery);
return db.rawQuery(unionQuery, null);
example rows I get back:
[_id: 33][quickkey: null][mimetype: image/jpeg][created: 1413327563000][hash: null][_path: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20141014-WA0001.jpg]
[_id: 47][quickkey: null][mimetype: image/jpeg][created: 1415751020000][hash: null][_path: /storage/emulated/0/Download/dota_2___clockwerk_by_sheron1030-d855txk.jpg]
I know these rows are local items because quickkey = null and hash = null
[_id: 181][quickkey: 88hcvu3t3y832p4][mimetype: image/gif][created: 1414021932000][hash: 86a15752bb550259d89e184bb5930306a9f3c8b390837b6f9b387816b6dcd461][_path: null]
[_id: 257][quickkey: 57b35uy9f12a462][mimetype: image/png][created: 1410831493000][hash: 3ad838b6a5543760b588655ad9a1714c19ecb1b91a326a21282596b2fb650c48][_path: null]
I know these rows are cloud items because path = null
Sorting does not work though, and column names are not aliased (nor do I know how to) because I expect the "created" column to be sorted, but they are not sorted for the entire result set. instead the sorting is done for each statement separately.