Android Studio databaseHelper没有这样的专栏

时间:2018-04-23 22:18:19

标签: java android sqlite android-studio

public class Database extends SQLiteOpenHelper {

    //DATABASE NAME,TABLES' NAMES
    private static final String DATABASE_NAME = "book_db.db";
    private static final int DATABASE_VERSION = 2;
    private static final String BOOKS_TABLE = "books";//<--TABLE
    private static final String BOOK_CATEGORIES_TABLE = "categories";//<--TABLE
    private static final String AUTHORS_TABLE = "authorsTable";//<--TABLE

    //BOOK_TABLE ATTRIBUTES
    private static final String BOOK_KEY = "bookKey";
    private static final String BOOK_TITLE = "_bookTitle";
    private static final String PERSONAL_RATING = "_personalRating";
    private static final String AVERAGE_RATING = "_averageRating";
    private static final String IMAGE_DATA = "imageData";
    private static final String BOOK_ID = "bookId";
    private static final String GOOGLE_ID = "googleId";
    private static final String ISBN_10 = "isbn10";
    private static final String ISBN_13 = "isbn13";
    private static final String BOOK_COVER_URL = "bookCoverUrl";
    private static final String DESCRIPTION = "description";
    private static final String CALLBACK_URL = "callBackUrl";
    private static final String PREVIEW_URL = "previewUrl";
    private static final String BUY_URL = "buyUrl";
    private static final String PAGE_COUNT = "pageCount";
    private static final String PUBLISHED_DATE = "publishedDate";
    private static final String IS_BOOK_COLLECTION = "isBookCollection";
    private static final String IS_BOOK_READ = "isBookRead";
    private static final String IS_BOOK_IN_WHISHLIST = "isBookInWishList";



    //AUTHORS TABLE ATTRIBUTES
    //private static final String GOOGLE_ID = "googleId";     //Already declared above
    private static final String AUTHOR = "author";

    //CATEGORIES TABLE ATTRIBUTES
    //private static final String GOOGLE_ID = "googleId";     //Already declared above
    private static final String CATEGORY = "category";

    private static Database mInstance;

    public static synchronized Database getInstance(Context c) {
        if (mInstance == null ) {
            mInstance = new Database(c);
        }
        return mInstance;
    }


    private Database(Context context) {
        super(context, DATABASE_NAME, null, 1);
        //TODO Auto-generated constructor stub
    }


    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        //BOOKS TABLE CREATE
        sqLiteDatabase.execSQL(" CREATE TABLE " + BOOKS_TABLE + " ( " + BOOK_TITLE + " TEXT, " + BOOK_KEY + " TEXT," + PERSONAL_RATING + " REAL,"
            + AVERAGE_RATING + " REAL," +
            BOOK_ID + " TEXT," + GOOGLE_ID +" TEXT," + ISBN_13 + " TEXT," + ISBN_10 + " TEXT," + BOOK_COVER_URL + " TEXT," + DESCRIPTION + " TEXT," +
            CALLBACK_URL + " TEXT," + PREVIEW_URL + " TEXT," + BUY_URL + " TEXT," + PAGE_COUNT + " INT," + PUBLISHED_DATE + " TEXT,"
            + IS_BOOK_COLLECTION + " INT," + IS_BOOK_READ + " INT," + IS_BOOK_IN_WHISHLIST  + " INT," + IMAGE_DATA + " BLOB," + " PRIMARY KEY(" + BOOK_KEY +"));");
        //No boolean type in SQLite, INT used instead.

        //CATEGORIES TABLE CREATE
        sqLiteDatabase.execSQL(" CREATE TABLE " + AUTHORS_TABLE + " ( " + BOOK_KEY + " TEXT, "   + CATEGORY +
            " TEXT, PRIMARY KEY("+ BOOK_KEY +"," + CATEGORY +"));");

