Cursor doesn't find columns? - android

I tried to load a list of values from a table, but the cursor doesn't find the columns?
The Code which is buggy:
public final AccessToken[] fetchAccessTokenByServerId(final long serverId) {
final Cursor c = db.query(
ACCESS_TOKEN_TABLE,
new String[] { ACCESS_TOKEN_COL_ID, ACCESS_TOKEN_COL_VALUE },
ACCESS_TOKEN_COL_SERVER_ID + "=?",
new String[] { Long.toString(serverId) },
null,
null,
null);
AccessToken[] result = new AccessToken[c.getCount()];
for (int i = 0; i < result.length; i++) {
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[i] = new AccessToken(value, id, serverId);
c.moveToNext();
}
return result;
}
public static final String COL_ID = "_id";
public static final String ACCESS_TOKEN_TABLE = "accesstoken";
public static final String ACCESS_TOKEN_COL_ID = COL_ID;
public static final String ACCESS_TOKEN_COL_SERVER_ID = "server_id";
public static final String ACCESS_TOKEN_COL_VALUE = "value";
But the first two statements in the for-loop fails:
Index -1 is requested, with a size of
1
The table exists with the columns: _id (= int), server_id (= int) and value (= string)
There is one entry: 1, 1, test
The parameter of the function is 1.
Sincerely
xZise

Just after initializing your cursor, do this:
c.moveToFirst();

In this part of the code I recommend it this way
Original:
AccessToken[] result = new AccessToken[c.getCount()];
for (int i = 0; i < result.length; i++) {
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[i] = new AccessToken(value, id, serverId);
c.moveToNext();
}
Modified:
if (c.moveToFirst()){
int rowCount = c.getCount();
AccessToken[] result = new AccessToken(rowCount);
int recCount = 0;
while (!c.isAfterLast()){
long id = c.getLong(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_ID));
String value = c.getString(c.getColumnIndexOrThrow(ACCESS_TOKEN_COL_VALUE));
result[recCount++] = new AccessToken(value, id, serverId);
c.moveToNext();
}
c.close(); // <-- IMPORTANT!!!!
}

Related

SQLite in Android

I want to read bookname field in database, but it does not work in this class.
How can I use this class?
public Person readPerson(String bookkname) {
Person person = null;
String[] columns = new String[]{"id" ,"bookname"};
String selection = "bookname=?";
String[] selectionArgs = new String[]{ bookkname};
String groupBy = null;
String having = null;
String orderBy = null;
String limit = null;
SQLiteDatabase database = null;
try {
database = sqLiteOpenHelper.getWritableDatabase();
Cursor cursor = database.query("tbl_persons", columns, selection, selectionArgs, groupBy, having, orderBy, limit);
if(cursor != null && cursor.moveToFirst()) {
int idIndex = 0;
int payIndex = 1;
int lastunitIndex = 2;
int lastlessenIndex = 3;
int booknameIndex = 4;
int maxfreeunitIndex = 5;
long personId = cursor.getLong(idIndex);
String personpay = cursor.getString(payIndex);
String personlastunit = cursor.getString(lastunitIndex);
String personlastlessen = cursor.getString(lastlessenIndex);
String personbookname = cursor.getString(booknameIndex);
String personmaxfreeunit = cursor.getString(maxfreeunitIndex);
person = new Person();
person.setId(personId);
person.setpay(personpay);
person.setlastunit(personlastunit);
person.setlastlessen(personlastlessen);
person.setbookname(personbookname);
person.setmaxfreeunit(personmaxfreeunit);
}
} catch (Exception ex) {
Log.d("Database", "Exception:" + ex.getMessage());
} finally {
if (database != null && database.isOpen()) {
database.close();
}
}
return person;
}
I try call readperson class like inner but cant give data from data base or give to me packagename
Please tell to me way of calling this class ?
PersonDatabaseAdapter databaseAdapteer = new PersonDatabaseAdapter(Main2Activity.this);
Person persoon = new Person();
databaseAdapteer = new PersonDatabaseAdapter(this);
username = databaseAdapteer.readPerson(pass.toString());

Problems with database

