views:

147

answers:

1

I'm using a SQLite database to store information on players and their teams using android. I've got it working so that all the players I've created will show up when ever I start my program, so the database is working. So far, so good.

However, whenever I try to retrieve the rowId of a player from the database, it always gives me 0 back. This surprises me in itself, since I'd think I'd get an error if I wasn't accessing it from the cursor correctly, but instead it gives me 0.

After debugging for a while, I realized that the Player object (not in database) also wasn't saving the id correctly, although it was finding a value for it. This was corrected when I set the id after creating the object, although it seems I would be able to set it in the creation statement itself. Curiouser and curiouser.

Even after I do have the id of the row, I can't edit it. The Player object will change, but if I actually retrieve the player from the database again, it hasn't changed at all.

Weirdest to me is that I don't receive any errors at any point throughout this process.

Ideas? Thank you in advance for your help! :-)

Here's my code for the Database Helper:

    public class VolleyDbAdapter {

 // Common
 public static final String KEY_ROWID = "id";
 public static final String KEY_NOTES = "Notes";

 // Player
 public static final String KEY_NUMBER = "Number";
 public static final String KEY_POSITION = "Position";
 public static final String KEY_FNAME = "FirstName";
 public static final String KEY_LNAME = "LastName";
 public static final String KEY_TEAMID = "teamId";


 private static final String TAG = "NotesDbAdapter";
 private DatabaseHelper mDbHelper;
 private SQLiteDatabase mDb;

 /**
  * Database creation sql statement
  */
 private static final String DATABASE_CREATE_PLAYERS = "CREATE TABLE 'players' ("
   + "  `id` INTEGER AUTO_INCREMENT DEFAULT NULL,"
   + "  `Number` INTEGER DEFAULT NULL,"
   + "  `Position` VARCHAR DEFAULT NULL,"
   + "  `FirstName` MEDIUMTEXT DEFAULT NULL,"
   + "  `LastName` MEDIUMTEXT DEFAULT NULL,"
   + "  `teamId` INTEGER DEFAULT NULL,"
   + "  `Notes` MEDIUMTEXT DEFAULT NULL,"
   + "  PRIMARY KEY (`id`)"
   + ");";

 private static final String DATABASE_PLAYERS = "players";
 private static final int DATABASE_VERSION = 5;

 private final Context mCtx;

 private static class DatabaseHelper extends SQLiteOpenHelper {

  DatabaseHelper(Context context) {
   super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  @Override
  public void onCreate(SQLiteDatabase db) {

   db.execSQL(DATABASE_CREATE_PLAYERS);
   db.execSQL(DATABASE_CREATE_GAMES);
   db.execSQL(DATABASE_CREATE_STATS);
   db.execSQL(DATABASE_CREATE_MATCHES);
   db.execSQL(DATABASE_CREATE_LINEUPS);
   db.execSQL(DATABASE_CREATE_TEAMS);

  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
     + newVersion + ", which will destroy all old data");

   // Add this later, when actually might update the database
   // Don't want to accidentally delete something now!
   db.execSQL("DROP TABLE IF EXISTS players;");
   db.execSQL("DROP TABLE IF EXISTS teams;");
   db.execSQL("DROP TABLE IF EXISTS matches;");
   db.execSQL("DROP TABLE IF EXISTS games;");
   db.execSQL("DROP TABLE IF EXISTS lineups;");
   db.execSQL("DROP TABLE IF EXISTS stats;");
   onCreate(db);
  }
 }

 public VolleyDbAdapter(Context ctx) {
  this.mCtx = ctx;
 }

 public VolleyDbAdapter open() throws SQLException {
  mDbHelper = new DatabaseHelper(mCtx);
  mDb = mDbHelper.getWritableDatabase();
  return this;
 }

 public void close() {
  mDbHelper.close();
 }

 public long createPlayer(String fname, String lname, int number,
   String position, long teamId) {
  ContentValues initialValues = new ContentValues();

  initialValues.put(KEY_FNAME, fname);
  initialValues.put(KEY_LNAME, lname);
  initialValues.put(KEY_NUMBER, number);
  initialValues.put(KEY_POSITION, position);
  initialValues.put(KEY_TEAMID, teamId);
  // Add the teamId?

  return mDb.insert(DATABASE_PLAYERS, null, initialValues);
 }

 public boolean deletePlayer(long rowId) {

  return mDb.delete(DATABASE_PLAYERS, KEY_ROWID + "=" + rowId, null) > 0;
 }

 public boolean deletePlayer(int number) {

  return mDb.delete(DATABASE_PLAYERS, KEY_NUMBER + "=" + number, null) > 0;
 }

 public Cursor fetchAllPlayers() {

  return mDb.query(DATABASE_PLAYERS, new String[] { KEY_ROWID,
    KEY_NUMBER, KEY_POSITION, KEY_FNAME, KEY_LNAME, KEY_TEAMID,
    KEY_NOTES }, null, null, null, null, null);
 }

 public Cursor fetchPlayer(long rowId) throws SQLException {

  Cursor mCursor =

  mDb.query(true, DATABASE_PLAYERS, new String[] { KEY_ROWID, KEY_NUMBER,
    KEY_POSITION, KEY_FNAME, KEY_LNAME, KEY_TEAMID, KEY_NOTES },
    KEY_ROWID + "=" + rowId, null, null, null, null, null);
  if (mCursor != null) {
   mCursor.moveToFirst();
  }
  return mCursor;

 }

 public Cursor fetchPlayer(int number) throws SQLException {

  Cursor mCursor =

  mDb.query(true, DATABASE_PLAYERS, new String[] { KEY_ROWID, KEY_NUMBER,
    KEY_POSITION, KEY_FNAME, KEY_LNAME, KEY_TEAMID, KEY_NOTES },
    KEY_NUMBER + "=" + number, null, null, null, null, null);
  if (mCursor != null) {
   mCursor.moveToFirst();
  }
  return mCursor;

 }

 public boolean updatePlayer(long rowId, String fname, String lname,
   int number, String position, long teamId) {
  ContentValues args = new ContentValues();

  args.put(KEY_FNAME, fname);
  args.put(KEY_LNAME, lname);
  args.put(KEY_NUMBER, number);
  args.put(KEY_POSITION, position);
  args.put(KEY_TEAMID, teamId);
  return mDb
    .update(DATABASE_PLAYERS, args, KEY_ROWID + "=" + rowId, null) > 0;
 }

And for loading the players:

    public class GlobalApp extends Application {
 SharedPreferences preferences;
 VolleyDbAdapter mDbHelper;
 public long teamId;
 public long matchId;
 public long gameId;


 ArrayList<Player> playerList;
 ArrayList<Player> court;
 ArrayList<Player> play;

 public int selectedPlayer;
 public int selectedPosition;
 //More vars not shown


 public void onCreate() {
  super.onCreate();
  preferences = PreferenceManager.getDefaultSharedPreferences(this);
  initializeVars();
  importOldData();
 }

 public void importOldData() {
  mDbHelper = new VolleyDbAdapter(this);
  mDbHelper.open();
  getPlayersFromDatabase();
  mDbHelper.close();
 }

    public void getPlayersFromDatabase() {
      Cursor c = mDbHelper.fetchPlayersFromTeam(getTeamId());
      c.moveToFirst();
      while (c.isAfterLast() == false) {
       long myId = c.getInt(c.getColumnIndex(VolleyDbAdapter.KEY_ROWID));
       String fname = c.getString(c
         .getColumnIndex(VolleyDbAdapter.KEY_FNAME));
       String lname = c.getString(c
         .getColumnIndex(VolleyDbAdapter.KEY_LNAME));
       String pos = c.getString(c
         .getColumnIndex(VolleyDbAdapter.KEY_POSITION));
       String num = c.getString(c
         .getColumnIndex(VolleyDbAdapter.KEY_NUMBER));
       long ti = c.getLong(c.getColumnIndex(VolleyDbAdapter.KEY_TEAMID));

       Player p = new Player(myId, fname, lname, num, pos, ti);
       addPlayer(p);

       c.moveToNext();
      }
      c.close();

     }

The code to create a new player (MenuManager is an activity that has the menu added to it):

public class EditPlayer extends MenuManager implements OnClickListener {

 GlobalApp global;
 VolleyDbAdapter mDbHelper;

 EditText s1, s2, s3;
 Button b1;
 Spinner choosePos;
 int editPosition;
 // Player selectedPlayer;
 ArrayAdapter<CharSequence> adapter;

 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.edit_player);
  global = ((GlobalApp) getApplicationContext());
  mDbHelper = new VolleyDbAdapter(this);
  mDbHelper.open();

  s1 = (EditText) this.findViewById(R.id.player_input_fname);
  s2 = (EditText) this.findViewById(R.id.player_input_lname);
  s3 = (EditText) this.findViewById(R.id.player_input_number);

  choosePos = (Spinner) findViewById(R.id.choosePos);
  adapter = ArrayAdapter.createFromResource(this, R.array.positions,
    android.R.layout.simple_spinner_item);
  adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  choosePos.setAdapter(adapter);

  b1 = (Button) this.findViewById(R.id.player_submit);
  b1.setOnClickListener(this);

  if (global.getSelectedPlayer() != null) {
   fillFields();
  }

 }

 public void fillFields() {
  s1.setText(global.getSelectedPlayer().getFName());
  s2.setText(global.getSelectedPlayer().getLName());
  s3.setText(global.getSelectedPlayer().getNumber());
  choosePos.setSelection(adapter.getPosition(global.getSelectedPlayer()
    .getPosition()));

 }

 @Override
 public void onClick(View v) {
  switch (v.getId()) {
  case R.id.player_submit:

   if (global.getSelectedPlayer() == null) {
    long myId = mDbHelper.createPlayer(s1.getText().toString(), s2
      .getText().toString(), Integer.parseInt(s3.getText()
      .toString()), choosePos.getSelectedItem().toString(),
      global.teamId);

    Player myP = new Player(myId, s1.getText().toString(), s2
      .getText().toString(), s3.getText().toString(),
      choosePos.getSelectedItem().toString(), global
        .getTeamId());
    myP.setId(myId);

    global.addPlayer(myP);
    global.sortPlayers(global.NUMBER);

    Intent intent = new Intent();
    setResult(RESULT_OK, intent);
    finish();
   } else {
    Player p = global.getSelectedPlayer();
    p.setFName(s1.getText().toString());
    p.setLName(s2.getText().toString());
    p.setNumber(s3.getText().toString());
    p.setPosition(choosePos.getSelectedItem().toString());

    mDbHelper.updatePlayer(p.getId(), p.getFName(), p.getLName(),
      p.getIntNumber(), p.getPosition(), p.getTeamId());

    global.sortPlayers(global.NUMBER);

    Intent intent = new Intent();
    setResult(RESULT_OK, intent);
    finish();
   }

   // this.finish();

   // setResult(0);
   break;
  }

 }

}

