diff --git a/Jenkinsfile b/Jenkinsfile
index b2aecd67..4ce4c86d 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,5 +1,5 @@
library 'pipeline-library'
buildModule {
- sdkVersion = '7.5.2.GA'
+ sdkVersion = '8.2.0.GA'
}
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 00000000..6e7e6e7c
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/android/encrypteddatabase.iml b/android/encrypteddatabase.iml
new file mode 100644
index 00000000..0b5476c4
--- /dev/null
+++ b/android/encrypteddatabase.iml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/lib/sqlcipher.jar b/android/lib/sqlcipher.jar
index 9da61c75..200330e8 100644
Binary files a/android/lib/sqlcipher.jar and b/android/lib/sqlcipher.jar differ
diff --git a/android/libs/arm64-v8a/libsqlcipher.so b/android/libs/arm64-v8a/libsqlcipher.so
index a92c5de8..f81c8e20 100644
Binary files a/android/libs/arm64-v8a/libsqlcipher.so and b/android/libs/arm64-v8a/libsqlcipher.so differ
diff --git a/android/libs/armeabi-v7a/libsqlcipher.so b/android/libs/armeabi-v7a/libsqlcipher.so
index adfec7a0..ff661db5 100644
Binary files a/android/libs/armeabi-v7a/libsqlcipher.so and b/android/libs/armeabi-v7a/libsqlcipher.so differ
diff --git a/android/libs/x86/libsqlcipher.so b/android/libs/x86/libsqlcipher.so
index 140a7125..41ea2b16 100644
Binary files a/android/libs/x86/libsqlcipher.so and b/android/libs/x86/libsqlcipher.so differ
diff --git a/android/manifest b/android/manifest
index 7dad753b..15bb673d 100644
--- a/android/manifest
+++ b/android/manifest
@@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
-version: 3.0.4
+version: 3.1.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86
description: Provides transparent, secure 256-bit AES encryption of SQLite database files.
diff --git a/android/src/appcelerator/encrypteddatabase/EncrypteddatabaseModule.java b/android/src/appcelerator/encrypteddatabase/EncrypteddatabaseModule.java
index e947699b..f0422c96 100644
--- a/android/src/appcelerator/encrypteddatabase/EncrypteddatabaseModule.java
+++ b/android/src/appcelerator/encrypteddatabase/EncrypteddatabaseModule.java
@@ -21,13 +21,13 @@
import org.appcelerator.titanium.TiFileProxy;
import org.appcelerator.titanium.io.TiBaseFile;
import org.appcelerator.titanium.io.TiFileFactory;
-import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.util.TiUrl;
-import android.app.Activity;
import android.content.Context;
+
import net.sqlcipher.SQLException;
import net.sqlcipher.database.SQLiteDatabase;
+import net.sqlcipher.database.SQLiteDatabaseHook;
@Kroll.module(name = "Encrypteddatabase", id = "appcelerator.encrypteddatabase")
public class EncrypteddatabaseModule extends KrollModule {
@@ -64,6 +64,15 @@ public void setPassword(String value) {
public TiDatabaseProxy open(Object file) {
// Attempt to create/open the given database file/name.
TiDatabaseProxy dbp = null;
+
+ // Migrate database if necessary.
+ final SQLiteDatabaseHook migrationHook = new SQLiteDatabaseHook() {
+ public void preKey(SQLiteDatabase database) {}
+ public void postKey(SQLiteDatabase database) {
+ database.rawExecSQL("PRAGMA cipher_migrate;");
+ }
+ };
+
if (file instanceof TiFileProxy) {
// File support is read-only for now. The NO_LOCALIZED_COLLATORS
// flag means the database doesn't have Android metadata (i.e.
@@ -73,7 +82,7 @@ public TiDatabaseProxy open(Object file) {
Log.d(TAG, "Opening database from filesystem: " + absolutePath);
SQLiteDatabase db = SQLiteDatabase.openDatabase(absolutePath, getPassword(), null,
- SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
+ SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS, migrationHook);
if (db != null) {
dbp = new TiDatabaseProxy(db);
} else {
@@ -83,7 +92,7 @@ public TiDatabaseProxy open(Object file) {
String name = (String) file;
File dbPath = TiApplication.getInstance().getDatabasePath(name);
dbPath.getParentFile().mkdirs();
- SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, getPassword(), null);
+ SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, getPassword(), null, migrationHook);
if (db != null) {
dbp = new TiDatabaseProxy(name, db);
} else {
diff --git a/android/src/appcelerator/encrypteddatabase/TiResultSetProxy.java b/android/src/appcelerator/encrypteddatabase/TiResultSetProxy.java
index f8a902ca..8fd94cf9 100644
--- a/android/src/appcelerator/encrypteddatabase/TiResultSetProxy.java
+++ b/android/src/appcelerator/encrypteddatabase/TiResultSetProxy.java
@@ -14,7 +14,7 @@
import org.appcelerator.titanium.util.TiConvert;
import android.database.Cursor;
-import net.sqlcipher.CrossProcessCursorWrapper;
+import net.sqlcipher.AbstractWindowedCursor;
import net.sqlcipher.SQLException;
import android.os.Build;
@@ -95,16 +95,16 @@ private Object internalGetField(int index, int type) {
boolean fromString = false;
try {
- if (rs instanceof CrossProcessCursorWrapper) {
- CrossProcessCursorWrapper cursor = (CrossProcessCursorWrapper) rs;
- int columnType = cursor.getType(index);
- if (columnType == android.database.Cursor.FIELD_TYPE_FLOAT) {
+ if (rs instanceof AbstractWindowedCursor) {
+ AbstractWindowedCursor cursor = (AbstractWindowedCursor) rs;
+
+ if (cursor.isFloat(index)) {
result = cursor.getDouble(index);
- } else if (columnType == android.database.Cursor.FIELD_TYPE_INTEGER) {
+ } else if (cursor.isLong(index)) {
result = cursor.getLong(index);
- } else if (columnType == android.database.Cursor.FIELD_TYPE_NULL) {
+ } else if (cursor.isNull(index)) {
result = null;
- } else if (columnType == android.database.Cursor.FIELD_TYPE_BLOB) {
+ } else if (cursor.isBlob(index)) {
result = TiBlob.blobFromData(cursor.getBlob(index));
} else {
fromString = true;
@@ -123,11 +123,9 @@ private Object internalGetField(int index, int type) {
throw new IllegalStateException("Requested column number " + index + " does not exist");
}
} catch (RuntimeException e) {
- // Both SQLException and IllegalStateException (exceptions known to
- // occur
+ // Both SQLException and IllegalStateException (exceptions known to occur
// in this block) are RuntimeExceptions and since we anyway re-throw
- // and log the same error message, we're just catching all
- // RuntimeExceptions.
+ // and log the same error message, we're just catching all RuntimeExceptions.
Log.e(TAG, "Exception getting value for column " + index + ": " + e.getMessage(), e);
throw e;
}
@@ -139,7 +137,7 @@ private Object internalGetField(int index, int type) {
}
break;
case EncrypteddatabaseModule.FIELD_TYPE_INT:
- if (!(result instanceof Integer)) {
+ if (!(result instanceof Integer) && !(result instanceof Long)) {
result = TiConvert.toInt(result);
}
break;
diff --git a/test/unit/specs/int.boundary.spec.js b/test/unit/specs/int.boundary.spec.js
index 0a25fe5b..3e98984f 100644
--- a/test/unit/specs/int.boundary.spec.js
+++ b/test/unit/specs/int.boundary.spec.js
@@ -42,7 +42,7 @@ describe('appcelerator.encrypteddatabase', function () {
const resultSet = dbConnection.execute('SELECT id, intValue FROM intTable ORDER BY id');
expect(resultSet.rowCount).toEqual(rows.length);
for (let index = 0; resultSet.isValidRow(); resultSet.next(), index++) {
- expect(resultSet.field(1)).toEqual(rows[index]);
+ expect(parseInt(resultSet.field(1))).toEqual(rows[index]);
}
dbConnection.close();
});