I am new to Room, Rxjava and other android architecture components. I am trying to update/insert 2 records (If row already exists,update it. otherwise insert a new row.) I have tried to do it in following way. But, I didn't work.
GameActivity:
public class GameActivity extends AppCompatActivity {
...
public void onGameWinnerChanged(Player winner) {
mDisposable.add(gameViewModel.updateDb(winner)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.e("Success!!!", "updated records")
, throwable -> {
throwable.printStackTrace();
}));
}
}
GameViewModel:
public class GameViewModel extends ViewModel {
...
public Completable updateDb(Player winner) {
return Completable.fromAction(() -> {
updateWinner(winner);
Player loser = game.player1 == winner ? game.player2 : game.player1;
updateLoser(loser);
});
}
private void updateLoser(Player loser) {
User user = userDataSource.getSingleRecordFromName(loser.name);
if (user != null) {
user.loss++;
userDataSource.updateRecord(user);
} else {
user = new User(loser.name, "", 0, 0, 1);
userDataSource.insertOrUpdateUser(user);
}
}
private void updateWinner(Player winner) {
User user = userDataSource.getSingleRecordFromName(winner.name);
if (user != null) {
user.wins++;
userDataSource.updateRecord(user);
} else {
user = new User(winner.name, "", 0, 1, 0);
userDataSource.insertOrUpdateUser(user);
}
}
}
LocalUserDataSource
public class LocalUserDataSource implements UserDataSource {
private DaoAccess daoAccess;
public LocalUserDataSource(DaoAccess daoAccess){
this.daoAccess=daoAccess;
}
@Override
public Flowable<List<User>> getUsers() {
return daoAccess.fetchAllData();
}
@Override
public void insertOrUpdateUser(User user) {
Log.e("local user ds","insertOrUpdateUser");
daoAccess.insertOnlySingleRecord(user);
}
@Override
public User getSingleRecordFromName(String strName) {
return daoAccess.getSingleRecord(strName);
}
@Override
public void updateRecord(User user) {
daoAccess.updateRecord(user);
}
@Override
public void deleteRecord(User user) {
daoAccess.deleteRecord(user);
}
}
DaoAccess
@Dao
public interface DaoAccess {
@Insert
void insertOnlySingleRecord(User user);
@Query("SELECT * FROM User")
Flowable<List<User>> fetchAllData();
@Query("SELECT * FROM User WHERE name =:strName")
User getSingleRecord(String strName);
@Update
void updateRecord(User user);
@Delete
void deleteRecord(User user);
}
The problem is, when I try to run,NullPointer exceptions occurs if I try to insert any user which is not in database in following line of GameViewModel class.
User user = userDataSource.getSingleRecordFromName(loser.name);
Can anyone tell me where I am wrong or what should I do?
Edit
What I want to do is first fetch a user if it is there in database, update increment or decrement the score (if winner then +1 the wins column if loser then +1 the loss column). In case the user does not exists in the table, then create a new entry.
@Insert(onConflict = OnConflictStrategy.REPLACE) void insertOnlySingleRecord(User user);
you can update or replace like this. in your ` DaoAccess` – TaoismgetSingleRecord
query. – Taoism