How to write score to SQLite db? - java

i'm a sqlite newbie. What I'm trying to do...I have a game and after the game ends it stores time result in a double variable named elapsedSeconds. I want to place that result in a db, and than in my dedicated activity show top 10 scores for the user. I have HighScoreDb class where I create a db (i used some code I found online, but I think it'll serve my purpose). Here's the code.
public class HighScoreDb {
private static class HighScoreDbHelper extends SQLiteOpenHelper {
public HighScoreDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(SCORE_TABLE_CREATE);
} catch (SQLException e) {
Log.i("Error", "Error making database");
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + SCORE_TABLE_NAME);
onCreate(db);
}
}
private static final int DATABASE_VERSION = 2;
private static final String SCORE_TABLE_NAME = "highscore";
private static final String SCORE_TABLE_CREATE = "CREATE TABLE "
+ SCORE_TABLE_NAME
+ " (_id INTEGER PRIMARY KEY autoincrement, "
+ "name TEXT NOT NULL, score DOUBLE NOT NULL)";
private static final String DATABASE_NAME = "highscores.db";
// The index (key) column name for use in where clauses.
public static final String KEY_ID = "_id";
// The name and column index of each column in your database.
public static final String KEY_NAME = "name";
public static final String KEY_SCORE = "score";
public static final int NAME_COLUMN = 1;
public static final int NUMBER_COLUMN = 2;
public static final int SCORE_COLUMN = 3;
SQLiteDatabase db;
private final Context ctx;
private final HighScoreDbHelper dbHelper;
public HighScoreDb(Context context) {
this.ctx = context;
ctx.deleteDatabase(SCORE_TABLE_NAME);
dbHelper = new HighScoreDbHelper(context);
db = dbHelper.getWritableDatabase();
}
public void close() {
if (db != null) {
db.close();
}
}
public void createRow(String name, int score) {
ContentValues intialValue = new ContentValues();
intialValue.put("name", name);
intialValue.put("score", score);
db.insertOrThrow(SCORE_TABLE_NAME, null, intialValue);
}
public void deleteRow(long rowId) {
db.delete(SCORE_TABLE_NAME, "_id=" + rowId, null);
}
public Cursor GetAllRows() {
try {
return db.query(SCORE_TABLE_NAME, new String[] { "_id", "name", "score" }, null,
null, null, null, "score DESC");
} catch (SQLException e) {
Log.i("Error on query", e.toString());
return null;
}
}
public void updateRow(long _id, String name, String score) {
ContentValues args = new ContentValues();
args.put("name", name);
args.put("number", score);
db.update(SCORE_TABLE_NAME, args, "_id=" + _id, null);
}
}
From this table I will not need column name, cause I will just have 10 places with scores. How to insert that result in this db after my game ends? I think I know how to read from it, i will do something like this:
HighScoreDb db = new HighScoreDb(this);
Cursor myCursor = db.GetAllRows();
myCursor.moveToPosition(0);
String Row1Value2 = myCursor.getString(2);
myCursor.close();
db.close();
I'm calling it in my games class like this:
HighScoreDb db = new HighScoreDb(this);

I'm not sure i've understand your question... To put some datas in your db, you just have to correctly use your functions wrote below (i assume your class is working fine), for example :
HighScoreDbHelper myDbHelper = new HighScoreDbHelper(yourContext);
myDbHelper.createRow(yourName, yourScore);
This tutorial is a good starter to sqlite concepts : http://www.vogella.com/articles/AndroidSQLite/article.html