I have a problem with getting Shop from database:
Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
getShop function in ShopHandler.java
Shop getShop(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_SHOPS, new String[] { KEY_ID,
KEY_SHOP }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Shop shop = new Shop(Integer.parseInt(cursor.getString(0)), cursor.getString(1)); //first problem place
return shop;
}
and part of procedure in MainClass:
public void AddToList(View view)
{
EditText search = (EditText)findViewById(R.id.editTextsearch);
String SearchProduct = search.getText().toString();
int l = 0;
int p = 0;
ShopHandler sh = new ShopHandler(this);
String[] Shops = new String[sh.getShopCount()];
float[] prices = new float[sh.getShopCount()];
for(int i=0;i<=sh.getShopCount();i++)
{
Shop shop = sh.getShop(i); //hear is second problemplace
ShopName = shop.getShop();
ProductHandler ph = new ProductHandler(this);
for(int j=0;j<ph.getProductsCount();j++)
{
if(ph.getProduct(j).getName()==SearchProduct)
{
Shops[++l]=ShopName;
prices[++p]=ph.getProduct(j).price;
}
}
}
The cursor is empty. Check moveTo...() return value before accessing row data:
Shop shop = null;
if (cursor.moveToFirst()) {
shop = new Shop(Integer.parseInt(cursor.getString(0)), cursor.getString(1)); //first problem place
}
cursor.close();
return shop;
This causes the exception. Why the cursor is empty is likely because of the off-by-one here:
for(int i=0;i<=sh.getShopCount();i++)
Either start counting from 1 or change <= to <, depending on your data.
This is most likely the issue:
for(int i=0;i<=sh.getShopCount();i++)
should be for(int i=0;i < sh.getShopCount();i++)
You will be off-by-one if you keep your first loop to stop at sh.getShopCount()

Android Null Pointer Exception SQLite

I am trying to get book data from my database but I keep running into a NullPointerException. I have a double array Entries that I want filled with a book item and its 5 corresponding details. I know I have extra elements in the InventoryAdapter array that I dont use in this method, but I keep it there since I use it elsewhere.
The error occurs at Entries[i][0] = InventoryAdapter.getInventoryByISBN(records[i][0])[1]; and by extension at Cursor cursor = db.rawQuery(query, new String[] {ISBN});
Why would the error be at the Cursor? I would have thought the error would probably occur with calling an array location that doesn't exist.
Main code
int numEntries = 2;
Entries = new String[numEntries][5];
int totalCount = 0;
if (BuildConfig.DEBUG)
Log.d(debug.LOG, "numEntries="+numEntries);
Toast.makeText(ReportsByDateScreen.this, "numEntries="+numEntries, Toast.LENGTH_LONG).show();
// Set up search array
for(int i = 0; i < numEntries; i++)
{
Entries[i][0] = InventoryAdapter.getInventoryByISBN(records[i][0])[1];
Entries[i][1] = InventoryAdapter.getInventoryByISBN(records[i][0])[2];
Entries[i][2] = InventoryAdapter.getInventoryByISBN(records[i][0])[4];
Entries[i][3] = InventoryAdapter.getInventoryByISBN(records[i][0])[3];
for(int j = 0; j < records.length; j++)
{
if(records[j][0].equals(InventoryAdapter.getInventoryByISBN(records[i][0])[0]))
{
totalCount+=Integer.parseInt(InventoryAdapter.getInventoryByISBN(records[i][0])[8]);
}
}
Entries[i][4] = ((Integer)totalCount).toString();
reportArray.add(new ReportsItem(records[i][0],Entries[i]));
totalCount = 0;
}
InventoryAdapter
public static String[] getInventoryByISBN(String ISBN)
{
String[] entry = new String[9];
//Query
String query = "select * from INVENTORY where ISBN = ?";
Cursor cursor = db.rawQuery(query, new String[] {ISBN});
if(cursor.getCount()<1) // title Not Exist
{
cursor.close();
for(int i = 0; i < 9; i++)
entry[i] = "Not Found";
return entry;
}
cursor.moveToFirst();
//put data into respective variable
int publish = cursor.getInt(cursor.getColumnIndex("PUBLISH_DATE"));
String publishdate = ((Integer)publish).toString();
String title = cursor.getString(cursor.getColumnIndex("TITLE"));
String author = cursor.getString(cursor.getColumnIndex("AUTHOR"));
String callNumber = cursor.getString(cursor.getColumnIndex("CALL_NUMBER"));
int available = cursor.getInt(cursor.getColumnIndex("AVAILABLE_COUNT"));
String availablecount = ((Integer)available).toString();
int inventory = cursor.getInt(cursor.getColumnIndex("INVENTORY_COUNT"));
String inventorycount = ((Integer)inventory).toString();
int due = cursor.getInt(cursor.getColumnIndex("DUE_PERIOD"));
String dueperiod = ((Integer)due).toString();
int checkoutcount = cursor.getInt(cursor.getColumnIndex("COUNT"));
String count = ((Integer)checkoutcount).toString();
//combine variables into one array
entry[0] = ISBN;
entry[1] = title;
entry[2] = author;
entry[3] = publishdate;
entry[4] = callNumber;
entry[5] = availablecount;
entry[6] = inventorycount;
entry[7] = dueperiod;
entry[8] = count;
cursor.close();
return entry;
}
There is 2 different possibilities here :
ISBN is null (and by extension records[i][0] is null too);
db is null
I'll look into that if I were you.
Use the debugger.
I can tell you much because you don't post the code of your init of the SQLiteDatabase.

Editing cursor data before display

I'm new in android and Java world and I want to edit cursor data result before displaying it. To do so I wrote the following code
private static final String[] INTERNAL_COLUMNS_1 = new String[] {
MediaStore.Audio.Media._ID,MediaStore.Audio.Media.TITLE};
private static final String[] INTERNAL_COLUMNS_2 = new String[] {
MediaStore.Audio.Media._ID, "fixString(" + MediaStore.Audio.Media.TITLE + ")"};
private Cursor getInternals() {
return query(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS_1,
constructBooleanTrueWhereClause(mFilterColumns),
null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
}
private Cursor mCursor = new SortCursor(getInternals());
public String fixString(String oldstr)
{
String str = new String(oldstr);
str = str.replace("_", " ");
if (Character.isLowerCase(str.charAt(0)))
{
str = str.substring(0,1).toUpperCase() + str.substring(1,str.length());
}
for(int i=1;i<str.length();i++)
{
if ((Character.isUpperCase(str.charAt(i)))
&& (Character.isLetter(str.charAt(i)))
&& (Character.isLowerCase(str.charAt(i - 1)))
&& (Character.isLetter(str.charAt(i - 1))))
{
str = str.substring(0,i) + " " + str.substring(i,str.length());
}
}
return str;
}
public static void main(){
for (int i = 0; i < mCursor.getCount(); i++)
{
mCursor.moveToPosition(i);
String string = mCursor.getString(1);
Log.d("OUT"," string = "+ string);
}
Using INTERNAL_COLUMNS_1, the log shows
TomSkinner
Jack_Smith
foxRayan
I want to have as the cursor result :
Tom Skinner
Jack Smith
Fox Rayan
So I used INTERNAL_COLUMNS_2, but I have exception
android.database.sqlite.SQLiteException: no such function: fixString
Does any one know how to do so, or any other idea ?
You need to either change the data before it gets into the database, or change it before you display it. What you are trying to do is create a function and use it in a SQLite query, which will not work. Removing the fixString parts from the SQL query and then using it on the string from the cursor is one way it will work.
for (int i = 0; i < mCursor.getCount(); i++)
{
mCursor.moveToPosition(i);
String string = mCursor.getString(1);
Log.d("OUT"," string = "+ fixString(string));
}

My device doesnt recognize my DB where my emulator does

When I try to query using my db in the femulator it works perfectly, but given the same appliction and same varibales into the device (milestone) it seems like the DB is not recognized.
I think the key to solving it is to understand where on the device we store the db.
On the emulator it's on /data/data/com.countryCityGame/databases/test1.db
But when I am using the device itself it must be in another place, does someone know where?
This is the java code where I build the DB:
public static void main(String[] args) throws Exception {
String CITIES[] = city.split(",");
String ANIMEL[] = animel.split(",");
String CELEB[] = UK_CELEB.split(",");
String Nature[] = vegtablesAndFruiets.split(",");
String V[][] = {COUNTRIES,CITIES,ANIMEL,Nature,occupations,CELEB};
String []TypeNames = {"Country","City","Animels","Nature","Occupation","Celeb"};
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:test1.db");
Statement stat = conn.createStatement();
//stat.executeUpdate("drop table if exists "+"android_metadata"+";");
stat.executeUpdate("create table android_metadata (\"locale\" TEXT DEFAULT 'en_US');");
//PreparedStatement prep1 = conn.prepareStatement(
// "insert into "+"android_metadata"+" values (?);");
//prep1.setString(1, "en_US") ;
//prep1.addBatch();
stat.executeUpdate("drop table if exists "+TABLE_NAME+";");
//stat.executeUpdate("create table "+TABLE_NAME+" (name, occupation);");
stat.executeUpdate("create table "+TABLE_NAME+" ("+VALUE+" TEXT NOT NULL,"+TYPE+" TEXT NOT NULL,"+LETTER+" TEXT NOT NULL,"+counter+" INTEGER);");
PreparedStatement prep = conn.prepareStatement(
"insert into "+TABLE_NAME+" values (?,?,?,?);");
//private void insertToTalble();
int j=0,i=0;
try{
for(j = 0 ;j < V.length; j++)
for (i = 0 ;i < V[j].length ; i++)
{
if (V[j][i] != null)
{
V[j][i] = asUpperCaseFirstChar(V[j][i]);
Character c = V[j][i].charAt(0);
prep.setString(3, c.toString());
}
prep.setString(1, V[j][i]);
prep.setString(2, TypeNames[j]);
prep.setInt(4,0);
prep.addBatch();
}
}catch(Exception e) {
System.out.println("***********"+i+"***************");
}
conn.setAutoCommit(false);
prep.executeBatch();
// prep1.executeBatch();
conn.setAutoCommit(true);
ResultSet rs = stat.executeQuery("select * from "+TABLE_NAME+";");
while (rs.next()) {
System.out.println("country name = " + rs.getString(VALUE));
System.out.println("type = " + rs.getString(TYPE));
System.out.println("letter = " + rs.getString(LETTER));
System.out.println("********************************");
}
rs.close();
conn.close();
}
and this is the code from where i first get the bug:
private static final String DB_PATH = "/data/data/com.countryCityGame/databases/test1.db";
private static final String DATABASE_NAME = "test1.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "GameTable";
private static final String VALUE = "value";
private static final String TYPE = "type";
private static final String LETTER = "letter";
public countryCityGameLogic(EditText[] myEditTextArr , Context context) {
points = 0;//init values
Cursor cursor = null ;
this.context = context;
openHelper = new OpenHelper(context);
gameList = new CharSequence [myEditTextArr.length];
for (int i = 0 ; i < myEditTextArr.length; i++){
gameList[i] = myEditTextArr[i].getText();
}
//this.db = openHelper.getWritableDatabase();
try{
db = SQLiteDatabase.openDatabase(DB_PATH , null, SQLiteDatabase.NO_LOCALIZED_COLLATORS/*SQLiteDatabase.CREATE_IF_NECESSARY*/);
//this question
cursor = db.query(TABLE_NAME, new String[] {LETTER}
,LETTER+ " like " + "'%" + "A" +"%'", null, null, null, null);
if ( !cursor.moveToFirst()){
//*****if data base doesnot exist HERE I GOT PROBLEMES****
this.db = openHelper.getWritableDatabase();//make new data base
}
}catch(SQLiteException e){
this.db = openHelper.getWritableDatabase();//make new data base
// for (int i = 0 ; i < ALLVALUES.length ; i++)
// insertValus(ALLVALUES[i],i);
}
NOTICE: In the device I am using /data/data/com.countryCityGame/databases/test1.db, it might not be the path where the appliction is located onto the device I am using.

Categories

Resources