How can I write SQLite Real vals to Java BigDecimal values?
Asked Answered
C

1

2

I have a class like this:

public class DeliveryItem {
    private int _id;
    private String _invoiceNumber;
    private String _UPC_PLU;
    private String _vendorItemId;
    private int _packSize;
    private String _description;
    private BigDecimal _cost;
    private BigDecimal _margin;
    private BigDecimal _listPrice;
    private int _departmentNumber;
    private String _subdepartment;
    private String _quantity;

    public void setID(int id) {
        this._id = id;
    }

    public int getID() {
        return this._id;
    }
    . . .

The cost, margin, and listprice columns are "BigDecimal" because in the orginal (C#) app they were Decimal

The corresponding SQLite table is defined thus:

String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
        TABLE_DELIVERYITEMS + "("
        + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
        + COLUMN_UPCPLU + " TEXT," + COLUMN_VENDORITEMID + " TEXT,"
        + COLUMN_PACKSIZE + " INTEGER," + COLUMN_DESCRIPTION + " TEXT," + COLUMN_COST +  
        " REAL,"
        + COLUMN_MARGIN + " REAL," + COLUMN_LISTPRICE + " REAL," + COLUMN_DEPTNUM + " 
        INTEGER,"
        + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + " TEXT"
        + ")";

The closest SQLite gets to Decimal (C#) or BigDecimal (Java) is REAL, SQLite's only floating point data type.

In a class that extends SQLiteOpenHelper, I am trying to select values from the table and store them in an ArrayList of my custom class type like so:

public ArrayList<DeliveryItem> getAllDeliveryItems() {
    ArrayList<DeliveryItem>  delItems = new ArrayList<DeliveryItem>();
    String query = "Select * FROM " + TABLE_DELIVERYITEMS;

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db != null ? db.rawQuery(query, null) : null;

    if (cursor != null) {
        while (cursor.moveToNext()) {
            DeliveryItem d = new DeliveryItem();
            d.setID(Integer.parseInt(cursor.getString(0)));
            . . .
            d.set_cost(BigDecimal.valueOf(cursor.getString(6)));
            d.set_margin(BigDecimal.valueOf(cursor.getString(7)));
            d.set_listPrice(BigDecimal.valueOf(cursor.getString(8)));
            . . .
            delItems.add(d);
        }
    }
    if (cursor != null) {
        cursor.close();
    }

    return delItems;
}

Note that I can assign string vals to the DeliveryItem class using "cursor.getString(N)" and integer vals using "Integer.parseInt(cursor.getString(0))" but as to the BigDecimal values, I run into a problem.

Java's BigDecimal data type/class has no associated "parseBigDecimal" method.

If I try this:

d.set_cost(BigDecimal.valueOf(cursor.getString(6)));

I get, "error: no suitable method found for valueOf(String) method BigDecimal.valueOf(long) is not applicable (argument mismatch; String cannot be converted to long) method BigDecimal.valueOf(double) is not applicable (argument mismatch; String cannot be converted to double)"

...and if I try this:

d.set_cost(Float.parseFloat(cursor.getString(6)));

...I get, "error: incompatible types: float cannot be converted to BigDecimal"

If I try Double.parseDouble(), I get the similar, "...double cannot be converted to BigDecimal"

How can I read the REALs from the database and populate the BigDecimal vals with those vals?

UPDATE

I'm not even able at present to "fake it until I make it" with this temporary code:

d.set_cost(42.00);

...or this:

d.set_cost((BigDecimal)42.00);

...as both of them complain with, "error: incompatible types: double cannot be converted to BigDecimal"

And the same goes for this alternate casting syntax, which Droidio suggested:

d.set_cost(((BigDecimal) 42.00));
Capitulate answered 11/4, 2014 at 19:34 Comment(1)
don't cast... create a new BigDecimal like d.set_cost(new BigDecimal(42.00));Adventurism
A
1

I"m not sure why you are trying to cast and/or use valueOf() operations... simply make a new BigDecimal object. It does have a constructor to take a float, double, string, etc.

d.set_cost(new BigDecimal(42.00));

:)

You could also change your getString() opertaions to getBigDecimal().

So like:

d.set_cost(cursor.getBigDecimal(6));

This gets around creating a temporary (and unnecessary)String since you seem to be after getting a BigDecimal in the end anyways.

Just be aware, if the value your ResultSet returns is not able to be converted into a BigDecimal like it's a string "abcd" then it will throw an Exception, but this is probably desired since you are then dealing with bad data.

Adventurism answered 11/4, 2014 at 21:13 Comment(4)
Okay, that gets me past the kludge; based on that, though, it might even work for the real problem (it compiles anyway): d.set_cost(new BigDecimal(cursor.getString(6))); Any reason why that won't work?Capitulate
@B.ClayShannon I would skip the String creation and just use getBigDecimal() as this is the resulting object you seem to be after anyways. see my update above :)Adventurism
There doesn't seem to be any such thing as "getBigDecimal" for me; maybe the Androiderized Java is a subset of "BigJava"? I have double, blob, float, int, short, and string for "get" possibilities following "d.set_cost(cursor." - but nary a "BigDecimal" hove into sight.Capitulate
@B.ClayShannon hmm, you may be right. i've not done much android myself. if there is no such thing then you can use whatever flavor of get_() suites you... Strings tend to be "heavy" so perhaps something closer is better like a Double... but Doubles and Floats have precision problems (obviously)... so maybe d.set_cost(new BigDecimal(cursor.getString(6))); is your best bet.Adventurism

© 2022 - 2024 — McMap. All rights reserved.