And finally, the player itself:

public class Player{
 String number;
 String fname;
 String lname;
 String position;
 long id;
 long teamId;

 public Player(String fn, String ln, String nu, String p, long t) {
  fname = fn;
  lname = ln;
  number = nu;
  position = p;
  teamId = t;
 }

 public Player(long i, String fn, String ln, String nu, String p, long t) {
  id = i;
  fname = fn;
  lname = ln;
  number = nu;
  position = p;
  teamId = t;
 }

 public void setId(long i) { id = i; }
 public long getId() { return id; }
 public long getTeamId() {return teamId; }
 //You should never need to set the teamId outside of the constructor


 public String getFName() { return fname; }
 public String getLName() { return lname; }
 public String getFullName() { return fname + " " + lname; }


 public String getNumber() { return number; }
 public int getIntNumber() { return Integer.valueOf(getNumber()); } 
 public String getPosition() { return position; }

 public int getHits() { return hits; }
 public int getSets() { return sets; }
 public int getSetsKills() { return setsKills; }
 public int getPasses() { return passes; }
 public int getPassesKills() { return passesKills; }
 public int getHitsKills() { return hitsKills; }
 public int getHitsMisses() { return hitsMisses; }
 public int getBlocks() { return blocks; }

 public void setFName(String s) { fname = s; }
 public void setLName(String s) { lname = s; }
 public void setNumber(String s) { number = s; }
 public void setPosition(String s) { position = s; }

