0

I want to - just for "Proof of Concept's sake" - display an entire query result set as a string. And I want the table queried to be a variable.

How can it be done? I've got the following start:

public String[] getAllRecordsFrom(String tblName) {
    String query = "Select * FROM " + tblName;
    String[] results = null;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db != null ? db.rawQuery(query, null) : null;
    if (cursor == null) return results;
    while (cursor.moveToFirst()) {
        results. <== now what?
    }
    cursor.close();

    if (db != null) {
        db.close();
    }
    return results;
}

...but don't know how to proceed from the "<== now what?" part.

UPDATE

Based on Greg's ideas/code, I'm going to try this:

// Generic * query
public StringBuilder getAllRecordsFrom(String tblName) {
    String query = "Select * FROM " + tblName;
    StringBuilder results = new StringBuilder();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db != null ? db.rawQuery(query, null) : null;
    if (cursor == null) return results;
    int colCount = cursor.getColumnCount();
    cursor.moveToFirst();
    while (true) {
        for (int i = 0; i < colCount; i++) {
            results.append(cursor.getString(i).toString());
            // if the above (getting all data types as string) doesn't work, see if this (pseudocode) will: Type t = results.append(cursor.getType(i); if t == int then getint(i), else if t == string then getString(i), &c.
        }
        if (cursor.isLast()) break;
        cursor.moveToNext();
    }
    cursor.close();

    if (db != null) {
        db.close();
    }
    return results;
}

UPDATE 2

Okay, that worked, along with this:

private class ShowLocalDataTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... strings) {
        String tbl = strings[0];
        SQLiteOpenHelperHHS sqliteHHS = new SQLiteOpenHelperHHS(SQLiteActivity.this, null);
        StringBuilder sb = sqliteHHS.getAllRecordsFrom(tbl);
        return sb.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        EditText etmultiline = (EditText) findViewById(R.id.editTextMultiline);
        if (result == null) return;
        etmultiline.setText(result);
        Log.i("QueryResults", result);
    }
}

Note: If the ".toString() hadn't have worked, presumably I could have used "cursor.getType(i)" The return vals of getType are: 0 == null, 1 == int, 2 == float (REAL), 3 == String, 4 == BLOb

UPDATE 3

This is a little more "elegant," I think (getting the columns as their types):

public StringBuilder getAllRecordsFrom(String tblName) {
    final int NULLVAL = 0;
    final int INTVAL = 1;
    final int FLOATVAL = 2;
    final int STRINGVAL = 3;
    final int BLOBVAL = 4;

    String query = "Select * FROM " + tblName;
    StringBuilder results = new StringBuilder();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db != null ? db.rawQuery(query, null) : null;
    if (cursor == null) return results;
    int colCount = cursor.getColumnCount();
    cursor.moveToFirst();

    int typeVal;
    while (true) {
        for (int i = 0; i < colCount; i++) {
            typeVal = cursor.getType(i);
            switch (typeVal) {
                case NULLVAL:
                    // nuttin', honey
                    break;
                case INTVAL:
                    results.append(cursor.getInt(i)).toString();
                    break;
                case FLOATVAL:
                    results.append(cursor.getFloat(i)).toString();
                    break;
                case STRINGVAL:
                    results.append(cursor.getString(i));
                    break;
                case BLOBVAL:
                    //results.append(cursor.getBlob(i)).toString();
                    // Probably better off doing it this way:
                    results.append("BLOb" + String.valueOf(i));
                    break;
            }
        }
        if (cursor.isLast()) break;
        cursor.moveToNext();
    }
    cursor.close();

    if (db != null) {
        db.close();
    }
    return results;
}
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

1 Answers1

1

You might do better to use the StringBuilder class like this (note this gives you one huge string, not an array of strings; if you want an array where each row of the cursor is it's own element, then declare results as an ArrayList, replace results.append with results.add and return results.toArray().

public String getAllRecordsFrom(String tblName) {
    String query = "Select * FROM " + tblName;
    StringBuilder results = new StringBuilder();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db != null ? db.rawQuery(query, null) : null;
    if (cursor == null) { return null }

    cursor.moveToFirst();
    while (true) {
        results.append(cursor.getString(0));  // this assumes only one column in the results
        if (cursor.isLast()) break;
        cursor.moveToNext();
    }
    cursor.close();

    if (db != null) {
        db.close();
    }
    return results.toString();
}
Greg
  • 192
  • 7
  • This looks promising; however, is there a way to get all the columns (there is never just one). – B. Clay Shannon-B. Crow Raven Apr 22 '14 at 23:58
  • cursor.getColumnCount() will return the total number of columns. You could then interate over those as an inner loop right under while(true) (move results.append into that new inner loop) – Greg Apr 23 '14 at 00:03
  • That gets me a step closer, but is there a way to interrogate that so that I could know which data type to get (string, int, &c)? – B. Clay Shannon-B. Crow Raven Apr 23 '14 at 20:38
  • 1
    Normally one knows the structure/schema of the database which would of course tell you the types for each column. In theory, you could simply hard-code that knowledge into your program. If you are running this relatively blindly on databases you don't know about beforehand, you probably are stuck adding a method that first does a raw query to describe the table in question, then parse the result to get the data type for each column. It would be better to use the standard cursor.query() method where you explicitly define the columns you want. – Greg Apr 23 '14 at 22:28
  • It seems to work the way I have it above - simply getting all the vals as string and then appending a sometimes-superfluous ".toString()" to that. It seems to work, I say, as the "_id" (int) column worked fine. My comment in the update shows I'm thinking the same as you with the "getType" jazz - but that doesn't seem to be necessary. – B. Clay Shannon-B. Crow Raven Apr 23 '14 at 22:35
  • I did elegantize it, though (Update 3) – B. Clay Shannon-B. Crow Raven Apr 23 '14 at 23:15
  • 1
    agreed! Looks like you've got this one under control. Glad I could help! – Greg Apr 24 '14 at 02:40