Created
October 8, 2019 12:12
-
-
Save ericluong/8176413b6f02bdc97b97dc0f92aa1f69 to your computer and use it in GitHub Desktop.
Migrating AsyncStorage after ejecting from Expo (SDK 34)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.company.project; | |
import java.io.File; | |
import java.net.URLEncoder; | |
import android.content.ContentValues; | |
import android.content.Context; | |
import android.database.Cursor; | |
import android.database.sqlite.SQLiteDatabase; | |
import android.util.Log; | |
import com.facebook.react.modules.storage.ReactDatabaseSupplier; | |
public class AsyncStorageMigration { | |
static final String LOG_TAG = "expo_storage_migration"; | |
static final String PERSIST_KEY = "persist:root"; | |
static final String TABLE_CATALYST = "catalystLocalStorage"; | |
static final String KEY_COLUMN = "key"; | |
static final String VALUE_COLUMN = "value"; | |
private static Context mContext; | |
private static String expoDatabaseName; | |
public static void migrate(Context context) { | |
mContext = context; | |
expoDatabaseName = getExpoDatabaseName(); | |
if (expoDatabaseName.length() == 0) | |
return; | |
Boolean expoDatabaseExists = checkExpoDatabase(); | |
if (!expoDatabaseExists) { | |
Log.v(LOG_TAG, "Expo AsyncStorage was previously migrated. Exiting migration..."); | |
return; | |
} | |
String data = getOldData(); | |
if (data.length() == 0) { | |
Log.v(LOG_TAG, "Could not get old data. Exiting migration..."); | |
return; | |
} | |
if (!deleteOldDatabase()) { | |
Log.v(LOG_TAG, "Could not delete old database. Exiting migration..."); | |
return; | |
} | |
populateNewStore(data); | |
Log.v(LOG_TAG, "Migration done!"); | |
} | |
private static String getExpoDatabaseName() { | |
String databaseName = ""; | |
String experienceId = getExperienceId(); | |
if (experienceId == null || experienceId.length() == 0) { | |
Log.v(LOG_TAG, "No Experience ID. Exiting migration..."); | |
} else { | |
try { | |
String experienceIdEncoded = URLEncoder.encode(experienceId, "UTF-8"); | |
databaseName = "RKStorage-scoped-experience-" + experienceIdEncoded; | |
} catch (Exception e) { | |
Log.e(LOG_TAG, "Could not get Expo database name"); | |
} | |
} | |
return databaseName; | |
} | |
private static String getExperienceId() { | |
return BuildConfig.LEGACY_EXPO_EXPERIENCE_ID; | |
} | |
private static boolean checkExpoDatabase() { | |
File dbFile = mContext.getDatabasePath(expoDatabaseName); | |
return dbFile.exists(); | |
} | |
private static String getOldData() { | |
String data = ""; | |
SQLiteDatabase readableDatabase = null; | |
Cursor cursor = null; | |
try { | |
String databasePath = mContext.getDatabasePath(expoDatabaseName).getPath(); | |
readableDatabase = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READONLY); | |
cursor = readableDatabase.query(TABLE_CATALYST, new String[]{VALUE_COLUMN}, KEY_COLUMN + " = ?", new String[]{PERSIST_KEY}, null, null, null); | |
if (cursor != null && cursor.moveToFirst()) { | |
data = cursor.getString(cursor.getColumnIndex(VALUE_COLUMN)); | |
} | |
} catch (Exception e) { | |
Log.e(LOG_TAG, "Get old data error: " + e.getMessage()); | |
} finally { | |
if (readableDatabase != null) { | |
readableDatabase.close(); | |
} | |
} | |
return data; | |
} | |
private static Boolean deleteOldDatabase() { | |
return mContext.deleteDatabase(expoDatabaseName); | |
} | |
private static void populateNewStore(String value) { | |
SQLiteDatabase readableDatabase = null; | |
try { | |
readableDatabase = ReactDatabaseSupplier.getInstance(mContext).getReadableDatabase(); | |
// Check if entry exists | |
Cursor cursor = readableDatabase.query(TABLE_CATALYST, new String[]{VALUE_COLUMN}, KEY_COLUMN + " = ?", new String[]{PERSIST_KEY}, null, null, null); | |
boolean entryExists = cursor.getCount() != 0; | |
cursor.close(); | |
ContentValues args = new ContentValues(); | |
args.put(KEY_COLUMN, PERSIST_KEY); | |
args.put(VALUE_COLUMN, value); | |
// Update value | |
if (entryExists) { | |
Log.v(LOG_TAG, "Entry already exists, ready for update..."); | |
readableDatabase.update(TABLE_CATALYST, args, KEY_COLUMN + " = ?", new String[]{PERSIST_KEY}); | |
} | |
// Insert value | |
else { | |
Log.v(LOG_TAG, "Entry does not exists, ready for insertion..."); | |
readableDatabase.insert(TABLE_CATALYST, null, args); | |
} | |
} catch (Exception e) { | |
Log.e(LOG_TAG, "Populate error: " + e.getMessage()); | |
} finally { | |
if (readableDatabase != null) { | |
readableDatabase.close(); | |
} | |
} | |
} | |
} |
Guys, I just want to say thank you for this!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for the solution, if you are not using Redux this can be useful too: https://gist.github.com/luizjr92/db091719f09617abc5909ba64485e395