package com.xabber.android.data.database; import android.database.Cursor; import android.os.Looper; import com.xabber.android.data.Application; import com.xabber.android.data.database.realm.AccountRealm; import com.xabber.android.data.database.realm.DiscoveryInfoCache; import com.xabber.android.data.database.sqlite.AccountTable; import com.xabber.android.data.log.LogManager; import io.realm.DynamicRealm; import io.realm.Realm; import io.realm.RealmConfiguration; import io.realm.RealmMigration; import io.realm.RealmSchema; import io.realm.annotations.RealmModule; public class RealmManager { private static final String REALM_DATABASE_NAME = "realm_database.realm"; private static final int REALM_DATABASE_VERSION = 6; private static final String LOG_TAG = RealmManager.class.getSimpleName(); private final RealmConfiguration realmConfiguration; private static RealmManager instance; private Realm realmUiThread; public static RealmManager getInstance() { if (instance == null) { instance = new RealmManager(); } return instance; } private RealmManager() { Realm.init(Application.getInstance()); realmConfiguration = createRealmConfiguration(); boolean success = Realm.compactRealm(realmConfiguration); System.out.println("Realm compact database file result: " + success); } void deleteRealm() { Realm realm = getNewBackgroundRealm(); Realm.deleteRealm(realm.getConfiguration()); realm.close(); } @RealmModule(classes = {DiscoveryInfoCache.class, AccountRealm.class}) static class RealmDatabaseModule { } private RealmConfiguration createRealmConfiguration() { return new RealmConfiguration.Builder() .name(REALM_DATABASE_NAME) .schemaVersion(REALM_DATABASE_VERSION) .migration(new RealmMigration() { @Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); if (oldVersion == 2) { schema.get(AccountRealm.class.getSimpleName()) .setRequired(AccountRealm.Fields.ID, true); oldVersion++; } if (oldVersion == 3) { schema.get(AccountRealm.class.getSimpleName()) .addField(AccountRealm.Fields.CLEAR_HISTORY_ON_EXIT, boolean.class); schema.get(AccountRealm.class.getSimpleName()) .addField(AccountRealm.Fields.MAM_DEFAULT_BEHAVIOR, String.class); oldVersion++; } if (oldVersion == 4) { schema.get(AccountRealm.class.getSimpleName()). addField(AccountRealm.Fields.LOAD_HISTORY_SETTINGS, String.class); oldVersion++; } if (oldVersion == 5) { schema.get(AccountRealm.class.getSimpleName()) .addField(AccountRealm.Fields.SUCCESSFUL_CONNECTION_HAPPENED, boolean.class); oldVersion++; } } }) .modules(new RealmDatabaseModule()) .build(); } /** * Creates new realm instance for use from background thread. * Realm should be closed after use. * * @return new realm instance * @throws IllegalStateException if called from UI (main) thread */ public Realm getNewBackgroundRealm() { if (Looper.myLooper() == Looper.getMainLooper()) { throw new IllegalStateException("Request background thread message realm from UI thread"); } return getNewRealm(); } /** * Creates new realm instance for use from any thread. Better to avoid this method. * Realm should be closed after use. * * @return new realm instance */ public Realm getNewRealm() { return Realm.getInstance(realmConfiguration); } /** * Returns realm instance for use from UI (main) thread. * Do not close realm after use! * * @return realm instance for UI thread * @throws IllegalStateException if called from background thread */ public Realm getRealmUiThread() { if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("Request UI thread message realm from non UI thread"); } if (realmUiThread == null) { realmUiThread = Realm.getInstance(realmConfiguration); } return realmUiThread; } void copyDataFromSqliteToRealm() { Realm realm = getNewBackgroundRealm(); realm.beginTransaction(); LogManager.i(LOG_TAG, "copying from SQLite to Realm"); long counter = 0; Cursor cursor = AccountTable.getInstance().list(); while (cursor.moveToNext()) { AccountRealm accountRealm = AccountTable.createAccountRealm(cursor); realm.copyToRealm(accountRealm); counter++; } cursor.close(); LogManager.i(LOG_TAG, counter + " accounts copied to Realm"); LogManager.i(LOG_TAG, "onSuccess. removing accounts from SQLite:"); int removedAccounts = AccountTable.getInstance().removeAllAccounts(); LogManager.i(LOG_TAG, removedAccounts + " accounts removed from SQLite"); realm.commitTransaction(); realm.close(); } }