Skip to content

Instantly share code, notes, and snippets.

@tranquan
Created January 4, 2019 20:34
Show Gist options
  • Save tranquan/63e1c9cf2c898a5ea3c7150cbbf64293 to your computer and use it in GitHub Desktop.
Save tranquan/63e1c9cf2c898a5ea3c7150cbbf64293 to your computer and use it in GitHub Desktop.
A helper to handle open and close realm database
/**
* Summary:
* - A helper to handle open and close realm database
* - If a database fail to open on the first time, the old one will be deleted.
* And a new database is re-created
* Documents:
* https://realm.io/docs/javascript/latest/
* https://realm.io/docs/javascript/latest/api/index.html
*/
import Realm from "realm";
const LOG_TAG = "RealmDatabase";
class RealmDatabase {
// PRIVATE
// --------------------------------------------------
private static realm: Realm | undefined;
private static schema: any[] = [];
private static schemaVersion: number = 1;
private static isOpened = false;
private static shouldOpenAgain = true;
// open realm database
// incase of migrating fail because db schema change,
// just wipeout the whole db & open again
// -> return a Promise
private static openDatabase() {
console.log(`${LOG_TAG}: openDatabase:`);
return new Promise<boolean>((resolve, reject) => {
const configs = {
schema: RealmDatabase.schema,
schemaVersion: RealmDatabase.schemaVersion,
deleteRealmIfMigrationNeeded: false,
};
try {
Realm.open(configs)
.then(realmDB => {
console.log(`${LOG_TAG}: open db success`);
RealmDatabase.realm = realmDB;
RealmDatabase.isOpened = true;
resolve(true);
})
.catch(err => {
console.warn(`${LOG_TAG}: openDatabase: Realm.open: ${err}`, err);
resolve(RealmDatabase.handleOpenDatabaseException(err));
});
} catch (err) {
console.warn(`${LOG_TAG}: openDatabase: ${err}`, err);
resolve(RealmDatabase.handleOpenDatabaseException(err));
}
});
}
private static handleOpenDatabaseException(err: Error): Promise<boolean> {
// 1. check should open again?
console.warn(`${LOG_TAG}: open db error: ${err}`);
console.warn(`${LOG_TAG}: should open again: ${RealmDatabase.shouldOpenAgain}`);
if (!RealmDatabase.shouldOpenAgain) {
// return Promise.reject(new Error("OPEN DB ERROR"));
throw new Error("OPEN DB ERROR");
}
this.shouldOpenAgain = false;
// 2. try to delete old db
if (!RealmDatabase.deleteDatabase()) {
// return Promise.reject(new Error("OPEN DB ERROR"));
throw new Error("OPEN DB ERROR");
}
// 3. open again with new db
return RealmDatabase.openDatabase();
}
private static deleteDatabase() {
try {
const deleteConfigs = {
path: Realm.defaultPath,
schemaVersion: RealmDatabase.schemaVersion,
};
Realm.deleteFile(deleteConfigs);
RealmDatabase.realm = undefined;
RealmDatabase.isOpened = false;
console.warn(`${LOG_TAG}.deleteDatabase success`);
return true;
} catch (err) {
console.warn(`${LOG_TAG}.deleteDatabase err:`, err);
return false;
}
}
private static closeDatabase() {
try {
const realm = RealmDatabase.realm!;
realm.close();
RealmDatabase.realm = undefined;
RealmDatabase.isOpened = false;
return true;
} catch (error) {
console.warn(`${LOG_TAG}: closeDatabase error: `, error);
return false;
}
}
private static clearAllRecords() {
try {
const realm = RealmDatabase.realm!;
realm.write(() => {
realm.deleteAll();
});
return true;
} catch (error) {
console.warn(`${LOG_TAG}: clearDatabase error: `, error);
return false;
}
}
// PUBLIC
// --------------------------------------------------
/**
* Create if needed & open database
*/
static initDatabase(schema: any[], schemaVersion: number) {
if (RealmDatabase.isOpened) {
console.log(`${LOG_TAG}: initDatabase: already init -> return`);
return Promise.resolve(true);
}
RealmDatabase.schema = schema;
RealmDatabase.schemaVersion = schemaVersion;
return RealmDatabase.openDatabase();
}
/**
* Close database and delete
*/
static deinitDatabase() {
if (!RealmDatabase.isOpened) {
console.log(`${LOG_TAG}: deinitDatabase: already de-init -> return`);
return Promise.resolve(true);
}
return new Promise((resolve, reject) => {
if (RealmDatabase.closeDatabase()) {
RealmDatabase.deleteDatabase();
RealmDatabase.isOpened = false;
RealmDatabase.shouldOpenAgain = true;
resolve(true);
} else {
reject(new Error("DELETE DB ERROR"));
}
});
}
static isDatabaseInitialized() {
return this.isOpened && this.realm;
}
static getRealm() {
return RealmDatabase.realm;
}
static doCloseDatabase() {
return this.closeDatabase();
}
static doDeleteDatabase() {
return RealmDatabase.deleteDatabase();
}
static doClearAllRecords() {
return RealmDatabase.clearAllRecords();
}
}
export default RealmDatabase;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment