package net.sf.openrocket.android.db;
import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import net.sf.openrocket.android.util.AndroidLogWrapper.LogHelper;
import net.sf.openrocket.motor.Manufacturer;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.util.Coordinate;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class MotorDao {
private SQLiteDatabase mDb;
private final static String DATABASE_TABLE = "motor";
private final static String DROP_TABLE = "DROP TABLE IF EXISTS " + DATABASE_TABLE;
private final static String CREATE_TABLE =
"create table " + DATABASE_TABLE + " ( " +
"_id integer primary key, " +
"unique_name text unique, " +
"digest string, " +
"designation text, " +
"delays text, " +
"diameter number, " +
"tot_impulse_ns number, " +
"avg_thrust_n number, " +
"max_thrust_n number, " +
"burn_time_s number, " +
"length number," +
"prop_mass_g number," +
"tot_mass_g number," +
"case_info text," +
"manufacturer text," +
"type text," +
"impulse_class text," +
"thrust_data blob," +
"time_data blob," +
"cg_data blob" +
");";
MotorDao(SQLiteDatabase mDb) {
this.mDb = mDb;
}
static String[] create() {
return new String[] { CREATE_TABLE };
}
static String[] update(int oldVer, int newVer) {
return new String[] { DROP_TABLE, CREATE_TABLE };
}
public final static String ID = "_id";
public final static String UNIQUE_NAME = "unique_name";
public final static String DIGEST = "digest";
public final static String DESIGNATION = "designation";
public final static String DELAYS = "delays";
public final static String DIAMETER = "diameter";
public final static String TOTAL_IMPULSE = "tot_impulse_ns";
public final static String AVG_THRUST = "avg_thrust_n";
public final static String MAX_THRUST = "max_thrust_n";
public final static String BURN_TIME = "burn_time_s";
public final static String LENGTH = "length";
public final static String CASE_INFO = "case_info";
public final static String MANUFACTURER = "manufacturer";
public final static String TYPE = "type";
public final static String IMPULSE_CLASS = "impulse_class";
public final static String THRUST_DATA = "thrust_data";
public final static String TIME_DATA = "time_data";
public final static String CG_DATA = "cg_data";
private final static String[] ALL_COLS = new String[] {
ID,
DIGEST,
DESIGNATION,
DELAYS,
DIAMETER,
TOTAL_IMPULSE,
AVG_THRUST,
MAX_THRUST,
BURN_TIME,
LENGTH,
CASE_INFO,
TYPE,
IMPULSE_CLASS,
MANUFACTURER,
THRUST_DATA,
TIME_DATA,
CG_DATA
};
public long insertOrUpdateMotor(ExtendedThrustCurveMotor mi) throws Exception {
ContentValues initialValues = new ContentValues();
initialValues.put(ID, mi.getId());
initialValues.put(UNIQUE_NAME, mi.getManufacturer() + mi.getDesignation());
initialValues.put(DIGEST, mi.getDigest());
initialValues.put(DESIGNATION, mi.getDesignation());
initialValues.put(DELAYS, ConversionUtils.delaysToString(mi.getStandardDelays()));
initialValues.put(DIAMETER, mi.getDiameter());
initialValues.put(TOTAL_IMPULSE, mi.getTotalImpulseEstimate());
initialValues.put(AVG_THRUST, mi.getAverageThrustEstimate());
initialValues.put(MAX_THRUST, mi.getMaxThrustEstimate());
initialValues.put(BURN_TIME, mi.getBurnTimeEstimate());
initialValues.put(LENGTH, mi.getLength());
initialValues.put(CASE_INFO, mi.getCaseInfo());
initialValues.put(TYPE, mi.getMotorType().name());
initialValues.put(IMPULSE_CLASS, mi.getImpulseClass());
initialValues.put(MANUFACTURER, mi.getManufacturer().getSimpleName());
initialValues.put(THRUST_DATA, ConversionUtils.serializeArrayOfDouble(mi.getThrustPoints()));
initialValues.put(TIME_DATA, ConversionUtils.serializeArrayOfDouble(mi.getTimePoints()));
initialValues.put(CG_DATA, ConversionUtils.serializeArrayOfCoordinate(mi.getCGPoints()));
AndroidLogWrapper.d(MotorDao.class, "insertOrUpdate Motor");
long rv = mDb.insertWithOnConflict(DATABASE_TABLE, null, initialValues, SQLiteDatabase.CONFLICT_REPLACE);
return rv;
}
/**
* Delete the motor and burn data with the given rowId
*
* @param name name of motor to delete
* @return true if deleted, false otherwise
*/
public boolean deleteMotor(Long id) {
boolean rv = mDb.delete(DATABASE_TABLE, ID + "=" + id, null) > 0;
return rv;
}
/**
*
* @param groupCol
* @param groupVal
* @return
*/
public Cursor fetchAllInGroups(String groupCol, String groupVal) {
return mDb.query(DATABASE_TABLE,
/* columns */ALL_COLS,
/* selection */groupCol + "=?",
/* selection args*/new String[] { groupVal },
/* groupby */null,
/* having*/null,
/* orderby*/TOTAL_IMPULSE);
}
/**
* Fetch the groups based on groupCol
* @param groupCol
* @return
*/
public Cursor fetchGroups(String groupCol) {
return mDb.query(true, DATABASE_TABLE,
/* columns */new String[] {
groupCol
},
/* selection */null,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/groupCol,
/* limit*/null);
}
/**
* Return a Cursor over the list of all motors
*
* @return Cursor over all notes
*/
public Cursor fetchAllMotors() {
return mDb.query(DATABASE_TABLE,
/* columns */ALL_COLS,
/* selection */null,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
}
private ExtendedThrustCurveMotor hydrateMotor(Cursor mCursor) throws Exception {
ExtendedThrustCurveMotor mi;
{
String digest = mCursor.getString(mCursor.getColumnIndex(DIGEST));
String designation = mCursor.getString(mCursor.getColumnIndex(DESIGNATION));
String delayString = mCursor.getString(mCursor.getColumnIndex(DELAYS));
double[] delays = ConversionUtils.stringToDelays(delayString);
double diameter = mCursor.getDouble(mCursor.getColumnIndex(DIAMETER));
double totImpulse = mCursor.getDouble(mCursor.getColumnIndex(TOTAL_IMPULSE));
double avgImpulse = mCursor.getDouble(mCursor.getColumnIndex(AVG_THRUST));
double maxThrust = mCursor.getDouble(mCursor.getColumnIndex(MAX_THRUST));
double length = mCursor.getDouble(mCursor.getColumnIndex(LENGTH));
Motor.Type type;
try {
type = Enum.valueOf(Motor.Type.class, mCursor.getString(mCursor.getColumnIndex(TYPE)));
} catch (IllegalArgumentException e) {
type = Motor.Type.UNKNOWN;
}
Manufacturer manufacturer = Manufacturer.getManufacturer(mCursor.getString(mCursor.getColumnIndex(MANUFACTURER)));
double[] thrustData = ConversionUtils.deserializeArrayOfDouble(mCursor.getBlob(mCursor.getColumnIndex(THRUST_DATA)));
double[] timeData = ConversionUtils.deserializeArrayOfDouble(mCursor.getBlob(mCursor.getColumnIndex(TIME_DATA)));
Coordinate[] cgData = ConversionUtils.deserializeArrayOfCoordinate(mCursor.getBlob(mCursor.getColumnIndex(CG_DATA)));
ThrustCurveMotor tcm = new ThrustCurveMotor(manufacturer,
designation,
"",
type,
delays,
diameter,
length,
timeData,
thrustData,
cgData,
digest
);
mi = new ExtendedThrustCurveMotor(tcm);
mi.setId(mCursor.getLong(mCursor.getColumnIndex(ID)));
mi.setCaseInfo(mCursor.getString(mCursor.getColumnIndex(CASE_INFO)));
mi.setImpulseClass(mCursor.getString(mCursor.getColumnIndex(IMPULSE_CLASS)));
}
return mi;
}
public ExtendedThrustCurveMotor fetchMotor(Long id) throws Exception {
Cursor mCursor = mDb.query(DATABASE_TABLE,
/* columns */ALL_COLS,
/* selection */ID + "=" + id,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
if (mCursor == null) {
return null;
}
try {
if (mCursor.getCount() == 0) {
return null;
}
mCursor.moveToFirst();
return hydrateMotor(mCursor);
} finally {
mCursor.close();
}
}
public ExtendedThrustCurveMotor fetchMotor(String manufacturerShortName, String designation) throws Exception {
Cursor mCursor = mDb.query(DATABASE_TABLE,
/* columns */ALL_COLS,
/* selection */MANUFACTURER + "='" + manufacturerShortName + "' and " + DESIGNATION + "='" + designation + "'",
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
if (mCursor == null) {
return null;
}
try {
if (mCursor.getCount() == 0) {
return null;
}
mCursor.moveToFirst();
return hydrateMotor(mCursor);
} catch( Exception ex ) {
LogHelper.getInstance().debug("whoa!", ex);
throw ex;
} finally {
mCursor.close();
}
}
}