        //AUTHORS TABLE CREATE
        sqLiteDatabase.execSQL(" CREATE TABLE " + BOOK_CATEGORIES_TABLE + " ( " + BOOK_KEY + " TEXT, "   + AUTHOR +
            " TEXT, PRIMARY KEY("+ BOOK_KEY +"," + AUTHOR +"));");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + BOOKS_TABLE);
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + BOOK_CATEGORIES_TABLE);
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + AUTHORS_TABLE);
        onCreate(sqLiteDatabase);
    }

    /**
     *  This method adds a Book to the database
     * @param book
     * @return
     */
    public boolean addRecord(Book book){

        boolean resultBooksTable = false;
        boolean resultAuthorsTable = false;
        boolean resultCategoriesTable = false;

        SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
        ContentValues booksTableValues = new ContentValues();

        //BOOK TABLE VALUES   \\\\------///
        booksTableValues.put(BOOK_KEY,book.getKey());
        booksTableValues.put(BOOK_TITLE,book.getBookTitle());
        booksTableValues.put(AVERAGE_RATING,book.getAverageRating());
        booksTableValues.put(PERSONAL_RATING,book.getPersonalRating());
        booksTableValues.put(BOOK_ID,book.getId());
        booksTableValues.put(GOOGLE_ID,book.getGoogleID());
        booksTableValues.put(ISBN_13,book.getISBN13());
        booksTableValues.put(ISBN_10,book.getISBN10());
        booksTableValues.put(BOOK_COVER_URL,book.getBookCoverURL());
        booksTableValues.put(DESCRIPTION,book.getDescription());
        booksTableValues.put(CALLBACK_URL,book.getCallbackURL());
        booksTableValues.put(PREVIEW_URL,book.getPreviewURL());
        booksTableValues.put(BUY_URL,book.getBuyURL());
        booksTableValues.put(PAGE_COUNT,book.getPageCount());
        booksTableValues.put(PUBLISHED_DATE,book.getPublishedDate());
        booksTableValues.put(IS_BOOK_COLLECTION,book.isBookInCollection());
        booksTableValues.put(IS_BOOK_READ,book.isBookRead());
        booksTableValues.put(IS_BOOK_IN_WHISHLIST,book.isBookInWishlist());
        booksTableValues.put(IMAGE_DATA,book.getByteArray());

        //Inserting into BOOKS_TABLE

        try{//Try inserting into BOOKS_TABLE

            sqLiteDatabase.insertOrThrow(BOOKS_TABLE,null, booksTableValues);
            resultBooksTable = true;
        }catch (SQLiteConstraintException alreadyInserted){
            //Row is already inserted
        }

        //CATEGORY Table values
        ContentValues CategoriesTableValues = new ContentValues();
        CategoriesTableValues.put(BOOK_KEY,book.getKey());

        //AUTHORS_TABLE values
        ContentValues authorsTableValues = new ContentValues();
        authorsTableValues.put(BOOK_KEY,book.getKey());

        //Insert categories into BOOK_CATEGORIES_TABLE
        int i = 0;
        if (book.getCategories().length >= 0) try {//Try inserting into CATEGORIES_TABLE

            for (i = 0; i < book.getCategories().length; i++) {


                CategoriesTableValues.put(CATEGORY, book.getCategories()[i]);
                sqLiteDatabase.insertOrThrow(BOOK_CATEGORIES_TABLE, null, CategoriesTableValues);
            }

            resultCategoriesTable = true;

        } catch (SQLiteConstraintException alreadyInserted) {
            //Row is already inserted
        }

        //Insert authors into AUTHORS_TABLE
        i = 0;
        if (book.getAuthor().length >= 0) try {//Try inserting into CATEGORIES_TABLE

            for (i = 0; i < book.getAuthor().length; i++) {


                CategoriesTableValues.put(AUTHOR, book.getAuthor()[i]);
                sqLiteDatabase.insertOrThrow(AUTHORS_TABLE, null, authorsTableValues);
            }

            resultAuthorsTable = true;

        } catch (SQLiteConstraintException alreadyInserted) {
            //Row is already inserted
        }


        return resultBooksTable && resultAuthorsTable && resultCategoriesTable;

    }

    /**
     * Packs all books from database to a bookList and returns the list
     * @return
     */
    public ArrayList<Book> getSavedBooksList(){

        ArrayList<Book> savedBooksList = new ArrayList<Book>();

        Book book=new Book();//First declaration so it's not undeclared.



        SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
        //Query
        String q = "SELECT * FROM " + BOOKS_TABLE;//The entire table
        Cursor cursor = sqLiteDatabase.rawQuery(q,null);

        /////->One iteration for each book

        try{
            //Index of each column
            int bookKeyIndex = cursor.getColumnIndex(BOOK_KEY);
            int titleIndex = cursor.getColumnIndex(BOOK_TITLE);
            int averageRatingIndex = cursor.getColumnIndex(AVERAGE_RATING);
            int personalRatingIndex = cursor.getColumnIndex(PERSONAL_RATING);
            int IdIndex = cursor.getColumnIndex(BOOK_ID);
            int googleIdIndex = cursor.getColumnIndex(GOOGLE_ID);
            int isbn13Index = cursor.getColumnIndex(ISBN_13);
            int isbn10Index = cursor.getColumnIndex(ISBN_10);
            int urlIndex = cursor.getColumnIndex(BOOK_COVER_URL);
            int descriptionIndex = cursor.getColumnIndex(DESCRIPTION);
            int callbackUrlIndex = cursor.getColumnIndex(CALLBACK_URL);
            int previewUrlIndex = cursor.getColumnIndex(PREVIEW_URL);
            int buyUrlIndex = cursor.getColumnIndex(BUY_URL);
            int pageCountIndex = cursor.getColumnIndex(PAGE_COUNT);
            int dateIndex = cursor.getColumnIndex(PUBLISHED_DATE);
            int isBookCollectionIndex = cursor.getColumnIndex(IS_BOOK_COLLECTION);
            int isBookReadIndex = cursor.getColumnIndex(IS_BOOK_READ);
            int isBookInWishlistIndex = cursor.getColumnIndex(IS_BOOK_IN_WHISHLIST);
            int bookCoverIndex = cursor.getColumnIndex(IMAGE_DATA);



            cursor.moveToPosition(-1);

            while(cursor.moveToNext()){


                book = new Book();

                book.setId(cursor.getString(IdIndex));
                book.setAverageRating(averageRatingIndex);
                book.setPersonalRating(personalRatingIndex);
                book.setBookTitle(cursor.getString(titleIndex));
                book.setBookCoverURL(cursor.getString(urlIndex));
                book.setDescription(cursor.getString(descriptionIndex));
                book.setGoogleID(cursor.getString(googleIdIndex));
                book.setCallbackURL(cursor.getString(callbackUrlIndex));
                book.setPreviewURL(cursor.getString(previewUrlIndex));
                book.setBuyURL(cursor.getString(buyUrlIndex));
                book.setPageCount(cursor.getInt(pageCountIndex));
                book.setPublishedDate(cursor.getString(dateIndex));
                book.setISBN13(cursor.getString(isbn13Index));
                book.setISBN10(cursor.getString(isbn10Index));
                book.setBookInCollection(1 == cursor.getInt(isBookCollectionIndex));//1==int var (converts int to boolean)
                book.setBookRead(1 == cursor.getInt(isBookReadIndex));//SQLite doesn't support boolean.
                book.setBookInWishlist(1 == cursor.getInt(isBookInWishlistIndex));
                book.setBitmapFromByteArray(cursor.getBlob(bookCoverIndex));


                //Query of categories of the current book
                String q1 = null;

                q1 = "SELECT * FROM " + BOOK_CATEGORIES_TABLE
                    + " WHERE " + BOOK_CATEGORIES_TABLE + "." + BOOK_KEY + "='" + book.getKey() + "'";


                Cursor cursorCategories = sqLiteDatabase.rawQuery(q1,null);

                //Query of authors of the current book
                String q2 = null;
                q2 = "SELECT * FROM " + AUTHORS_TABLE
                    + " WHERE " + AUTHORS_TABLE + "." + BOOK_KEY + "='" + book.getKey() + "'";

                Cursor cursorAuthors = sqLiteDatabase.rawQuery(q2,null);

                int categoryIndex = cursorCategories.getColumnIndex(CATEGORY);

                int authorIndex = cursorAuthors.getColumnIndex(AUTHOR);

                String[] categories = new String[cursorCategories.getCount()];

                String[] authors = new String[cursorAuthors.getCount()];

                cursorCategories.moveToPosition(-1);
                cursorAuthors.moveToPosition(-1);

                //Create String[] of categories
                while(cursorCategories.moveToNext()) {
                    categories[cursorCategories.getPosition()] = cursorCategories.getString(categoryIndex);

                }
                book.setCategories(categories);

                //Create String[] of authors
                while(cursorAuthors.moveToNext()) {
                    authors[cursorAuthors.getPosition()] = cursorAuthors.getString(authorIndex);

                }
                book.setAuthor(authors);

                //Add book to list
                savedBooksList.add(book);
            }
        }catch (Exception outOfBounds){

        }
        finally {
            cursor.close();
        }




        return savedBooksList;
    }

    /**
     * This method deletes a row from the database
     * @param book
     * @return
     */
    public boolean deleteRecord(Book book){

        SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();

        int numOfRowsDeleted = 0;

        try{//Delete everything for this book from categories table
            numOfRowsDeleted += sqLiteDatabase.delete(BOOK_CATEGORIES_TABLE, BOOK_KEY + "='" + book.getKey() +"'", null);

        }catch (Exception noSuchColumn){
            //No such column
            //numOfRowsDeleted = 0;
        }

        try{
            numOfRowsDeleted += sqLiteDatabase.delete(BOOKS_TABLE, BOOK_KEY + "='" + book.getKey() +"'", null);

        }catch (Exception noSuchColumn){
            //No such column
            //numOfRowsDeleted = 0;
        }

        try{//Delete everything for this book from authors table
            numOfRowsDeleted += sqLiteDatabase.delete(AUTHORS_TABLE, BOOK_KEY + "='" + book.getKey() +"'", null);

        }catch (Exception noSuchColumn){
            //No such column
            //numOfRowsDeleted = 0;
        }

        if(numOfRowsDeleted > 0){//If 1 row at least deleted return true
            return true;
        }else{
            return false;
        }


    }

    /** Returns true if book exists in the database.
     *  Returns false if it doesn't.
     *
     * @param book
     * @return
     */
    public boolean isBookSaved(Book book){
        SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
        String q = "SELECT * FROM " + BOOKS_TABLE
            + " WHERE "
            + BOOK_KEY + "='" + book.getKey() + "'";



        Cursor cursor = sqLiteDatabase.rawQuery(q,null);

        return cursor.moveToFirst();

    }

    /**
     *   UPDATE PERSONAL RATING
     *   The only variable for update is PERSONAL_RATING
     *   The update takes place only on BOOKS_TABLE.
     *   Other tables don't have to be updated.
     * @param book
     * @return
     */
    public boolean updateRecord(Book book){
        SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
        boolean result = false;
        ContentValues booksTableValues = new ContentValues();
        //BOOK TABLE VALUES   \\\\------///
        booksTableValues.put(BOOK_TITLE,book.getBookTitle());
        booksTableValues.put(AVERAGE_RATING,book.getAverageRating());
        booksTableValues.put(PERSONAL_RATING,book.getPersonalRating());
        booksTableValues.put(BOOK_ID,book.getId());
        booksTableValues.put(GOOGLE_ID,book.getGoogleID());
        booksTableValues.put(ISBN_13,book.getISBN13());
        booksTableValues.put(ISBN_10,book.getISBN10());
        booksTableValues.put(BOOK_COVER_URL,book.getBookCoverURL());
        booksTableValues.put(DESCRIPTION,book.getDescription());
        booksTableValues.put(CALLBACK_URL,book.getCallbackURL());
        booksTableValues.put(PREVIEW_URL,book.getPreviewURL());
        booksTableValues.put(BUY_URL,book.getBuyURL());
        booksTableValues.put(PAGE_COUNT,book.getPageCount());
        booksTableValues.put(PUBLISHED_DATE,book.getPublishedDate());
        booksTableValues.put(IS_BOOK_COLLECTION,book.isBookInCollection());
        booksTableValues.put(IS_BOOK_READ,book.isBookRead());
        booksTableValues.put(IS_BOOK_IN_WHISHLIST,book.isBookInWishlist());
        booksTableValues.put(IMAGE_DATA,book.getByteArray());

        String q = null;

        q = "SELECT * FROM " + BOOKS_TABLE +" WHERE " + BOOK_KEY + " ='" + book.getKey() + "'";

        Cursor cursor = sqLiteDatabase.rawQuery(q,null);
        if(cursor.moveToFirst()){
            sqLiteDatabase.update(BOOKS_TABLE, booksTableValues, q, null);
            result = true;
        }
        cursor.close();
        //sqLiteDatabase.close();
        return result;
    }
}

