mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 13:44:04 +00:00
Fix SQL errors caused by huge operations
Differential Revision: D2475717 committer: Service User <svcscm@fb.com>
This commit is contained in:
parent
eee11eaeed
commit
c1e3f9100e
@ -49,10 +49,10 @@ import static com.facebook.react.modules.storage.ReactDatabaseSupplier.VALUE_COL
|
|||||||
* {a, b, c}
|
* {a, b, c}
|
||||||
* to be used in the SQL select statement: WHERE key in (?, ?, ?)
|
* to be used in the SQL select statement: WHERE key in (?, ?, ?)
|
||||||
*/
|
*/
|
||||||
/* package */ static String[] buildKeySelectionArgs(ReadableArray keys) {
|
/* package */ static String[] buildKeySelectionArgs(ReadableArray keys, int start, int count) {
|
||||||
String[] selectionArgs = new String[keys.size()];
|
String[] selectionArgs = new String[count];
|
||||||
for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
|
for (int keyIndex = 0; keyIndex < count; keyIndex++) {
|
||||||
selectionArgs[keyIndex] = keys.getString(keyIndex);
|
selectionArgs[keyIndex] = keys.getString(start + keyIndex);
|
||||||
}
|
}
|
||||||
return selectionArgs;
|
return selectionArgs;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,10 @@ import static com.facebook.react.modules.storage.ReactDatabaseSupplier.VALUE_COL
|
|||||||
public final class AsyncStorageModule
|
public final class AsyncStorageModule
|
||||||
extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable {
|
extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable {
|
||||||
|
|
||||||
|
// SQL variable number limit, defined by SQLITE_LIMIT_VARIABLE_NUMBER:
|
||||||
|
// https://raw.githubusercontent.com/android/platform_external_sqlite/master/dist/sqlite3.c
|
||||||
|
private static final int MAX_SQL_KEYS = 999;
|
||||||
|
|
||||||
private ReactDatabaseSupplier mReactDatabaseSupplier;
|
private ReactDatabaseSupplier mReactDatabaseSupplier;
|
||||||
private boolean mShuttingDown = false;
|
private boolean mShuttingDown = false;
|
||||||
|
|
||||||
@ -104,47 +108,50 @@ public final class AsyncStorageModule
|
|||||||
String[] columns = {KEY_COLUMN, VALUE_COLUMN};
|
String[] columns = {KEY_COLUMN, VALUE_COLUMN};
|
||||||
HashSet<String> keysRemaining = SetBuilder.newHashSet();
|
HashSet<String> keysRemaining = SetBuilder.newHashSet();
|
||||||
WritableArray data = Arguments.createArray();
|
WritableArray data = Arguments.createArray();
|
||||||
Cursor cursor = mReactDatabaseSupplier.get().query(
|
for (int keyStart = 0; keyStart < keys.size(); keyStart += MAX_SQL_KEYS) {
|
||||||
TABLE_CATALYST,
|
int keyCount = Math.min(keys.size() - keyStart, MAX_SQL_KEYS);
|
||||||
columns,
|
Cursor cursor = mReactDatabaseSupplier.get().query(
|
||||||
AsyncLocalStorageUtil.buildKeySelection(keys.size()),
|
TABLE_CATALYST,
|
||||||
AsyncLocalStorageUtil.buildKeySelectionArgs(keys),
|
columns,
|
||||||
null,
|
AsyncLocalStorageUtil.buildKeySelection(keyCount),
|
||||||
null,
|
AsyncLocalStorageUtil.buildKeySelectionArgs(keys, keyStart, keyCount),
|
||||||
null);
|
null,
|
||||||
|
null,
|
||||||
try {
|
null);
|
||||||
if (cursor.getCount() != keys.size()) {
|
keysRemaining.clear();
|
||||||
// some keys have not been found - insert them with null into the final array
|
try {
|
||||||
for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
|
if (cursor.getCount() != keys.size()) {
|
||||||
keysRemaining.add(keys.getString(keyIndex));
|
// some keys have not been found - insert them with null into the final array
|
||||||
|
for (int keyIndex = keyStart; keyIndex < keyStart + keyCount; keyIndex++) {
|
||||||
|
keysRemaining.add(keys.getString(keyIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
WritableArray row = Arguments.createArray();
|
||||||
|
row.pushString(cursor.getString(0));
|
||||||
|
row.pushString(cursor.getString(1));
|
||||||
|
data.pushArray(row);
|
||||||
|
keysRemaining.remove(cursor.getString(0));
|
||||||
|
} while (cursor.moveToNext());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FLog.w(ReactConstants.TAG, "Exception in database multiGet ", e);
|
||||||
|
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()), null);
|
||||||
|
} finally {
|
||||||
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
for (String key : keysRemaining) {
|
||||||
do {
|
WritableArray row = Arguments.createArray();
|
||||||
WritableArray row = Arguments.createArray();
|
row.pushString(key);
|
||||||
row.pushString(cursor.getString(0));
|
row.pushNull();
|
||||||
row.pushString(cursor.getString(1));
|
data.pushArray(row);
|
||||||
data.pushArray(row);
|
|
||||||
keysRemaining.remove(cursor.getString(0));
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
keysRemaining.clear();
|
||||||
FLog.w(ReactConstants.TAG, "Exception in database multiGet ", e);
|
|
||||||
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()), null);
|
|
||||||
} finally {
|
|
||||||
cursor.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String key : keysRemaining) {
|
|
||||||
WritableArray row = Arguments.createArray();
|
|
||||||
row.pushString(key);
|
|
||||||
row.pushNull();
|
|
||||||
data.pushArray(row);
|
|
||||||
}
|
|
||||||
keysRemaining.clear();
|
|
||||||
callback.invoke(null, data);
|
callback.invoke(null, data);
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
@ -223,14 +230,21 @@ public final class AsyncStorageModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mReactDatabaseSupplier.get().beginTransaction();
|
||||||
try {
|
try {
|
||||||
mReactDatabaseSupplier.get().delete(
|
for (int keyStart = 0; keyStart < keys.size(); keyStart += MAX_SQL_KEYS) {
|
||||||
TABLE_CATALYST,
|
int keyCount = Math.min(keys.size() - keyStart, MAX_SQL_KEYS);
|
||||||
AsyncLocalStorageUtil.buildKeySelection(keys.size()),
|
mReactDatabaseSupplier.get().delete(
|
||||||
AsyncLocalStorageUtil.buildKeySelectionArgs(keys));
|
TABLE_CATALYST,
|
||||||
|
AsyncLocalStorageUtil.buildKeySelection(keyCount),
|
||||||
|
AsyncLocalStorageUtil.buildKeySelectionArgs(keys, keyStart, keyCount));
|
||||||
|
}
|
||||||
|
mReactDatabaseSupplier.get().setTransactionSuccessful();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FLog.w(ReactConstants.TAG, "Exception in database multiRemove ", e);
|
FLog.w(ReactConstants.TAG, "Exception in database multiRemove ", e);
|
||||||
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()));
|
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()));
|
||||||
|
} finally {
|
||||||
|
mReactDatabaseSupplier.get().endTransaction();
|
||||||
}
|
}
|
||||||
callback.invoke();
|
callback.invoke();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user