package com.vorsk.crossfitr.models;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import java.math.BigDecimal;
/**
* DAO for "profile" table.
*
* Create a new instance and use the methods to interact with the database. Data
* is returned as instances of ProfileRow where each column is a publicly
* accessible property.
*
* @author Vivek
* @since 1.0
*/
public class ProfileModel extends SQLiteDAO {
// // Constants
// Table-specific columns
public static final String COL_ATTR = "attribute";
public static final String COL_VALUE = "value";
/***** Constructors *****/
/**
* Init SQLiteDAO with table "profile"
*
* @param ctx
* In the example they passed "this" from the calling class.. I'm
* not really sure what this is yet.
*/
public ProfileModel(Context ctx) {
super("profile", ctx);
}
/***** Private *****/
/**
* Utility method to grab all the rows from a cursor
*
* @param cr
* result of a query
* @return Array of entries
*/
private ProfileRow[] fetchProfileRows(Cursor cr)
{
if (cr == null) {
return null;
}
ProfileRow[] result = new ProfileRow[cr.getCount()];
if (result.length == 0) {
cr.close();
return result;
}
boolean valid = cr.moveToFirst();
int ii = 0;
// Grab the cursor's column indices
// An error here indicates the COL constants aren't synced with the DB
int ind_id = cr.getColumnIndexOrThrow(COL_ID);
int ind_attr = cr.getColumnIndexOrThrow(COL_ATTR);
int ind_val = cr.getColumnIndexOrThrow(COL_VALUE);
// Iterate over every row (move the cursor down the set)
while (valid) {
result[ii] = new ProfileRow();
result[ii]._id = cr.getLong(ind_id);
result[ii].attribute = cr.getString(ind_attr);
result[ii].value = cr.getString(ind_val);
valid = cr.moveToNext();
ii++;
}
cr.close();
return result;
}
/***** Public *****/
/**
* Inserts a new entry into the workout table
*
* @param row
* Add this entry to the DB
* @return ID of newly added entry, -1 on failure
*/
public long insert(ProfileRow row) {
return super.insert(row.toContentValues());
}
/**
* Inserts a new entry into the profile table, defaults record to 0
*
* @param attr
* Attribute name
* @param value
* Value of the attribute
* @return ID of newly added entry, -1 on failure
*/
public long insert(String attr, String value) {
ContentValues cv = new ContentValues();
cv.put(COL_ATTR, attr);
cv.put(COL_VALUE, value);
return super.insert(cv);
}
/**
* Attempts to update a previously entered attribute. If the update fails,
* it inserts a new entry into the profile table, defaults record to 0
*
* @param attr
* Attribute name
* @param value
* Value of the attribute
* @return ID of newly added entry, -1 on failure
*/
public long updateInsert(String attr, String value) {
long correct = 1;
ContentValues cv = new ContentValues();
cv.put(COL_VALUE, value);
correct = super.update(cv, "attribute='" + attr + "'");
if (correct <= 0) // If update fails, insert
return this.insert(attr, value);
else
return correct;
}
/**
* Fetch an entry via the ID
*
* @param id
* @return Associated entry or NULL on failure
*/
public ProfileRow getByID(long id) {
Cursor cr = selectByID(id);
// ID should never return more than 1 row...
if (cr.getCount() > 1) {
return null; // TODO: Throw exception
}
ProfileRow[] rows = fetchProfileRows(cr);
return (rows.length == 0) ? null : rows[0];
}
/**
* Fetch a specific profile attribute
*
* @param name
* Attribute name to retrieve
* @return Associated entry or NULL on failure
*/
public ProfileRow getByAttribute(String attr) {
Cursor cr = select(new String[] { COL_ATTR }, new String[] { attr });
// Name should be unique
/*
* if (cr.getCount() > 1) { // TODO: Throw exception? }
*/
ProfileRow[] rows = fetchProfileRows(cr);
return (rows.length == 0) ? null : rows[0];
}
/**
* Fetch all profile information
*
* @return List of each profile attribute and value
*/
public ProfileRow[] getAll() {
Cursor cr = select(new String[] {}, new String[] {});
return fetchProfileRows(cr);
}
/**
* Calculate BMI
*
* @return BMI of the user, -1 on Failure
*/
public BigDecimal calculateBMI() {
if ((this.getByAttribute("height") != null)
&& this.getByAttribute("weight") != null) {
// BMI = mass(lb) * 703 / (height(in) ^ 2)
double mass = Double
.parseDouble(this.getByAttribute("weight").value);
double height = Double
.parseDouble(this.getByAttribute("height").value);
// Preventing division by 0
if(height == 0){
return (BigDecimal.valueOf(0));
}
return (BigDecimal.valueOf(mass * 703 / (height * height)));
}
else{
return BigDecimal.valueOf(-1);
}
}
}