Large Sqlite Statements for Android -
i filling cursorloader app has been in play store on year now. there no trouble crashing or complaints it. trouble is, without use of stored procedures, has massive sql statement fill loader. make little more manageable, used string variables build up. without string variables, unfold several pages of unmanageable sql statement. app cardiologger in play store. sql format 4 columns of data on log page. can't feeling missing important concept or api. best practice composing sqlite statements in dire need of stored procedures? veteran developers using develop clean code?
here 4 column sql result
sql statement give above result.
/******************************************************************************* * * sql string workoutlogcolumns * * *****************************************************************************/ calendar c = calendar.getinstance(); int utcoffset = c.get(calendar.zone_offset) + c.get(calendar.dst_offset); long utcmilliseconds = c.gettimeinmillis() + utcoffset; //since1970 variable used 1 time. private final int since1970 = (int) (utcmilliseconds/86400000.0); //numberofdaysago variable used 1 time. private final string numberofdaysago = "(" + since1970 + " - " + workoutlog.wo_date + ")"; //convertdate variable used 4 times. private final string convertdate = "(" + workoutlog.wo_date + "*86400), 'unixepoch'"; // converttime variable used 5 times. private final string converttime = workoutlog.total_time + ", 'unixepoch'"; // dayofweek variable used 5 times. private final string dayofweek = "case (cast (strftime('%w'," + convertdate+") integer)) " + "when 0 'sun'"+ "when 1 'mon'"+ "when 2 'tues'"+ "when 3 'wed'"+ "when 4 'thurs'"+ "when 5 'fri'"+ "else 'sat'"+ "end "; //shortendate variable used 1 time. private final string shortenddate = "case when strftime('%y',date('now')) == strftime('%y', "+ convertdate+")"+ "then strftime('%m/%d', "+ convertdate+")"+ "else strftime('%m/%d/%y', "+ convertdate+")"+ "end "; //eventdate variable used 1 time. private final string eventdate = "case "+ numberofdaysago + "when 0 'today' "+ "when 1 'yesterday' "+ "when 2 " +dayofweek + "when 3 " +dayofweek + "when 4 " +dayofweek + "when 5 " +dayofweek + "when 6 " +dayofweek + "else "+shortenddate+ "end "+ workoutlog.wo_date; //lap variable used 6 times. private final string lap = routine.routine_distance + " * " + workoutlog.distance; //lapmeter variable used 1 time. private final string lapmeter = " case when ("+lap+") >= 1000 "+ "then replace(round("+lap+" / 1000, 2),'.0','')||'km' "+ "else replace(round("+lap+", 2),'.0','')||'m' "+ "end "; //distmeter variable used 1 time. private final string distmeter = " case when ("+workoutlog.distance+") >= 1000 "+ "then replace(round("+workoutlog.distance+" / 1000, 2),'.0','')||'km' "+ "else replace(round("+workoutlog.distance+", 2),'.0','')||'m' "+ "end "; //eventdist variable used 1 time. private final string eventdist = "case(" + routine.settings + " & 97) "+ "when 0 replace(round("+lap+",2),'.0','')||'mi'"+ //miles "when 1 replace(round("+workoutlog.distance+",2),'.0','')||'mi'"+ "when 32 replace(round("+lap+",2),'.0','')||'yd'"+ //yards "when 33 replace(round("+workoutlog.distance+",2),'.0','')||'yd'"+ "when 64 then" + lapmeter + //meters "when 65 then" + distmeter + "when 96 replace(round("+lap+",2),'.0','')||'km'"+ //km "when 97 replace(round("+workoutlog.distance+",2),'.0','')||'km'"+ "end " + workoutlog.distance; //places variable used 1 time. private final string places = "((" + routine.settings +" & 384)>>7)"; //timefrac variable used 2 times. private final string timefrac = "||'.'||substr('00'||" + workoutlog.total_fractions + ", length('00'||" + workoutlog.total_fractions +")+1-"+places+","+places+")"; //eventtime variable used 1 time. private final string eventtime = "case cast (((strftime('%h'," + converttime+")=='00')||(ifnull("+ workoutlog.total_fractions + ",0)==0)) integer)"+ "when 0 strftime('%h:%m:%s'," + converttime + ")" + timefrac + "when 1 strftime('%h:%m:%s'," + converttime + ") " + "when 10 strftime('%m:%s'," + converttime + ")" + timefrac + "when 11 strftime('%m:%s'," + converttime + ") " + "end " + workoutlog.total_fractions; //workoutlogcolumns variable used sqlite statement fill cursorloader. private final string workoutlogcolumns = "select " + eventdate + ", "+ routine.routine_table_name + "." +routine.r_name + ", " + eventdist + ", "+ eventtime + ", "+ workoutlog.wo_date + " workout_date, "+ workoutlog.workout_log_table_name + "." + workoutlog._id + " " + workoutlog.workout_log_table_name + " join " + routine.routine_table_name + " on (" + workoutlog.workout_log_table_name + "." + workoutlog.routine_id + "=" + routine.routine_table_name + "." + routine._id + ")" + " order workout_date desc;";
it quite difficult refactor database loader-based approach customized one. nevertheless, possible. basically, should done create sql table per every model. once have separate table model can make sql views or tables providing data ui. thing have remember register content observer every table uri sqlite view consists of (once decide create sql view ofc).
if suffer poor performance, can move loading-related logic loader's thread , display data cursor or parsed directly models.
i don't know extent of database in case choose custom loaders.
commonsware created loader transforming sql string cursor: https://github.com/commonsguy/cwac-loaderex/blob/master/src/com/commonsware/cwac/loaderex/sqlitecursorloader.java
moreover, here great article loaders: http://chalup.github.io/blog/2014/06/12/android-loaders/
hope advice helps out somehow.
Comments
Post a Comment