Skip to content

Instantly share code, notes, and snippets.

@RaghavThakkar
Last active May 16, 2022 09:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RaghavThakkar/87027cb272804d2dc1fdde253c77ac90 to your computer and use it in GitHub Desktop.
Save RaghavThakkar/87027cb272804d2dc1fdde253c77ac90 to your computer and use it in GitHub Desktop.
public class PrimaryKeyFactory {
/**
* primary key field name
*/
public static final String PRIMARY_KEY_FIELD = "id";
/**
* Singleton instance.
*/
private final static PrimaryKeyFactory instance = new PrimaryKeyFactory();
/**
* Maximum primary key values.
*/
private Map<Class<? extends RealmModel>, AtomicLong> keys;
/**
* get the singleton instance
*
* @return singleton instance
*/
public static PrimaryKeyFactory getInstance() {
return instance;
}
/**
* Initialize the factory. Must be called before any primary key is generated
* - preferably from application class.
*/
public synchronized void initialize(final Realm realm) {
if (keys != null) {
throw new IllegalStateException("already initialized");
}
keys = new HashMap<>();
final RealmConfiguration configuration = realm.getConfiguration();
final RealmSchema realmSchema = realm.getSchema();
for (final Class<? extends RealmModel> c : configuration.getRealmObjectClasses()) {
final RealmObjectSchema objectSchema = realmSchema.get(c.getSimpleName());
Log.i(getClass().getSimpleName(), format("schema for class %s : %s", c.getName(), objectSchema));
if (objectSchema != null && objectSchema.hasPrimaryKey()) {
Number keyValue = null;
try {
keyValue = realm.where(c).max(PRIMARY_KEY_FIELD);
} catch (ArrayIndexOutOfBoundsException ex) {
Log.d(getClass().getSimpleName(), format("error while getting number primary key %s " +
" for %s", PRIMARY_KEY_FIELD, c.getName()), ex);
}
if (keyValue == null) {
Log.w(getClass().getSimpleName(), format("can't find number primary key %s " +
" for %s.", PRIMARY_KEY_FIELD, c.getName()));
keys.put(c, new AtomicLong(0));
} else {
keys.put(c, new AtomicLong(keyValue.longValue()));
}
}
}
}
/**
* Automatically create next key for a given class.
*/
public synchronized long nextKey(final Class<? extends RealmObject> clazz) {
if (keys == null) {
throw new IllegalStateException("not initialized yet");
}
AtomicLong l = keys.get(clazz);
if (l == null) {
Log.i(getClass().getSimpleName(), "There was no primary keys for " + clazz.getName());
//RealmConfiguration#getRealmObjectClasses() returns only classes with existing instances
//so we need to store value for the first instance created
l = new AtomicLong(0);
keys.put(clazz, l);
}
return l.incrementAndGet();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment