Skip to content

Instantly share code, notes, and snippets.

@daolq
Last active December 28, 2016 19:13
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save daolq/dfe77581294fd070eba0ad7369ce0c89 to your computer and use it in GitHub Desktop.
Save daolq/dfe77581294fd070eba0ad7369ce0c89 to your computer and use it in GitHub Desktop.
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import io.realm.Realm;
import io.realm.RealmObject;
/**
* RealmAutoIncrement.
*
* @author DaoLQ
*/
public final class RealmAutoIncrement {
private Map<Class<? extends RealmObject>, AtomicInteger> modelMap = new HashMap<>();
private static RealmAutoIncrement autoIncrementMap;
private Class<? extends RealmObject> mObj;
private RealmAutoIncrement(Class<? extends RealmObject> obj) {
mObj = obj;
modelMap.put(obj, new AtomicInteger(getLastIdFromModel(mObj)));
}
private int getLastIdFromModel(Class<? extends RealmObject> clazz) {
String primaryKeyColumnName = "id";
Number lastId = Realm.getDefaultInstance().where(clazz).max(primaryKeyColumnName);
return lastId == null ? 0 : lastId.intValue();
}
public Integer getNextIdFromModel() {
if (isValidMethodCall()) {
AtomicInteger modelId = modelMap.get(mObj);
if (modelId == null) {
return 0;
}
return modelId.incrementAndGet();
}
return 0;
}
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(Class<? extends RealmObject> obj) {
if (autoIncrementMap == null) {
autoIncrementMap = new RealmAutoIncrement(obj);
}
return autoIncrementMap;
}
}
@Suresh-Reddevil
Copy link

Thanks this was great. But I have a issue.
I used this class and tried finding the used id's. I have printed the key for my id whenever they are saved.
it gives the id list:
2
4
6
8
After closing the activity and later returning to the same Activity to same some more data it gives error,
value already exists and some arbitrary number that was never seen in id's.

@daolq
Copy link
Author

daolq commented Jul 7, 2016

@Suresh-Reddevil
Thank your feedback.
But I test and give id list:
1 2 3 4 5 6
Please write your error log you get to I can understand more clearly about your issue

@paulpv
Copy link

paulpv commented Aug 17, 2016

Thanks for your code.
I simplified it for my purposes to:

import android.support.annotation.NonNull;

import com.pebblebee.common.annotations.NonNullNonEmpty;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmModel;

/**
 * To use:
 * <pre>
 *     public class DataModel extends RealmObject
 *     {
 *         public static RealmUserModel createData(@NonNull Realm realm) {
 *             boolean wasInTransaction = realm.isInTransaction();
 *             if (!wasInTransaction) {
 *                 realm.beginTransaction();
 *             }
 *
 *             long id = RealmAutoIncrement.getNextIdFromModel(realm, DataModel.class, "id");
 *             RealmUserModel user = realm.createObject(DataModel.class, id);
 *
 *             if (!wasInTransaction) {
 *                 realm.commitTransaction();
 *             }
 *
 *             return user;
 *         }
 *
 *         {@literal @}PrimaryKey
 *         private long id;
 *         ...
 *     }
 *
 *     ...
 *     Realm realm = Realm.getDefaultInstance(); // <-- or however you get your instance
 *     ...
 *     DataModel data = DataModel.createData(realm);
 *     ...
 *     realm.close();
 *
 * </pre>
 */
public class RealmAutoIncrement
{
    public static long INVALID_ID = -1;

    private static final Map<RealmConfiguration, Map<Class<? extends RealmModel>, AtomicLong>> sModelMap = new HashMap<>();

    public static long getLastIdFromModel(
            @NonNull
            Realm realm,
            @NonNull
            Class<? extends RealmModel> clazz,
            @NonNullNonEmpty
            String fieldName)
    {
        Number lastId = realm.where(clazz).max(fieldName);
        return lastId != null ? lastId.intValue() : INVALID_ID + 1;
    }

    public static long getNextIdFromModel(
            @NonNull
            Realm realm,
            @NonNull
            Class<? extends RealmModel> clazz,
            @NonNullNonEmpty
            String fieldName)
    {
        RealmConfiguration realmConfiguration = realm.getConfiguration();
        Map<Class<? extends RealmModel>, AtomicLong> modelMap = sModelMap.get(realmConfiguration);
        if (modelMap == null)
        {
            modelMap = new HashMap<>();
            sModelMap.put(realmConfiguration, modelMap);
        }

        AtomicLong modelId = modelMap.get(clazz);
        if (modelId == null)
        {
            modelId = new AtomicLong(getLastIdFromModel(realm, clazz, fieldName));
            modelMap.put(clazz, modelId);
        }

        return modelId.incrementAndGet();
    }
}

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