 public String toString() { return getNumber(); }

 public String showMyStats() {

  /*TableLayout tb = new TableLayout(c);
   tb.addView(getStatRow("Number: ", getNumber(), c));
   tb.addView(getStatRow("Name: ", getName(), c));
   tb.addView(getStatRow("Position: ", getPosition(), c));
   tb.addView(getStatRow("", "", c));
   tb.addView(getStatRow("Hit Attempts: ", getHits(), c));
   tb.addView(getStatRow("Kills", getHitsKills(), c));
   tb.addView(getStatRow("", "", c));
   tb.addView(getStatRow("", "", c));*/

  String stats = "";
  stats += "Number: " + getNumber() + "\n";
  stats += "Name: " + getFullName() + "\n";
  stats += "Position: " + getPosition() + "\n";
  stats += "\n";
  stats += "Hit Attempts: " + getHits() + "\n";
  stats += "Kills: " + getHitsKills() + "\n";
  stats += "Misses: " + getHitsMisses() + "\n";
  stats += "Hitting Percentage: " + getHittingPercentage() + "\n";
  stats += "\n";
  stats += "Sets: " + getSets() + "\n";
  stats += "Set Kills: " + getSetsKills() + "\n";
  stats += "Setting Percentage: " + getSettingPercentage() + "\n";
  stats += "\n";
  stats += "Passes: " + getPasses() + "\n";
  stats += "Passes Kills: " + getPassesKills() + "\n";
  stats += "Passing Percentage: " + getPassingPercentage() + "\n";


  //TextView popup = new TextView(c);
  //popup.setLayout(new TableLayout());
  //popup.setText(stats);


  return stats;
 }