弹出以下错误:

android.database.sqlite.SQLiteException: table books has no column named isbn10 (code 1): , while compiling: INSERT INTO books(isbn10,googleId,isBookRead,bookCoverUrl,_bookTitle,buyUrl,isBookCollection,publishedDate,previewUrl,pageCount,_personalRating,bookKey,isbn13,isBookInWishList,callBackUrl,description,bookId,imageData,_averageRating) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
android.database.sqlite.SQLiteException: no such column: bookKey (code 1): , while compiling: SELECT * FROM books WHERE bookKey='4593490'
at com.example.xrhstos.bookapp.Database.isBookSaved(Database.java:381)

1 个答案:

答案 0 :(得分:1)

找不到的可能原因是因为常见的误解是SQLiteOpenHelper的onCreate方法每次运行SQLiteOpenHelper的子类实例(也就是DatabaseHelper 数据库)已创建。

但是,onCreate方法仅在数据库的生命周期内调用一次。因此,除非删除数据库(或者以其他方式调用onCreate方法),否则将不会应用由onCreate方法调用的代码中对数据库结构所做的任何更改。 / p>

简单的解决方法是删除数据库,然后运行onCreate方法。通过删除应用程序的数据或卸载应用程序(都删除应用程序的数据,从而删除数据库),可以轻松删除数据库。

