Search code examples
androidsqlitesqliteopenhelper

It seems that the SQLite table had stopped being populated for unknown reason


The application worked fine, but then the method Cursor.moveToFirst() started returning false, and the Application's list has stopped appearing in a Fragment.

I think it all started after I changed a constat's name: IMAGE_URI to IMAGE_URL, and imageUri to imageUrl. Not sure though.

I tried debugging and searching for similar cases but there are many varied causes. When debugging, I couldn't get to the onCreate of the SQLiteHelper class in order to find out what happens during the population of the table (It seems that the table exists since an empty db of the table is being created), So I can't debug nor search for similar issues since no relevant output is found in the Logcat.

GetDatabase

This class is used for some of the communication with the SQLiteOpenHelper class.

public class GetDatabase {

    private static final int DB_VERSION = 1; //required for the constructor
    public static final String dbName = "moviesList";

    private SQLiteOpenHelper sqLiteOpenHelper;
    private SQLiteDatabase db ;

    public GetDatabase(Context context) {
        Log.d("GetDatabase", "Cont.");

        this.sqLiteOpenHelper = new SQLiteHelper(context, dbName, null, DB_VERSION);
    }

    public void open() {
       db = sqLiteOpenHelper.getWritableDatabase();
    }

    public void close() {
        if (sqLiteOpenHelper != null) {
            sqLiteOpenHelper.close();
        }
    }

    public ArrayList<Movie> getMovies() {
        String[] columns = {
                Movie.ID,
                Movie.TITLE,
                Movie.IMAGE_URL,
                Movie.RATING,
                Movie.RELEASE_YEAR,
                Movie.GENRE
        };

        // sorting orders
        String sortOrder =
                Movie.RELEASE_YEAR + " ASC";
        ArrayList<Movie> moviesList = new ArrayList<>();

        Cursor cursor = db.query(TABLE_NAME, //Table to query
                columns,
                null,
                null,
                null,
                null,
                sortOrder);

        if (cursor.moveToFirst()) {
            do {
                Movie movie = new Movie();
                movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
                movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
                movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
                movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
                movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
                movie.setGenre(cursor.getString(cursor.getColumnIndex(Movie.GENRE)));
                // Adding a movie to the list
                moviesList.add(movie);
            } while (cursor.moveToNext());
        }
        Log.d(TAG, "The movies list from sqlite: " + moviesList);
        cursor.close();
        db.close();

        return moviesList;
    }

    private Cursor getData(int id) {
        return db.rawQuery( "select * from " + TABLE_NAME + " where id="+id+"", null );
    }

    public Cursor getMovieDetails(int movieId) {// For viewing details of a specific item

        Cursor cursor = getData(movieId);
        cursor.moveToFirst();

        return cursor;
    }
}

SQliteHelper

The SQLiteOpenHelper class

public class SQLiteHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "movies.db";
    private static final int DB_VERSION = 1; //required for the constructor
    private static final String TABLE_NAME = "movies";

    private String fileName = "movies.json";
    private String appName = "MoviesList";
    private String path = getExternalStorageDirectory() + "/" + appName + "/" + fileName;

    private String jsonString = null;

    private SQLiteDatabase db;

    // The cont. for saving to SQLite .Called from SplashActivity after downloading the JSON
    public SQLiteHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        Log.d(TAG, "At SQLiteHelper");

        createSQLIteTable(db);
        if(tableIsEmpty(db)) {
            try {
                parseJsonAndInsertToSQLIte(db);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

    private void createSQLIteTable(SQLiteDatabase db) {

        //creating a table for SQLite
        String CREATE_SQL_TABLE_STRING = "CREATE TABLE IF NOT EXISTS "+TABLE_NAME
                + " ("
                + Movie.ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,"
                + Movie.TITLE + " TEXT,"
                + Movie.IMAGE_URL + " TEXT,"
                + Movie.RATING + " TEXT,"
                + Movie.RELEASE_YEAR + " TEXT,"
                + Movie.GENRE + " TEXT "
                + ")";

        Log.i(TAG,"created sql table: "+CREATE_SQL_TABLE_STRING);

        db.execSQL(CREATE_SQL_TABLE_STRING);
    }

    private void parseJsonAndInsertToSQLIte(SQLiteDatabase db) throws JSONException {
        // parsing the json
        String jsonString = getJsonFileData();
        JSONArray moviesArray = new JSONArray(jsonString);
        ContentValues insertValues;

        for (int i = 0; i < moviesArray.length(); i++) {

            JSONObject jsonObject = moviesArray.getJSONObject(i);

            String title = jsonObject.getString("title");
            String imageUrl = jsonObject.getString("imageUrl");
            String rating = jsonObject.getString("rating");
            String releaseYear = jsonObject.getString("releaseYear");
            String genre = jsonObject.getString("genre");

            insertValues = new ContentValues();

            insertValues.put(Movie.TITLE, title);
            insertValues.put(Movie.IMAGE_URL, imageUrl);
            insertValues.put(Movie.RATING, rating);
            insertValues.put(Movie.RELEASE_YEAR, releaseYear);
            insertValues.put(Movie.GENRE, genre);
            long res = db.insert(TABLE_NAME, null, insertValues);

            Log.i(TAG, "parsed and inserted to sql - row: " + res);
        }
    }

    private String getJsonFileData() {
        //loading the jsonString
        try {
            InputStream in = new FileInputStream(new File(path));
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder output = new StringBuilder();
            while ((jsonString = reader.readLine()) != null) {
                output.append(jsonString);
            }
            System.out.println(output.toString());   //Prints the string content read from input stream

            jsonString = output.toString();
            Log.d(TAG, "the jsonString was loaded");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return jsonString;
    }
}

If I don't solve this, I think the entire application is worthless, since I don't know what mistake needs to be corrected.

Thanks!


Solution

  • Clear your application data from setting and run your application again. Since you have made changes in database column, it will not reflect unless you clear data.

    Or

    Do proper handling with DB version. Drop all tables in onUpgrade method and increase DB version every time you made changes in DB structure.

    EDIT: Clear Data window

    App Info Window