 public TableRow getStatRow(String s1, String s2, Context c) {
  TableRow tr = new TableRow(c);
  TextView t = new TextView(c);

  t.setText(s1);
  tr.addView(t);
  t.setText(s2);
  tr.addView(t);

  return tr;

 }

 public TableRow getStatRow(String s1, int s2, Context c) {
  return getStatRow(s1, Integer.toString(s2), c);

 }

 public double getHittingPercentage() {
  if(getHits() > 0) {
   return (getHitsKills()-getHitsMisses()) / getHits(); 
  } else { return 0; }

 }

 public double getSettingPercentage() {
  if(getSets() > 0) {
   return (getSetsKills()) / getSets(); 
  } else { return 0; }

 }

 public double getPassingPercentage() {
  if(getPasses() > 0) {
   return (getPassesKills()) / getPasses(); 
  } else { return 0; }

 }

}
A: 

Actually, I think the right formula for auto increment is :

INTEGER PRIMARY KEY AUTOINCREMENT

not

AUTO_INCREMENT

Sephy
Good idea! I just tried that, but it crashed. LogCat says it found a "syntax error near AUTOINCREMENT", so I think that part's okay as is. Also, I'm getting a non-0 value returned when I add a player, and that should be the rowId, so that seems to be working. Thanks for the help though!
Geekgirl
weird. I always wrote it that way and never got a crash.If you have issues with databases, download SQLite database browser, It helps a lot dealing with databases.
Sephy
Wow, SQLite database browser rocks! Thanks! You're right, for some reason it's not adding anything at all to the id field, it just contains "".
Geekgirl
Oops! On further examination it was the fact that I forgot the ending comma that autoincrement didn't work! oops! When I replaced:`id` INTEGER AUTO_INCREMENT DEFAULT NULL,"with`id` INTEGER PRIMARY KEY AUTOINCREMENT,"it worked! I'm not sure whether it was taking away the default or assigning it as the primary key initially that did the trick, but it now has an id. Yay!
Geekgirl
Wonderful! It's working great now!
Geekgirl
Indeed, I didn't spotted that.you actually had 2 errors, the spelling for autoincrement AND the Default null which has absolutely no sense in this context. Good luck with SQLite Database browser. It saved me a lot of time when I was building raw queries.
Sephy