如果已将数据库助手的onUpgrade方法写入DROP所有表,然后再调用onCreate方法,则也可以使用此方法。当数据库版本(超级构造函数的第4个参数)增加时,数据库助手会调用onUpgrade方法。所以这种方法需要增加版本号。

在上述所有3个中,现有数据将丢失。如果需要保留数据,那么流程将更加复杂,并且还取决于正在进行的结构变更。

修复

要解决此问题,请执行以下操作之一: -

  • 删除应用程序的数据。
  • 卸载应用程序。
  • 更改
    • super(context, DATABASE_NAME, null, 1);
    • super(context, DATABASE_NAME, null, 2);

然后重新运行App。

注意

  • 这是最可能/最常见的原因。
  • 尚未对您的代码进行彻底的检查测试。
  • 如果问题仍然存在,则表明如此,可以对代码进行更彻底的检查。

其他

在实际测试代码之后,很可能原因如上所述。即没有对表进行任何修改创建SQL表创建,因此非常强烈地暗示原因如上所述。

使用您的代码,删除利用其他对象(如Books)的方法,并使用Are there any methods that assist with resolving common SQLite issues? - Addition 1 - logDatabaseInfo中的方法

然后报告的缺失列 isbn10 bookKey 按预期存在: -

        Table = books ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1

        Table = books ColumnName = isbn10 ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0


        Table = authorsTable ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1

        Table = categories ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1

