diff --git a/src/edu/rosehulman/sqlhighscores/SQLiteScoreAdapter.java b/src/edu/rosehulman/sqlhighscores/SQLiteScoreAdapter.java deleted file mode 100644 index 1d8df8b..0000000 --- a/src/edu/rosehulman/sqlhighscores/SQLiteScoreAdapter.java +++ /dev/null @@ -1,15 +0,0 @@ -package edu.rosehulman.sqlhighscores; - -public class SQLiteScoreAdapter { - // Just the tag we use to log - private static final String TAG = "SQLiteScoreAdapter"; - // Becomes the filename of the database - private static final String DATABASE_NAME = "scores.db"; - // Only one table in this database - private static final String TABLE_NAME = "scores"; - // We increment this every time we change the database schema which will - // kick off an automatic upgrade - private static final int DATABASE_VERSION = 1; - // TODO: Implement a SQLite database - -} diff --git a/src/edu/rosehulman/sqlhighscores/Score.java b/src/edu/rosehulman/sqlhighscores/Score.java index 7b779df..6e5bf08 100644 --- a/src/edu/rosehulman/sqlhighscores/Score.java +++ b/src/edu/rosehulman/sqlhighscores/Score.java @@ -6,8 +6,12 @@ public class Score implements Comparable{ private String mName; private int mScore; + private long mId; - public String getName() { return mName; } + public long getId() { return mId; } + public void setId(long id) { this.mId = id; } + + public String getName() { return mName; } public void setName(String name) { mName = name; } public int getScore() { return mScore; } @@ -15,5 +19,5 @@ public class Score implements Comparable{ public int compareTo(Score other) { return other.getScore() - getScore(); } - public String toString() { return getName() + " " + getScore(); } + public String toString() { return getId() + " " + getName() + " " + getScore(); } } diff --git a/src/edu/rosehulman/sqlhighscores/ScoreDataAdapter.java b/src/edu/rosehulman/sqlhighscores/ScoreDataAdapter.java new file mode 100644 index 0000000..f9d7ee5 --- /dev/null +++ b/src/edu/rosehulman/sqlhighscores/ScoreDataAdapter.java @@ -0,0 +1,148 @@ +package edu.rosehulman.sqlhighscores; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +public class ScoreDataAdapter { + // Becomes the filename of the database + private static final String DATABASE_NAME = "scores.db"; + // Only one table in this database + private static final String TABLE_NAME = "scores"; + // We increment this every time we change the database schema which will + // kick off an automatic upgrade + private static final int DATABASE_VERSION = 1; + + // TODO: Implement a SQLite database + private SQLiteOpenHelper mOpenHelper; + private SQLiteDatabase mDatabase; + // Android naming convention for IDs + public static final String KEY_ID = "_id"; + public static final String KEY_NAME = "name"; + public static final String KEY_SCORE = "score"; + + private static String DROP_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME; + private static String CREATE_STATEMENT; + static { + StringBuilder sb = new StringBuilder(); + sb.append("CREATE TABLE " + TABLE_NAME + " ("); + sb.append(KEY_ID + " integer primary key autoincrement, "); + sb.append(KEY_NAME + " text, "); + sb.append(KEY_SCORE + " integer"); + sb.append(")"); + CREATE_STATEMENT = sb.toString(); + } + + public ScoreDataAdapter(Context context) { + // Create a SQLiteOpenHelper + mOpenHelper = new ScoreDbHelper(context); + } + + public void open() { + // Open the database + mDatabase = mOpenHelper.getWritableDatabase(); + } + + public void close() { + // Close the database + mDatabase.close(); + } + + private ContentValues getContentValuesFromScore(Score score) { + ContentValues row = new ContentValues(); + row.put(KEY_NAME, score.getName()); + row.put(KEY_SCORE, score.getScore()); + return row; + } + + /** + * Add score to the table. + * + * @param score + * @return id of the inserted row or -1 if failed + */ + public long addScore(Score score) { + ContentValues row = getContentValuesFromScore(score); + long rowId = mDatabase.insert(TABLE_NAME, null, row); + score.setId(rowId); + return rowId; + } + + public Cursor getScoresCursor() { + String[] projection = new String[] { KEY_ID, KEY_NAME, KEY_SCORE }; + return mDatabase.query(TABLE_NAME, projection, null, null, null, null, + KEY_SCORE + " DESC"); + } + + public Score getScore(long id) { + String[] projection = new String[] { KEY_ID, KEY_NAME, KEY_SCORE }; + String selection = KEY_ID + " = " + id; + boolean distinctRows = true; + Cursor c = mDatabase.query(distinctRows, TABLE_NAME, projection, + selection, null, null, null, null, null); + if (c != null && c.moveToFirst()) { + return getScoreFromCursor(c); + } + return null; + } + + private Score getScoreFromCursor(Cursor c) { + Score s = new Score(); + s.setId(c.getInt(c.getColumnIndexOrThrow(KEY_ID))); + s.setName(c.getString(c.getColumnIndexOrThrow(KEY_NAME))); + s.setScore(c.getInt(c.getColumnIndexOrThrow(KEY_SCORE))); + return s; + } + + public void updateScore(Score score) { + ContentValues row = getContentValuesFromScore(score); + String selection = KEY_ID + " = " + score.getId(); + mDatabase.update(TABLE_NAME, row, selection, null); + } + + public boolean removeScore(long id) { + return mDatabase.delete(TABLE_NAME, KEY_ID + " = " + id, null) > 0; + } + + public boolean removeScore(Score s) { + return removeScore(s.getId()); + } + + public void logAll() { + Cursor c = getScoresCursor(); + if (c != null && c.moveToFirst()) { + Log.d(ScoresListActivity.SLS, "LOGGING TABLE"); + while (!c.isAfterLast()) { + Score score = getScoreFromCursor(c); + Log.d(ScoresListActivity.SLS, score.toString()); + c.moveToNext(); + } + } + } + + private static class ScoreDbHelper extends SQLiteOpenHelper { + + public ScoreDbHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(CREATE_STATEMENT); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.d(ScoresListActivity.SLS, "Updating from version " + oldVersion + + " to " + newVersion + + ", which will destroy old table(s)."); + db.execSQL(DROP_STATEMENT); + onCreate(db); + } + + } + +} diff --git a/src/edu/rosehulman/sqlhighscores/ScoresListActivity.java b/src/edu/rosehulman/sqlhighscores/ScoresListActivity.java index 690e6de..8c6f19c 100644 --- a/src/edu/rosehulman/sqlhighscores/ScoresListActivity.java +++ b/src/edu/rosehulman/sqlhighscores/ScoresListActivity.java @@ -1,10 +1,8 @@ package edu.rosehulman.sqlhighscores; -import java.util.ArrayList; -import java.util.Collections; - import android.app.Dialog; import android.app.ListActivity; +import android.database.Cursor; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; @@ -15,10 +13,10 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; +import android.widget.SimpleCursorAdapter; /** * Activity that displays a list view of Names and Scores Currently using no @@ -29,12 +27,16 @@ */ public class ScoresListActivity extends ListActivity { // A ListActivity is an Activity that supports a ListView. Its layout must - // include a ListView (and optionally TextView for when the list is empty) with specific ids: see that file. + // include a ListView (and optionally TextView for when the list is empty) + // with specific ids: see that file. + + private ScoreDataAdapter mScoreDataAdapter; + private SimpleCursorAdapter mCursorAdapter; /** * TAG for debug log messages */ - public static final String TAG = "Scores"; + public static final String SLS = "SLS"; /** * Dialog ID for adding and editing scores (one dialog for both tasks) @@ -52,31 +54,26 @@ public class ScoresListActivity extends ListActivity { */ private long mSelectedId = NO_ID_SELECTED; - /** - * Array holding the scores - */ - private ArrayList mScores = new ArrayList(); - - /** - * Adapter to fill the List View with mScores data Note: Could use the - * ListActivity function getListAdapter, but that results in a lot of ugly - * casting - */ - private ArrayAdapter mScoreAdapter; - - /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.scores_list_activity); - - mScoreAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, mScores); - // This is how a ListActivity sets the adapter, similar to how a ListView sets it. - setListAdapter(mScoreAdapter); - + mScoreDataAdapter = new ScoreDataAdapter(this); + mScoreDataAdapter.open(); + + Cursor cursor = mScoreDataAdapter.getScoresCursor(); + String[] fromColumns = new String[] { ScoreDataAdapter.KEY_NAME, + ScoreDataAdapter.KEY_SCORE }; + int[] toTextViews = new int[] { R.id.textViewName, R.id.textViewScore }; + mCursorAdapter = new SimpleCursorAdapter(this, + R.layout.score_list_item, cursor, fromColumns, toTextViews, 0); + // This is how a ListActivity sets the adapter, similar to how a + // ListView sets it. + setListAdapter(mCursorAdapter); + registerForContextMenu(getListView()); - + } /** @@ -170,9 +167,13 @@ protected void onDestroy() { * New score to add */ private void addScore(Score s) { - mScores.add(s); - Collections.sort(mScores); - mScoreAdapter.notifyDataSetChanged(); + // mScores.add(s); + // Collections.sort(mScores); + // mScoreAdapter.notifyDataSetChanged(); + mScoreDataAdapter.addScore(s); + Cursor cursor = mScoreDataAdapter.getScoresCursor(); + mCursorAdapter.changeCursor(cursor); + mScoreDataAdapter.logAll(); } /** @@ -182,7 +183,8 @@ private void addScore(Score s) { * Index of the score in the data storage mechanism */ private Score getScore(long id) { - return mScores.get((int) id); + // return mScores.get((int) id); + return mScoreDataAdapter.getScore(id); } /** @@ -194,13 +196,18 @@ private Score getScore(long id) { */ private void editScore(Score s) { if (mSelectedId == NO_ID_SELECTED) { - Log.e(TAG, "Attempt to update with no score selected."); + Log.e(SLS, "Attempt to update with no score selected."); } - Score selectedScore = getScore(mSelectedId); - selectedScore.setName(s.getName()); - selectedScore.setScore(s.getScore()); - Collections.sort(mScores); - mScoreAdapter.notifyDataSetChanged(); + s.setId((int) mSelectedId); + mScoreDataAdapter.updateScore(s); + Cursor cursor = mScoreDataAdapter.getScoresCursor(); + mCursorAdapter.changeCursor(cursor); + + // Score selectedScore = getScore(mSelectedId); + // selectedScore.setName(s.getName()); + // selectedScore.setScore(s.getScore()); + // Collections.sort(mScores); + // mScoreAdapter.notifyDataSetChanged(); } /** @@ -210,9 +217,12 @@ private void editScore(Score s) { * Index of the score in the data storage mechanism */ private void removeScore(long id) { - mScores.remove((int) id); - Collections.sort(mScores); - mScoreAdapter.notifyDataSetChanged(); + // mScores.remove((int) id); + // Collections.sort(mScores); + // mScoreAdapter.notifyDataSetChanged(); + mScoreDataAdapter.removeScore(id); + Cursor cursor = mScoreDataAdapter.getScoresCursor(); + mCursorAdapter.changeCursor(cursor); } // ======================================================================