Skip to content

Commit 3d56539

Browse files
Add facility to report data size in bytes of SQL query
1 parent 9a79691 commit 3d56539

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

android-database-sqlcipher/src/main/java/net/sqlcipher/database/SQLiteDatabase.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import net.sqlcipher.SQLException;
2626
import net.sqlcipher.database.SQLiteDebug.DbStats;
2727
import net.sqlcipher.database.SQLiteDatabaseHook;
28+
import net.sqlcipher.database.SQLiteQueryStats;
2829

2930
import java.io.File;
3031
import java.io.FileOutputStream;
@@ -1842,6 +1843,38 @@ public Cursor rawQuery(String sql, String[] selectionArgs) {
18421843
return rawQueryWithFactory(null, sql, selectionArgs, null);
18431844
}
18441845

1846+
/**
1847+
* Determines the total size in bytes of the query results, and the largest
1848+
* single row in bytes for the query.
1849+
*
1850+
* @param sql the SQL query. The SQL string must a SELECT statement
1851+
* @param args the argments to bind to the query
1852+
*
1853+
* @return A {@link SQLiteQueryStats} based the provided SQL query.
1854+
*/
1855+
public SQLiteQueryStats getQueryStats(String sql, Object[] args){
1856+
long totalPayload = 0L;
1857+
long largestIndividualPayload = 0L;
1858+
try {
1859+
String query = String.format("CREATE TABLE tempstat AS %s", sql);
1860+
execSQL(query, args);
1861+
Cursor cursor = rawQuery("SELECT sum(payload) FROM dbstat WHERE name = 'tempstat';", new Object[]{});
1862+
if(cursor == null) return new SQLiteQueryStats(totalPayload, largestIndividualPayload);
1863+
cursor.moveToFirst();
1864+
totalPayload = cursor.getLong(0);
1865+
cursor.close();
1866+
cursor = rawQuery("SELECT max(mx_payload) FROM dbstat WHERE name = 'tempstat';", new Object[]{});
1867+
if(cursor == null) return new SQLiteQueryStats(totalPayload, largestIndividualPayload);
1868+
cursor.moveToFirst();
1869+
largestIndividualPayload = cursor.getLong(0);
1870+
cursor.close();
1871+
execSQL("DROP TABLE tempstat;");
1872+
} catch(Exception ex) {
1873+
execSQL("DROP TABLE IF EXISTS tempstat;");
1874+
throw ex;
1875+
}
1876+
return new SQLiteQueryStats(totalPayload, largestIndividualPayload);
1877+
}
18451878

18461879
/**
18471880
* Runs the provided SQL and returns a {@link Cursor} over the result set.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.sqlcipher.database;
2+
3+
public class SQLiteQueryStats {
4+
long totalQueryResultSize = 0L;
5+
long largestIndividualRowSize = 0L;
6+
7+
public SQLiteQueryStats(long totalQueryResultSize,
8+
long largestIndividualRowSize) {
9+
this.totalQueryResultSize = totalQueryResultSize;
10+
this.largestIndividualRowSize = largestIndividualRowSize;
11+
}
12+
13+
public long getTotalQueryResultSize(){
14+
return totalQueryResultSize;
15+
}
16+
17+
public long getLargestIndividualRowSize(){
18+
return largestIndividualRowSize;
19+
}
20+
}

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ ext {
7676
"-DSQLITE_ENABLE_FTS3_PARENTHESIS " +
7777
"-DSQLITE_ENABLE_FTS4 " +
7878
"-DSQLITE_ENABLE_FTS5 " +
79-
"-DSQLCIPHER_CRYPTO_OPENSSL"
79+
"-DSQLCIPHER_CRYPTO_OPENSSL " +
80+
"-DSQLITE_ENABLE_DBSTAT_VTAB"
8081
}
8182

8283
task clean(type: Delete) {

0 commit comments

Comments
 (0)