以上提取的完整输出是: -

04-24 00:29:08.459 1263-1263/soanswers.soanswers D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/data/soanswers.soanswers/databases/book_db.db
    PRAGMA -  sqlite_version = 3.7.11
    PRAGMA -  user_version = 1
    PRAGMA -  encoding = UTF-8
    PRAGMA -  auto_vacuum = 1
    PRAGMA -  cache_size = 2000
    PRAGMA -  foreign_keys = 0
04-24 00:29:08.463 1263-1263/soanswers.soanswers D/SQLITE_CSU: PRAGMA -  freelist_count = 0
    PRAGMA -  ignore_check_constraints = 0
    PRAGMA -  journal_mode = persist
    PRAGMA -  journal_size_limit = 524288
    PRAGMA -  locking_mode = normal
    PRAGMA -  max_page_count = 1073741823
    PRAGMA -  page_count = 9
    PRAGMA -  page_size = 4096
    PRAGMA -  recursive_triggers = 0
    PRAGMA -  reverse_unordered_selects = 0
04-24 00:29:08.467 1263-1263/soanswers.soanswers D/SQLITE_CSU: PRAGMA -  secure_delete = 0
    PRAGMA -  synchronous = 2
    PRAGMA -  temp_store = 0
    PRAGMA -  wal_autocheckpoint = 100
    Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
    Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Number of Indexes = 0
    Number of Foreign Keys = 0
    Number of Triggers = 0
    Table Name = books Created Using = CREATE TABLE books ( _bookTitle TEXT, bookKey TEXT,_personalRating REAL,_averageRating REAL,bookId TEXT,googleId TEXT,isbn13 TEXT,isbn10 TEXT,bookCoverUrl TEXT,description TEXT,callBackUrl TEXT,previewUrl TEXT,buyUrl TEXT,pageCount INT,publishedDate TEXT,isBookCollection INT,isBookRead INT,isBookInWishList INT,imageData BLOB, PRIMARY KEY(bookKey))
    Table = books ColumnName = _bookTitle ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1
