@SuppressWarnings("CheckStyle") @Override protected List<?>[] doInBackground(Byte... statsToLoad) { StatsListFragment fragment = mFragment.get(); if (fragment == null) return null; MainActivity mainActivity = (MainActivity) fragment.getActivity(); if (mainActivity == null) return null; MainActivity.waitForSaveThreads(new WeakReference<>(mainActivity)); final byte toLoad = statsToLoad[0]; Cursor cursor; int[][] statValues; List<String> listStatHeaders = new ArrayList<>(); List<List<Pair<String, String>>> listStatNamesAndValues = new ArrayList<>(); fragment.prepareListData(mainActivity, toLoad, listStatHeaders, listStatNamesAndValues); statValues = new int[listStatHeaders.size()][]; for (int i = 0; i < statValues.length; i++) statValues[i] = new int[listStatNamesAndValues.get(i).size()]; switch (toLoad) { case StatUtils.LOADING_BOWLER_STATS: fragment.mNumberOfGeneralDetails = 1; cursor = fragment.getBowlerOrLeagueCursor(false); break; case StatUtils.LOADING_LEAGUE_STATS: fragment.mNumberOfGeneralDetails = 2; listStatNamesAndValues .get(fragment.mStatsGeneral) .add(1, Pair.create("League/Event", mainActivity.getLeagueName().substring(1))); cursor = fragment.getBowlerOrLeagueCursor(true); break; case StatUtils.LOADING_SERIES_STATS: fragment.mNumberOfGeneralDetails = 3; listStatNamesAndValues .get(fragment.mStatsGeneral) .add(1, Pair.create("League/Event", mainActivity.getLeagueName().substring(1))); listStatNamesAndValues .get(fragment.mStatsGeneral) .add(2, Pair.create("Date", mainActivity.getSeriesDate())); cursor = fragment.getSeriesCursor(); break; case StatUtils.LOADING_GAME_STATS: fragment.mNumberOfGeneralDetails = 4; listStatNamesAndValues .get(fragment.mStatsGeneral) .add(1, Pair.create("League/Event", mainActivity.getLeagueName().substring(1))); listStatNamesAndValues .get(fragment.mStatsGeneral) .add(2, Pair.create("Date", mainActivity.getSeriesDate())); listStatNamesAndValues .get(fragment.mStatsGeneral) .add(3, Pair.create("Game #", String.valueOf(mainActivity.getGameNumber()))); cursor = fragment.getGameCursor(); break; default: throw new IllegalArgumentException( "invalid value for toLoad: " + toLoad + ". must be between 0 and 3 (inclusive)"); } /** * Passes through rows in cursor and updates stats which are affected as each frame is * analyzed */ final byte numberOfGames = (toLoad >= StatUtils.LOADING_LEAGUE_STATS ? ((mainActivity.getLeagueName().substring(1).equals(Constants.NAME_OPEN_LEAGUE)) ? 5 : mainActivity.getDefaultNumberOfGames()) : 20); int totalShotsAtMiddle = 0; int spareChances = 0; int seriesTotal = 0; int[] totalByGame = new int[numberOfGames]; int[] countByGame = new int[numberOfGames]; if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { byte frameNumber = (byte) cursor.getInt(cursor.getColumnIndex(Contract.FrameEntry.COLUMN_FRAME_NUMBER)); if (toLoad != StatUtils.LOADING_GAME_STATS && frameNumber == 1) { short gameScore = cursor.getShort(cursor.getColumnIndex(Contract.GameEntry.COLUMN_SCORE)); byte gameNumber = (byte) cursor.getInt(cursor.getColumnIndex(Contract.GameEntry.COLUMN_GAME_NUMBER)); totalByGame[gameNumber - 1] += gameScore; countByGame[gameNumber - 1]++; byte matchResults = (byte) (cursor.getInt(cursor.getColumnIndex(Contract.GameEntry.COLUMN_MATCH_PLAY))); if (matchResults > 0) statValues[fragment.mStatsMatch][matchResults - 1]++; if (statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SINGLE] < gameScore) statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SINGLE] = gameScore; statValues[fragment.mStatsOverall][StatUtils.STAT_TOTAL_PINS] += gameScore; statValues[fragment.mStatsOverall][StatUtils.STAT_NUMBER_OF_GAMES]++; if (gameNumber == 1) { if (statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SERIES] < seriesTotal) statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SERIES] = seriesTotal; seriesTotal = gameScore; } else seriesTotal += gameScore; } boolean gameIsManual = (cursor.getInt(cursor.getColumnIndex(Contract.GameEntry.COLUMN_IS_MANUAL)) == 1); if (gameIsManual) { cursor.moveToNext(); continue; } boolean frameAccessed = (cursor.getInt(cursor.getColumnIndex(Contract.FrameEntry.COLUMN_IS_ACCESSED)) == 1); if (toLoad == StatUtils.LOADING_GAME_STATS && !frameAccessed) break; String frameFouls = Score.foulIntToString( cursor.getInt(cursor.getColumnIndex(Contract.FrameEntry.COLUMN_FOULS))); boolean[][] pinState = new boolean[3][5]; for (byte i = 0; i < pinState.length; i++) { pinState[i] = Score.ballIntToBoolean( cursor.getInt(cursor.getColumnIndex(Contract.FrameEntry.COLUMN_PIN_STATE[i]))); } for (byte i = 1; i <= 3; i++) { if (frameFouls.contains(String.valueOf(i))) statValues[fragment.mStatsFouls][0]++; } if (frameNumber == Constants.NUMBER_OF_FRAMES) { totalShotsAtMiddle++; int ballValue = fragment.getFirstBallValue(pinState[0]); if (ballValue != -1) statValues[fragment.mStatsGeneral][StatUtils.STAT_MIDDLE_HIT]++; fragment.increaseFirstBallStat(ballValue, statValues, 0); if (ballValue < 5 && ballValue != Constants.BALL_VALUE_STRIKE) spareChances++; if (ballValue != 0) { if (Arrays.equals(pinState[1], Constants.FRAME_PINS_DOWN)) { statValues[fragment.mStatsGeneral][StatUtils.STAT_SPARE_CONVERSIONS]++; fragment.increaseFirstBallStat(ballValue, statValues, 1); if (ballValue >= 5) spareChances++; } else { statValues[fragment.mStatsPins][StatUtils.STAT_PINS_LEFT] += fragment.countPinsLeftStanding(pinState[2]); } } else { totalShotsAtMiddle++; ballValue = fragment.getFirstBallValue(pinState[1]); if (ballValue != -1) statValues[fragment.mStatsGeneral][StatUtils.STAT_MIDDLE_HIT]++; fragment.increaseFirstBallStat(ballValue, statValues, 0); if (ballValue != 0) { if (Arrays.equals(pinState[2], Constants.FRAME_PINS_DOWN)) { statValues[fragment.mStatsGeneral][StatUtils.STAT_SPARE_CONVERSIONS]++; fragment.increaseFirstBallStat(ballValue, statValues, 1); if (ballValue >= 5) spareChances++; } else { statValues[fragment.mStatsPins][StatUtils.STAT_PINS_LEFT] += fragment.countPinsLeftStanding(pinState[2]); } } else { totalShotsAtMiddle++; ballValue = fragment.getFirstBallValue(pinState[2]); if (ballValue != -1) statValues[fragment.mStatsGeneral][StatUtils.STAT_MIDDLE_HIT]++; fragment.increaseFirstBallStat(ballValue, statValues, 0); if (ballValue != 0) { statValues[fragment.mStatsPins][StatUtils.STAT_PINS_LEFT] += fragment.countPinsLeftStanding(pinState[2]); } } } } else { totalShotsAtMiddle++; int ballValue = fragment.getFirstBallValue(pinState[0]); if (ballValue != -1) statValues[fragment.mStatsGeneral][StatUtils.STAT_MIDDLE_HIT]++; fragment.increaseFirstBallStat(ballValue, statValues, 0); if (ballValue < 5 && ballValue != Constants.BALL_VALUE_STRIKE) spareChances++; if (ballValue != 0) { if (Arrays.equals(pinState[1], Constants.FRAME_PINS_DOWN)) { statValues[fragment.mStatsGeneral][StatUtils.STAT_SPARE_CONVERSIONS]++; fragment.increaseFirstBallStat(ballValue, statValues, 1); if (ballValue >= 5) spareChances++; } else { statValues[fragment.mStatsPins][StatUtils.STAT_PINS_LEFT] += fragment.countPinsLeftStanding(pinState[2]); } } } cursor.moveToNext(); } } if (toLoad != StatUtils.LOADING_GAME_STATS) { if (statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SERIES] < seriesTotal) statValues[fragment.mStatsOverall][StatUtils.STAT_HIGH_SERIES] = seriesTotal; if (toLoad != StatUtils.LOADING_SERIES_STATS) { for (byte i = 0; i < numberOfGames; i++) statValues[fragment.mStatsGameAverage][i] = (countByGame[i] > 0) ? totalByGame[i] / countByGame[i] : 0; } if (statValues[fragment.mStatsOverall][StatUtils.STAT_NUMBER_OF_GAMES] > 0) { statValues[fragment.mStatsOverall][StatUtils.STAT_AVERAGE] = statValues[fragment.mStatsOverall][StatUtils.STAT_TOTAL_PINS] / statValues[fragment.mStatsOverall][StatUtils.STAT_NUMBER_OF_GAMES]; statValues[fragment.mStatsPins][StatUtils.STAT_PINS_AVERAGE] = statValues[fragment.mStatsPins][StatUtils.STAT_PINS_LEFT] / statValues[fragment.mStatsOverall][StatUtils.STAT_NUMBER_OF_GAMES]; } } cursor.close(); fragment.setGeneralAndDetailedStatValues( listStatNamesAndValues, statValues, totalShotsAtMiddle, spareChances, fragment.mNumberOfGeneralDetails, toLoad); return new List<?>[] {listStatHeaders, listStatNamesAndValues}; }
/** * Upgrades database from oldVersion 2 to newVersion 3. * * @param db to upgrade */ @SuppressWarnings("CheckStyle") private void upgradeDatabaseFrom2To3(SQLiteDatabase db) { db.execSQL("DROP INDEX IF EXISTS frame_id_index"); db.execSQL("DROP INDEX IF EXISTS frame_game_fk_index"); db.execSQL( "CREATE TABLE frame2 (" + FrameEntry._ID + " INTEGER PRIMARY KEY, " + FrameEntry.COLUMN_FRAME_NUMBER + " INTEGER NOT NULL, " + FrameEntry.COLUMN_IS_ACCESSED + " INTEGER NOT NULL DEFAULT 0, " + FrameEntry.COLUMN_PIN_STATE[0] + " INTEGER NOT NULL DEFAULT 0, " + FrameEntry.COLUMN_PIN_STATE[1] + " INTEGER NOT NULL DEFAULT 0, " + FrameEntry.COLUMN_PIN_STATE[2] + " INTEGER NOT NULL DEFAULT 0, " + FrameEntry.COLUMN_FOULS + " INTEGER NOT NULL DEFAULT 0, " + FrameEntry.COLUMN_GAME_ID + " INTEGER NOT NULL" + " REFERENCES " + GameEntry.TABLE_NAME + " ON UPDATE CASCADE ON DELETE CASCADE, " + "CHECK (" + FrameEntry.COLUMN_FRAME_NUMBER + " >= 1 AND " + FrameEntry.COLUMN_FRAME_NUMBER + " <= 10), " + "CHECK (" + FrameEntry.COLUMN_IS_ACCESSED + " = 0 OR " + FrameEntry.COLUMN_IS_ACCESSED + " = 1)" + ");"); db.execSQL( "INSERT INTO frame2 (" + FrameEntry._ID + ", " + FrameEntry.COLUMN_FRAME_NUMBER + ", " + FrameEntry.COLUMN_IS_ACCESSED + ", " + FrameEntry.COLUMN_PIN_STATE[0] + ", " + FrameEntry.COLUMN_PIN_STATE[1] + ", " + FrameEntry.COLUMN_PIN_STATE[2] + ", " + FrameEntry.COLUMN_FOULS + ", " + FrameEntry.COLUMN_GAME_ID + ")" + " SELECT " + FrameEntry._ID + ", " + FrameEntry.COLUMN_FRAME_NUMBER + ", " + FrameEntry.COLUMN_IS_ACCESSED + ", " + FrameEntry.COLUMN_PIN_STATE[0] + ", " + FrameEntry.COLUMN_PIN_STATE[1] + ", " + FrameEntry.COLUMN_PIN_STATE[2] + ", " + FrameEntry.COLUMN_FOULS + ", " + FrameEntry.COLUMN_GAME_ID + " FROM " + FrameEntry.TABLE_NAME); db.execSQL("DROP TABLE " + FrameEntry.TABLE_NAME); db.execSQL("ALTER TABLE frame2 RENAME TO " + FrameEntry.TABLE_NAME); db.execSQL( "CREATE INDEX frame_id_index ON " + FrameEntry.TABLE_NAME + "(" + FrameEntry._ID + ")"); db.execSQL( "CREATE INDEX frame_game_fk_index ON " + FrameEntry.TABLE_NAME + "(" + FrameEntry.COLUMN_GAME_ID + ")"); try { db.beginTransaction(); for (int i = 0; i < 32; i++) { for (int j = 0; j < 3; j++) { ContentValues values = new ContentValues(); values.put(FrameEntry.COLUMN_PIN_STATE[j], i); db.update( FrameEntry.TABLE_NAME, values, FrameEntry.COLUMN_PIN_STATE[j] + "=?", new String[] {String.format("%5s", Integer.toBinaryString(i)).replace(' ', '0')}); } } for (int i = 24; i < 31; i++) { ContentValues values = new ContentValues(); values.put(FrameEntry.COLUMN_FOULS, i); db.update( FrameEntry.TABLE_NAME, values, FrameEntry.COLUMN_FOULS + "=?", new String[] {Score.foulIntToString(i)}); } db.setTransactionSuccessful(); } catch (Exception ex) { Log.e(TAG, "Error upgrading db from 2 to 3", ex); dropTablesAndRecreate(db); } finally { db.endTransaction(); } }