The way you open the database is fine.
Instead of using a cursor to get the particular information about a row, make an entity that represents a row inside the table. Create a list of these objects using the information from the Cursor.
public UserScore {
String name;
Integer score; // don't know why you would use double here.
// getters + setters or make it immutable
}
What I would provide is some method inside HighScoreDb to add a new score. For example with signature
public void addScore(UserScore userScore);
Don't think about just adding 10 scores, add every score to the database. Whenever you want the top 10 scores. Just query the last 10 scores descending. Otherwise you are programming a lot of complexity which is easily done with a query. To do this look into top-N queries.
An example writing to the DB inside the helper is like this, (didn't test the SQL but it should be in this form)
this.getWritableDatabase().execSQL("insert into highscore (name, score) values (" + userScore.getName() + "," + userScore.getScore() + ")");

Related

Data from Database is not being displayed

Not too sure how to explain this but will give it my best.
I have created a database within my Android project:
public class FootySortItDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "FootySortItDatabase";
private static final int DATABASE_VERSION = 1;
public FootySortItDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_PLAYER_TABLE = "CREATE TABLE " +
PlayerDetails.PlayerTableEntry.TABLE_NAME + "(" +
PlayerDetails.PlayerTableEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
PlayerDetails.PlayerTableEntry.COLUMN_PLAYER_NAME + " TEXT NOT NULL, " +
PlayerDetails.PlayerTableEntry.COLUMN_PLAYER_NUMBER + " TEXT NOT NULL, " +
PlayerDetails.PlayerTableEntry.COLUMN_IS_PLAYING + " INTEGER NOT NULL " +
");";
db.execSQL(SQL_CREATE_PLAYER_TABLE);
}
I have set the following contract:
public static final class PlayerTableEntry implements BaseColumns{
public static final String TABLE_NAME = "playerTable";
public static final String COLUMN_PLAYER_NAME = "playerName";
public static final String COLUMN_PLAYER_NUMBER = "playerNumber";
public static final String COLUMN_IS_PLAYING = "isPlaying";
}
I call a method which passes a DB and an array of details:
private SQLiteDatabase playerDatabase;
private Cursor getAllPlayers(){
playerDatabase = ComposeMessage.addPlayerToTheDatabase(playerDatabase, playerDataSet);
return playerDatabase.query(PlayerDetails.PlayerTableEntry.TABLE_NAME,
null,null,null,
null,null,null);
}
public static SQLiteDatabase addPlayerToTheDatabase(SQLiteDatabase playerDatabase, ArrayList<PlayerDetails> listGame) {
for (PlayerDetails i : listGame) {
ContentValues cv = new ContentValues();
cv.put(PlayerDetails.PlayerTableEntry.COLUMN_PLAYER_NAME, i.name);
cv.put(PlayerDetails.PlayerTableEntry.COLUMN_PLAYER_NUMBER, i.number);
playerDatabase.insert(PlayerDetails.PlayerTableEntry.TABLE_NAME, null, cv);
}
return playerDatabase;
}
Then, I pass the cursor into my RecyclerView :
public PlayerListRecyclerViewAdapter(Context context, Cursor cursor, ArrayList<PlayerDetails> aPlayerList,
int count) {
playerDataSet = aPlayerList;
this.pCursor = cursor;
pContext = context;
But my pCursor = 0. Which means that their are no rows in the table??
Via the terminal I use adb to navigate to the database, use SQLite3 on the DB to search the data of the table but it does not return anything:
sqlite> .tables
android_metadata playerTable
sqlite> select * from playerTable;
sqlite>
when I debug I can see during the insert part, that i.name and i.number has data to it and "it looks to be inserting it" but then why is cursor 0 and when I search the data, why is it not returning anything?
Not sure how to over come this...
There are 3 columns in the table. None of them can be null. When you write into the database, you are writing to 2 columns instead of 3. As a result, the insertion will fail.
To create a database, I recommend Schematic and use Stetho for debugging.

Android SQL lite DB adapter updating DB [duplicate]

This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 6 years ago.
I found a DB adapter searching the internet for android resources. I am currently trying to store information like location in the database. I got it working, but when I go back to try and add more columns, I get errors like "the column doesn't exist". so my question is, how can I delete the database and recreate it with these new columns? here is my code, everything worked until I added the "stamp" string...
// ------------------------------------ DBADapter.java ---------------------------------------------
// TODO: Change the package to match your project.
package biz.tanners.geo_x;
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;
// TO USE:
// Change the package (at top) to match your project.
// Search for "TODO", and make the appropriate changes.
public class DBAdapter {
/////////////////////////////////////////////////////////////////////
// Constants & Data
/////////////////////////////////////////////////////////////////////
// For logging:
private static final String TAG = "DBAdapter2";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
/*
* CHANGE 1:
*/
// TODO: Setup your fields here:
public static final String KEY_NAME = "name";
public static final String KEY_LONGITUDE = "longitude";
public static final String KEY_LATTITUDE = "lattitude";
public static final String KEY_STAMP = "stamp";
// TODO: Setup your field numbers here (0 = KEY_ROWID, 1=...)
public static final int COL_NAME = 1;
public static final int COL_LONGITUDE= 2;
public static final int COL_LATTITUDE = 3;
public static final int COL_STAMP = 4;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_NAME, KEY_LONGITUDE, KEY_LATTITUDE, KEY_STAMP};
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
public static final int DATABASE_VERSION = 4;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
/*
* CHANGE 2:
*/
// TODO: Place your fields here!
// + KEY_{...} + " {type} not null"
// - Key is the column name you created above.
// - {type} is one of: text, integer, real, blob
// (http://www.sqlite.org/datatype3.html)
// - "not null" means it is a required field (must be given a value).
// NOTE: All must be comma separated (end of line!) Last one must have NO comma!!
+ KEY_NAME + " text not null, "
+ KEY_LONGITUDE + " double not null, "
+ KEY_LATTITUDE + " double not null, " + KEY_STAMP + " text not null"
// Rest of creation:
+ ");";
// Context of application who uses us.
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
/////////////////////////////////////////////////////////////////////
// Public methods:
/////////////////////////////////////////////////////////////////////
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to the database.
public long insertRow(String name, double longitude, double lattitude, String stamp) {
/*
* CHANGE 3:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_LONGITUDE, longitude);
initialValues.put(KEY_LATTITUDE, lattitude);
initialValues.put(KEY_STAMP, stamp);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, double longitude, double lattitude, String stamp) {
String where = KEY_ROWID + "=" + rowId;
/*
* CHANGE 4:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_LONGITUDE, longitude);
newValues.put(KEY_LATTITUDE, lattitude);
newValues.put(KEY_STAMP, stamp);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
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_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such column: stamp (code 1): , while compiling: SELECT DISTINCT _id, name, longitude, lattitude, stamp FROM mainTable2)
Am giving you answer as I understood. You can make a drop table query and call that when you needed to delete that table or tables and whenever you want to create that table you can make create table query.

Android - How to access already created database from other class?

Here is my SQLiteOpenHelper class :
public class MySQLiteHelper extends SQLiteOpenHelper {
...
//all the code
SQLiteDatabase db;
String url;
String title;
String init_price;
String cur_price;
byte[] image;
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "ProductsDB";
// Products table name
private static final String TABLE_NAME = "products";
// Products Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_URL = "url";
private static final String KEY_TITLE = "title";
private static final String KEY_INIT_PRICE = "init_price";
private static final String KEY_CUR_PRICE = "cur_price";
private static final String KEY_IMAGE = "image";
private static final String[] COLUMNS = {KEY_ID, KEY_URL, KEY_TITLE, KEY_INIT_PRICE,KEY_CUR_PRICE, KEY_IMAGE};
//An array of database
String[][] table = new String[10][5];
byte[][] images = new byte[10][1];
int len = 0; //no.of rows in the table
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
this.db = db;
// SQL statement to create a products table
String CREATE_PRODUCTS_TABLE = "CREATE TABLE " + TABLE_NAME + " ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"url TEXT, " +
"title TEXT, " +
"init_price TEXT," +
"cur_price TEXT," +
"image BLOB" +
" );";
// create products table
db.execSQL(CREATE_PRODUCTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
// Create tables again
onCreate(db);
}
void read() {
int i = 0;
// 1. build the query
String query = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
do {
table[i][0] = cursor.getString(0);
table[i][1] = cursor.getString(1);
table[i][2] = cursor.getString(2);
table[i][3] = cursor.getString(3);
table[i][4] = cursor.getString(4);
images[i] = cursor.getBlob(5);
i++;
} while (cursor.moveToNext());
}
}
String[][] getTable() {
return table;
}
}
My List class :
Here in this class, I want to create a listview from the values in the database.
How do I access those values?
List.java :
public class List extends Activity {
MySQLiteHelper obj = new MySQLiteHelper(this);
// I have all the methods to get required data from database.
// But I'm unable to call those methods directly. Why?
// I actually can access those methods from a service.
// But now, I'm getting "Cannot resolve method" error.
MySQLiteHelper obj = new MySQLiteHelper(this);
obj.getLength(); //I'm getting error here
obj.read(); // It says that it cannot resolve the method.
}
Why is that? I put the same code in a thread inside List.java class and then I'm able to access those methods.
MySQLiteHelper has no method for getLength() but that is ok. (more on this at the end)
the read() method is not public, and it really does nothing other than populate the table member/field of the MySQLiteHelper class.
You aren't leveraging the getTable() method you created (which also is not public).
lets go ahead and make getTable public (consider renaming this as it is really returning table data and not an actual database table, up to you tho), and anytime it is called, lets also call read() anytime this method is called
// renamed from getTable
public String[][] getTableData() {
read();
return table;
}
With this small modification, your usage should look something like this:
MySQLiteHelper obj = new MySQLiteHelper(this);
String[][] tabledata = obj.getTableData();
// get the Length (no getLength() method needed as we will poll the tabledata length property.
int length = tabledata.length;
I'm going to assume (and I apologize if I'm incorrect) that this your first crack at doing android databases. So it might be good to read a tutorial like this one:
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
HTHS :)

Sqlite 'no such table' Error while Inserting Values to Database

I get this error when adding data to a table in my Sqlite database.
12-21 17:31:19.345: E/SQLiteLog(24127): (1) no such table: accessory_data
12-21 17:31:19.345: E/DB ERROR(24127): android.database.sqlite.SQLiteException:
no such table: accessory_data (code 1): ,
while compiling: SELECT aid, name, image, url, price
FROM accessory_data
Note that the Database is previously created by another method in order to add data to another table. What I'm doing here is simply adding data to a different table in the same database. Is that the root of the problem?
DBOperations Class:
public class DBOps extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "jezzadb";
public String CREATE_ACC_QUERY = "CREATE TABLE " + AccessoriesTableInfo.TABLE_NAME + " (" + AccessoriesTableInfo.AID + " VARCHAR, " +
AccessoriesTableInfo.NAME + " VARCHAR, " + AccessoriesTableInfo.IMAGE + " VARCHAR, " + AccessoriesTableInfo.PRICE + " VARCHAR, " +
AccessoriesTableInfo.URL + " VARCHAR);";
public DBOps(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_ACC_QUERY);
}
public void insertAccessories(DBOps dop, Accessories a)
{
SQLiteDatabase SQ = dop.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(AccessoriesTableInfo.AID, a.ID);
cv.put(AccessoriesTableInfo.NAME, a.Name);
cv.put(AccessoriesTableInfo.URL, a.URL);
cv.put(AccessoriesTableInfo.IMAGE, a.Image);
cv.put(AccessoriesTableInfo.PRICE, a.PRICE);
SQ.insert(AccessoriesTableInfo.TABLE_NAME, null, cv);
Log.d("Database Operations", "Inserted Accessories succesfully!");
}
public ArrayList<Accessories> getAccessories(DBOps dop)
{
ArrayList<Accessories> arr = new ArrayList<Accessories>();
SQLiteDatabase SQ = dop.getReadableDatabase();
String[] columns = {AccessoriesTableInfo.AID,AccessoriesTableInfo.NAME,AccessoriesTableInfo.IMAGE,AccessoriesTableInfo.URL,
AccessoriesTableInfo.PRICE};
Cursor CR = SQ.query(AccessoriesTableInfo.TABLE_NAME, columns, null, null, null, null, null);
CR.moveToFirst();
for(int i=0;i<CR.getCount();i++)
{
while (!CR.isAfterLast()) {
Accessories a= new Accessories();
a.ID = CR.getString(0);
a.Name = CR.getString(1);
a.URL = CR.getString(2);
a.Image = CR.getString(3);
a.PRICE = CR.getString(4);
arr.add(a);
CR.moveToNext();
}
CR.close();
break;
}
return arr;
}
AccessoriesTableInfo Class:
public class AccessoriesTableData {
public AccessoriesTableData()
{
}
public static abstract class AccessoriesTableInfo implements BaseColumns
{
public static final String AID = "aid";
public static final String NAME = "name";
public static final String IMAGE = "image";
public static final String URL = "url";
public static final String PRICE = "price";
public static final String TABLE_NAME = "accessory_data";
}
}
What am I doing wrong?
Note that the Database is previously created by another method in order to add data to another table. What I'm doing here is simply adding data to a different table in the same database. Is that the root of the problem?
Yes, that's the problem. Use only one SQLiteOpenHelper subclass per database file.
What happens is that the database file with the requested version 1 already exists, so no database helper lifecycle callbacks like onCreate() or onUpgrade() get invoked.
Further reading: When is SQLiteOpenHelper onCreate() / onUpgrade() run?

Android database working with currency/balance

I am developing an app that manages users expenses and incomes, I have reached a point where I am pretty stuck and feel like I need some help, What I want to do is save have a record of the total user balance and to be able to do calculations on it, depending on the users actions, If hes balance is 100 dollars and he adds an expense of 50 dollars, the saved balance will be updated to total of 50 dollars etc..
I am not sure what is the right way to do it or how to write the database function to do the math on the "balance" variable, this is my database class so far, I would really appreciate any example or tip.
Right now all I am having is the basic "add,update,remove,fetch" functions...
public class TransactionsDatabase {
private static final String DATABASE_NAME = "transactions_db";
private static final String DATABASE_TABLE = "transactions_table";
private static final int DATABASE_VERSION = 1;
private static final String TRANSACTION_ID = "_id";
private static final String TRANSACTION_AMOUNT = "amount";
private static final String TRANSACTION_DESCRIPTION = "description";
private static final String TRANSACTION_DATE = "date";
private static final String TRANSACTION_CATEGORY = "category";
private static final String TRANSACTION_CURRENCY = "currency_type";
private static final String TRANSACTION_EXPENSE_OR_INCOME = "expenseOrIncome";
private static int BALANCE; // this is how I have tried to use the balance so far...
private static final String CREATE_DATABASE = "create table transactions_table (_id integer primary key autoincrement, "
+ "amount integer not null, date text not null, category text not null, currency_type text not null, description text not null, expenseOrIncome text not null);";
private static final String TAG = "TransactionsDatabase";
private DatabaseHelper DbHelper;
private SQLiteDatabase SqlDatabase;
private final Context ctx;
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DATABASE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will erase old data");
db.execSQL("DROP TABLE IF EXISTS expenses_table");
onCreate(db);
}
}
TransactionsDatabase (Context c) {
this.ctx = c;
}
public TransactionsDatabase open() throws SQLException {
DbHelper = new DatabaseHelper(ctx);
SqlDatabase = DbHelper.getWritableDatabase();
return this;
}
public void close() {
DbHelper.close();
}
public long createExpenseOrIncome (int amount, String description, String date, String category, String currency_type, String expenseOrIncome) {
ContentValues values = new ContentValues();
values.put(TRANSACTION_AMOUNT, amount);
values.put(TRANSACTION_DESCRIPTION, description);
values.put(TRANSACTION_DATE, date);
values.put(TRANSACTION_CATEGORY, category);
values.put(TRANSACTION_CURRENCY, currency_type);
values.put(TRANSACTION_EXPENSE_OR_INCOME, expenseOrIncome);
// Returns the row ID of newly inserted row, or -1 if an error occurred.
return SqlDatabase.insert(DATABASE_TABLE, null, values);
}
public boolean deleteExpenseOrIncome(long rowId) {
// Returns true if deleted, false otherwise.
return SqlDatabase.delete(DATABASE_TABLE, TRANSACTION_ID + "=" + rowId, null) > 0;
}
public Cursor fetchAllExpensesAndIncomes() {
// Returns a cursor over the list of all expenses/incomes.
return SqlDatabase.query(DATABASE_TABLE, new String[] { TRANSACTION_ID,
TRANSACTION_AMOUNT, TRANSACTION_DESCRIPTION, TRANSACTION_DATE, TRANSACTION_CATEGORY, TRANSACTION_CURRENCY, TRANSACTION_EXPENSE_OR_INCOME }, null, null, null, null,
null);
}
public Cursor fetchSpecificExpenseOrIncome(long rowId) throws SQLException {
Cursor mCursor = SqlDatabase.query(true, DATABASE_TABLE, new String[] {
TRANSACTION_AMOUNT, TRANSACTION_DESCRIPTION,
TRANSACTION_DATE, TRANSACTION_CATEGORY, TRANSACTION_CURRENCY, TRANSACTION_EXPENSE_OR_INCOME },
TRANSACTION_ID + "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateExpenseOrIncome(long rowId, int amount, String description, String date, String category, String currency_type, String expenseOrIncome) {
// returns true if the expense/income was successfully updated, false otherwise.
ContentValues values = new ContentValues();
values.put(TRANSACTION_AMOUNT, amount);
values.put(TRANSACTION_DESCRIPTION, description);
values.put(TRANSACTION_DATE, date);
values.put(TRANSACTION_CATEGORY, category);
values.put(TRANSACTION_CURRENCY, currency_type);
values.put(TRANSACTION_EXPENSE_OR_INCOME, expenseOrIncome);
return SqlDatabase.update(DATABASE_TABLE, values, TRANSACTION_ID + "=" + rowId, null) > 0;
}
public boolean deleteAllExpensesOrIncomes() {
// true if any number of rows were deleted, false otherwise.
return SqlDatabase.delete(DATABASE_TABLE, null, null) > 0;
}
public boolean deleteSpecificExpenseOrIncome(long rowId) {
// true if a row is deleted, false otherwise.
return SqlDatabase.delete(DATABASE_TABLE, TRANSACTION_ID + "=" + rowId, null) > 0;
}
}
Since this is just a single-user android application, I'm going to skip the bit about caching calculated values (because an SQLite lookup is not very time-consuming). If you think you need that extra bit of performance, though, you should definitely consider having a second table to cache calculated values that is updated when you re-run your calculations.
Now then, on to your real question:
Let's say that you want to write a basic function to get the total balance based on your transactions and some base value. It might look a bit like this:
public int getBalance(int baseValue) {
String[] cols = new String[] {
"SUM(" + TRANSACTION_AMOUNT + ")"
};
try {
Cursor data = SqlDatabase.query(DATABASE_TABLE, cols, null, null, null, null, null);
return data.getInt(data.getColumnIndexOrThrow(cols[0])) + baseValue;
} catch(IllegalArgumentException e) {
Log.e("MyApp", "Couldn't get balance", e);
return 0;
}
}
The SUM(..) SQL function returns the sum of the values of the column.
Of course, this code won't work right away because, for one thing, you've got a separate expenseOrIncome column. There are a couple of ways to deal with that. Firstly: you could rewrite things to use only one column and have negative values be treated as expenses and positive values treated as income.
Alternatively, you could perform two queries. The first would select your income and the second your expenses. Then you'd subtract the expenses from the income to obtain your balance.

Categories

Resources