04-24 00:29:08.471 1263-1263/soanswers.soanswers D/SQLITE_CSU: Table = books ColumnName = _personalRating ColumnType = REAL Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = _averageRating ColumnType = REAL Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = bookId ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = googleId ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = isbn13 ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = isbn10 ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = bookCoverUrl ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = description ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = callBackUrl ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = previewUrl ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = buyUrl ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = pageCount ColumnType = INT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = publishedDate ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = isBookCollection ColumnType = INT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = isBookRead ColumnType = INT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = isBookInWishList ColumnType = INT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = books ColumnName = imageData ColumnType = BLOB Default Value = null PRIMARY KEY SEQUENCE = 0
    Number of Indexes = 1
    INDEX NAME = sqlite_autoindex_books_1
        Sequence = 0
        Unique   = true
        Index Origin indicator unsupported
        Index Partial indicator unsupported
        INDEX COLUMN = bookKey COLUMN ID = 1 SEQUENCE = 0
    Number of Foreign Keys = 0
    Number of Triggers = 0
    Table Name = authorsTable Created Using = CREATE TABLE authorsTable ( bookKey TEXT, category TEXT, PRIMARY KEY(bookKey,category))
    Table = authorsTable ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1
    Table = authorsTable ColumnName = category ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1
    Number of Indexes = 1
    INDEX NAME = sqlite_autoindex_authorsTable_1
        Sequence = 0
        Unique   = true
        Index Origin indicator unsupported
        Index Partial indicator unsupported
        INDEX COLUMN = bookKey COLUMN ID = 0 SEQUENCE = 0
        INDEX COLUMN = category COLUMN ID = 1 SEQUENCE = 1
04-24 00:29:08.475 1263-1263/soanswers.soanswers D/SQLITE_CSU: Number of Foreign Keys = 0
    Number of Triggers = 0
    Table Name = categories Created Using = CREATE TABLE categories ( bookKey TEXT, author TEXT, PRIMARY KEY(bookKey,author))
    Table = categories ColumnName = bookKey ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1
    Table = categories ColumnName = author ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 1
    Number of Indexes = 1
    INDEX NAME = sqlite_autoindex_categories_1
        Sequence = 0
        Unique   = true
        Index Origin indicator unsupported
        Index Partial indicator unsupported
        INDEX COLUMN = bookKey COLUMN ID = 0 SEQUENCE = 0
        INDEX COLUMN = author COLUMN ID = 1 SEQUENCE = 1
    Number of Foreign Keys = 0
    Number of Triggers = 0
    logCursorColumns invoked. Cursor has the following 19 columns.
    Column Name 1 is _bookTitle
    Column Name 2 is bookKey
    Column Name 3 is _personalRating
    Column Name 4 is _averageRating
    Column Name 5 is bookId
    Column Name 6 is googleId
    Column Name 7 is isbn13
    Column Name 8 is isbn10
    Column Name 9 is bookCoverUrl
    Column Name 10 is description
    Column Name 11 is callBackUrl
    Column Name 12 is previewUrl
    Column Name 13 is buyUrl
    Column Name 14 is pageCount
    Column Name 15 is publishedDate
04-24 00:29:08.479 1263-1263/soanswers.soanswers D/SQLITE_CSU: Column Name 16 is isBookCollection
    Column Name 17 is isBookRead
    Column Name 18 is isBookInWishList
    Column Name 19 is imageData
    logCursorColumns invoked. Cursor has the following 2 columns.
    Column Name 1 is bookKey
    Column Name 2 is author
    logCursorColumns invoked. Cursor has the following 2 columns.
    Column Name 1 is bookKey
    Column Name 2 is category