use of io.realm.internal.SharedRealm in project realm-java by realm.
the class BaseRealm method compactRealm.
/**
* Compacts the Realm file defined by the given configuration.
*
* @param configuration configuration for the Realm to compact.
* @return {@code true} if compaction succeeded, {@code false} otherwise.
*/
static boolean compactRealm(final RealmConfiguration configuration) {
SharedRealm sharedRealm = SharedRealm.getInstance(configuration);
Boolean result = sharedRealm.compact();
sharedRealm.close();
return result;
}
use of io.realm.internal.SharedRealm in project realm-java by realm.
the class Realm method executeTransactionAsync.
/**
* Similar to {@link #executeTransactionAsync(Transaction)}, but also accepts an OnSuccess and OnError callbacks.
*
* @param transaction {@link io.realm.Realm.Transaction} to execute.
* @param onSuccess callback invoked when the transaction succeeds.
* @param onError callback invoked when the transaction fails.
* @return a {@link RealmAsyncTask} representing a cancellable task.
* @throws IllegalArgumentException if the {@code transaction} is {@code null}, or if the realm is opened from
* another thread.
*/
public RealmAsyncTask executeTransactionAsync(final Transaction transaction, final Realm.Transaction.OnSuccess onSuccess, final Realm.Transaction.OnError onError) {
checkIfValid();
if (transaction == null) {
throw new IllegalArgumentException("Transaction should not be null");
}
// Avoid to call canDeliverNotification() in bg thread.
final boolean canDeliverNotification = sharedRealm.capabilities.canDeliverNotification();
// the results.
if ((onSuccess != null || onError != null)) {
sharedRealm.capabilities.checkCanDeliverNotification("Callback cannot be delivered on current thread.");
}
// We need to use the same configuration to open a background SharedRealm (i.e Realm)
// to perform the transaction
final RealmConfiguration realmConfiguration = getConfiguration();
// We need to deliver the callback even if the Realm is closed. So acquire a reference to the notifier here.
final RealmNotifier realmNotifier = sharedRealm.realmNotifier;
final Future<?> pendingTransaction = asyncTaskExecutor.submitTransaction(new Runnable() {
@Override
public void run() {
if (Thread.currentThread().isInterrupted()) {
return;
}
SharedRealm.VersionID versionID = null;
Throwable exception = null;
final Realm bgRealm = Realm.getInstance(realmConfiguration);
bgRealm.beginTransaction();
try {
transaction.execute(bgRealm);
if (Thread.currentThread().isInterrupted()) {
return;
}
bgRealm.commitTransaction();
// The bgRealm needs to be closed before post event to caller's handler to avoid concurrency
// problem. This is currently guaranteed by posting callbacks later below.
versionID = bgRealm.sharedRealm.getVersionID();
} catch (final Throwable e) {
exception = e;
} finally {
try {
if (bgRealm.isInTransaction()) {
bgRealm.cancelTransaction();
}
} finally {
bgRealm.close();
}
}
final Throwable backgroundException = exception;
final SharedRealm.VersionID backgroundVersionID = versionID;
// Cannot be interrupted anymore.
if (canDeliverNotification) {
if (backgroundVersionID != null && onSuccess != null) {
realmNotifier.post(new Runnable() {
@Override
public void run() {
if (isClosed()) {
// The caller Realm is closed. Just call the onSuccess. Since the new created Realm
// cannot be behind the background one.
onSuccess.onSuccess();
return;
}
if (sharedRealm.getVersionID().compareTo(backgroundVersionID) < 0) {
sharedRealm.realmNotifier.addTransactionCallback(new Runnable() {
@Override
public void run() {
onSuccess.onSuccess();
}
});
} else {
onSuccess.onSuccess();
}
}
});
} else if (backgroundException != null) {
realmNotifier.post(new Runnable() {
@Override
public void run() {
if (onError != null) {
onError.onError(backgroundException);
} else {
throw new RealmException("Async transaction failed", backgroundException);
}
}
});
}
} else {
if (backgroundException != null) {
// Throw in the worker thread since the caller thread cannot get notifications.
throw new RealmException("Async transaction failed", backgroundException);
}
}
}
});
return new RealmAsyncTaskImpl(pendingTransaction, asyncTaskExecutor);
}
use of io.realm.internal.SharedRealm in project realm-java by realm.
the class RealmCache method createRealmOrGetFromCache.
/**
* Creates a new Realm instance or get an existing instance for current thread.
*
* @param configuration {@link RealmConfiguration} will be used to create or get the instance.
* @param realmClass class of {@link Realm} or {@link DynamicRealm} to be created in or gotten from the cache.
* @return the {@link Realm} or {@link DynamicRealm} instance.
*/
static synchronized <E extends BaseRealm> E createRealmOrGetFromCache(RealmConfiguration configuration, Class<E> realmClass) {
boolean isCacheInMap = true;
RealmCache cache = cachesMap.get(configuration.getPath());
if (cache == null) {
// Creates a new cache.
cache = new RealmCache(configuration);
// The new cache should be added to the map later.
isCacheInMap = false;
copyAssetFileIfNeeded(configuration);
} else {
// Throws the exception if validation failed.
cache.validateConfiguration(configuration);
}
RefAndCount refAndCount = cache.refAndCountMap.get(RealmCacheType.valueOf(realmClass));
if (refAndCount.globalCount == 0) {
SharedRealm sharedRealm = SharedRealm.getInstance(configuration);
if (Table.primaryKeyTableNeedsMigration(sharedRealm)) {
sharedRealm.beginTransaction();
if (Table.migratePrimaryKeyTableIfNeeded(sharedRealm)) {
sharedRealm.commitTransaction();
} else {
sharedRealm.cancelTransaction();
}
}
sharedRealm.close();
}
if (refAndCount.localRealm.get() == null) {
// Creates a new local Realm instance
BaseRealm realm;
if (realmClass == Realm.class) {
// RealmMigrationNeededException might be thrown here.
realm = Realm.createInstance(configuration, cache.typedColumnIndicesArray);
} else if (realmClass == DynamicRealm.class) {
realm = DynamicRealm.createInstance(configuration);
} else {
throw new IllegalArgumentException(WRONG_REALM_CLASS_MESSAGE);
}
// The cache is not in the map yet. Add it to the map after the Realm instance created successfully.
if (!isCacheInMap) {
cachesMap.put(configuration.getPath(), cache);
}
refAndCount.localRealm.set(realm);
refAndCount.localCount.set(0);
}
Integer refCount = refAndCount.localCount.get();
if (refCount == 0) {
if (realmClass == Realm.class && refAndCount.globalCount == 0) {
final BaseRealm realm = refAndCount.localRealm.get();
// Stores a copy of local ColumnIndices as a global cache.
RealmCache.storeColumnIndices(cache.typedColumnIndicesArray, realm.schema.columnIndices.clone());
}
// This is the first instance in current thread, increase the global count.
refAndCount.globalCount++;
}
refAndCount.localCount.set(refCount + 1);
@SuppressWarnings("unchecked") E realm = (E) refAndCount.localRealm.get();
return realm;
}
Aggregations