简体   繁体   中英

Why is my query of my SQLite database returning null?

I don't know why my method to search my SQLite database and return a cursor is returning null. I have loaded the database from a txt file, and while trying to implement a search feature in the app, I am trying to query the same database to return a list of possible matches. However, as I traced back errors, I realized that this method keeps returning null instead of the cursor that I want. Can anyone help me with this? I'll gladly admit I'm very new to this, and would appreciate any help.

Here is my database table, with method getWordMatches() that is returning null:

public class DatabaseTable {

    public static final String TAG = "ConstantDatabase";

    //the columns included in the table
    public static final String COL_QUANTITY = "QUANTIY";
    public static final String COL_VALUE = "VALUE";
    public static final String COL_UNCERTAINTY = "UNCERTAINTY";
    public static final String COL_UNIT = "UNIT";
    public static final String _id = "_id";

    private static final String DATABASE_NAME = "CONSTANTS";
    private static final String FTS_VIRTUAL_TABLE = "FTS";
    private static final int DATABASE_VERSION = 1;

    private final DatabaseOpenHelper mDatabaseOpenHelper;

    public DatabaseTable(Context context){
        mDatabaseOpenHelper = new DatabaseOpenHelper(context);
    }

    private static class DatabaseOpenHelper extends SQLiteOpenHelper {

        private final Context mHelperContext;
        private SQLiteDatabase mDatabase;

        private static final String FTS_TABLE_CREATE =
                "CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
                        " USING fts3 (" +_id+ ", "+
                        COL_QUANTITY + ", " +
                        COL_VALUE + "," +
                        COL_UNCERTAINTY + "," +
                        COL_UNIT + ")";

        public DatabaseOpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            Log.e("Database Operation", "DatabaseOpenHelper constructor called");
            mHelperContext = context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            mDatabase = db;
            mDatabase.execSQL(FTS_TABLE_CREATE);
            Log.e("Database Operation", "Constants Table Created ...");
            loadConstants();
        }

        @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");
            db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
            onCreate(db);
        }

        public SQLiteDatabase getmDatabase(){
            return mDatabase;
        }


//        populating the virtual table with a string reading code

        private void loadConstants() {
            new Thread(new Runnable() {
                public void run() {
                    try {
                        loadConstantss();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();

            Log.e("Loading", "Constants Table Populated ...");
        }

        private void loadConstantss() throws IOException {
            final Resources resources = mHelperContext.getResources();
            InputStream inputStream = resources.openRawResource(R.raw.txt);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            try {
                String line;
                while ((line = reader.readLine()) != null) {
                    String[] strings = TextUtils.split(line, ",");
                    if (strings.length < 4) continue;
                    long id = addConstant(strings[0].trim(), strings[1].trim(), strings[2].trim(), strings[3].trim());
                    if (id < 0) {
                        Log.e(TAG, "unable to add word: " + strings[0].trim());
                    }
                }
            } finally {
                reader.close();
            }
        }

        public long addConstant(String quantity, String value, String uncertainty, String unit) {
            ContentValues initialValues = new ContentValues();
            initialValues.put(COL_QUANTITY, quantity);
            initialValues.put(COL_VALUE, value);
            initialValues.put(COL_UNCERTAINTY, uncertainty);
            initialValues.put(COL_UNIT, unit);

            return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
        }

        //database openhelper ends
    }

    public Cursor getWordMatches(String query, String[] columns) {
        String selection = COL_QUANTITY + " MATCH ?";
        String[] selectionArgs = new String[] {query+"*"};

        return query(selection, selectionArgs, columns);
    }

    public Cursor query(String selection, String[] selectionArgs, String[] columns) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(FTS_VIRTUAL_TABLE);

        Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
                columns, selection, selectionArgs, null, null, null);

        if (cursor == null) {
            return null;
        } else if (!cursor.moveToFirst()) {
            cursor.close();
            return null;
        }
        return cursor;
    }

    public Cursor getAllTitles()
    {
        return mDatabaseOpenHelper.getmDatabase().query(FTS_VIRTUAL_TABLE, new String[] {
                        COL_QUANTITY,
                        COL_UNCERTAINTY,
                        COL_UNIT,
                        COL_VALUE},
                null,
                null,
                null,
                null,
                null);
    }
}

Again, thank you so much.

EDIT:

the original error that led me to this was that when this was called in another activity:

Cursor c=db.getWordMatches(query,colums);
Log.e("cursor returned",c.toString());

the log cat returned

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

Your code closes the cursor if there's no data in it

if (cursor == null) {
    return null;
} else if (!cursor.moveToFirst()) {
    cursor.close();
    return null;
}

Doing so gives you a null value in a common use-case. Afterwards you use the cursor without checking

Log.e("cursor returned", c.toString());

If this is the only place where you use the cursor unchecked you could just replace it with

Log.e("cursor returned", String.valueOf(c));

Otherwise you might need to improve your implementation. Anyway it might be a good idea for you to have a look into DatabaseUtils .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM