Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Realm.io to store money values

I'm starting to play with Realm.io in an Android app that I'm writing. In one of my data objects, I'm required to store a currency value. Previously I had stored the value internally as a BigDecimal value and then converted that too and from a double value when moving in and out of the database.

I have always been told that it is a bad idea to store currency values in a double because of the way that they are handled. Unfortunately, Realm.io doesn't support the storage and retrieval of BigDecimal objects.

Is the best solution to write my own currency class that extends RealmObject and keeps that as a member variable of by data object?

like image 361
MrWizard54 Avatar asked Oct 07 '14 01:10

MrWizard54


People also ask

When would you use a Realm database?

The Realm is an object and mobile database. It's a data-storage solution for mobile and web development. A simpler definition would be that the Realm is where your app's or website's data is stored and managed. One could say that the Realm mobile database is the perfect replacement for SQLite and Core Data.

How does Realm database work?

Realm is built from scratch with C++ as its core can run directly on different devices. It stores data in a native object format whereby objects are represented in the database in a universal table-based format. This makes Realm database easy to use in different languages and platforms.

Is Realm an ORM?

Realm Database is an offline-first mobile object database in which you can directly access and store live objects without an ORM.

Is Realm swift free?

Realm is a database that is built to target mobile applications for iOS and Android. It works better and faster than SQLite and CoreData for iOS applications. It's easier to use and requires less code to store and retrieve data. It is free to use for iOS and Android apps without any limits.


2 Answers

Emanuele from Realm here.

You are right, using floats or doubles for currency is a bad idea.

We don't support BigDecimal for now, and before we do we will have to see how that plays in relation to all other language bindings since we want realm files to be compatible across all the supported platforms.

Christian's idea is good, but I see the conversion to and from String to be a bit slow. If you don't need the arbitrary precision property of BigDecimal you could use long and multiply/divide by the factor your required precision calls for. This would also save a lot of space in terms of the size of the Realm file since integer values are bit packed.

like image 101
Emanuelez Avatar answered Oct 21 '22 12:10

Emanuelez


That could work, but would probably be suboptimal if do calculations on your current BigDecimal objects.

You could also use the @Ignore annotation to provide a wrapper method for your custom objects like this:

public class Money extends RealmObject {

  private String dbValue;
  @Ignore private BigDecimal value;

  public String getDbValue() {
      return dbValue;
  }

  public void setDbValue(String dbValue) {
      this.dbValue = dbValue;
  }

  public BigDecimal getValue() {
     return new BigDecimal(getDbValue());
  }

  public void setValue(BigDecimal value) {
      setDbValue(value.toString());
  }
}

It is not perfect as you need to expose the *dbValue() methods, but it should work.

I would also suggest going to https://github.com/realm/realm-java/issues and make a feature request for this as BigDecimal is probably one of those java classes used by so many that it could warrant native Realm support, just like Date has.

like image 31
Christian Melchior Avatar answered Oct 21 '22 13:10

Christian Melchior