Skip to content

Instantly share code, notes, and snippets.

@carloseduardosx
Last active January 18, 2021 05:35
Show Gist options
  • Save carloseduardosx/a7bd88d7337660cd10a2c5dcc580ebd0 to your computer and use it in GitHub Desktop.
Save carloseduardosx/a7bd88d7337660cd10a2c5dcc580ebd0 to your computer and use it in GitHub Desktop.
RealmAutoIncrement is a singleton which maintain the last id saved from each database model
package com.carlosedurdo.database;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import io.realm.Realm;
import io.realm.RealmObject;
/**
* Implementation of Auto Increment feature for Realm
* RealmAutoIncrement is a singleton which maintain the last id saved from each database model.
*
* To get next id from anyone model, simple call the method getNextIdFromModel.
* @see #getNextIdFromModel(Class)
*/
public final class RealmAutoIncrement {
private Realm realm;
private Map<Class<? extends RealmObject>, AtomicInteger> modelMap = new HashMap<>();
private static RealmAutoIncrement autoIncrementMap;
private RealmAutoIncrement() {
}
{
realm = Realm.getDefaultInstance();
modelMap.put(SampleModel.class, new AtomicInteger(getLastIdFromModel(SampleModel.class)));
}
/**
* Utility method which query for all models saved and get the bigger model id saved
* Used to guarantee which the last model id saved is really the last
*
* @param clazz Model which should get the last id
* @return The last id saved from model passed
*/
private int getLastIdFromModel(Class<? extends RealmObject> clazz) {
String primaryKeyColumnName = "id";
Number lastId = realm.where(clazz).max(primaryKeyColumnName);
return lastId == null ? 0 : lastId.intValue();
}
/**
* Search in modelMap for the last saved id from model passed and return the next one
*
* @param clazz Model to search the last id
* @return The next id which can be saved in database for that model,
* {@code null} will be returned when this method is called by reflection
*/
public Integer getNextIdFromModel(Class<? extends RealmObject> clazz) {
if (isValidMethodCall()) {
AtomicInteger modelId = modelMap.get(clazz);
if (modelId == null) {
return 0;
}
return modelId.incrementAndGet();
}
return null;
}
/**
* Utility method to validate if the method is called from reflection,
* in this case is considered a not valid call otherwise is a valid call
*
* @return The boolean which define if the method call is valid or not
*/
private boolean isValidMethodCall() {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement stackTraceElement : stackTraceElements) {
if (stackTraceElement.getMethodName().equals("newInstance")) {
return false;
}
}
return true;
}
public static RealmAutoIncrement getInstance() {
if (autoIncrementMap == null) {
autoIncrementMap = new RealmAutoIncrement();
}
return autoIncrementMap;
}
}
@carloseduardosx
Copy link
Author

carloseduardosx commented Sep 3, 2016

I was update the implementation of Auto Increment feature for Realm. Now it's much more robust with support for large operations of insert and delete at same time.

Everyone can see the new implementation here:
https://gist.github.com/carloseduardosx/6c3a3dfc3a9cb467aa464884f39544c2

See: Sample of how to use RealAutoIncrement. Is pretty simple too 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment