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;
}
}
@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