diff --git a/src/org/geometerplus/android/fbreader/SQLiteBooksDatabase.java b/src/org/geometerplus/android/fbreader/SQLiteBooksDatabase.java index 430baab1f..f97f1a82a 100644 --- a/src/org/geometerplus/android/fbreader/SQLiteBooksDatabase.java +++ b/src/org/geometerplus/android/fbreader/SQLiteBooksDatabase.java @@ -60,7 +60,7 @@ public final class SQLiteBooksDatabase extends BooksDatabase { private void migrate(Context context) { final int version = myDatabase.getVersion(); - final int currentVersion = 10; + final int currentVersion = 11; if (version >= currentVersion) { return; } @@ -89,6 +89,8 @@ public final class SQLiteBooksDatabase extends BooksDatabase { updateTables8(); case 9: updateTables9(); + case 10: + updateTables10(); } myDatabase.setTransactionSuccessful(); myDatabase.endTransaction(); @@ -646,6 +648,36 @@ public final class SQLiteBooksDatabase extends BooksDatabase { return ids; } + private SQLiteStatement mySaveFavoritesStatement; + protected void saveFavoritesIds(final List ids) { + if (mySaveFavoritesStatement == null) { + mySaveFavoritesStatement = myDatabase.compileStatement( + "INSERT INTO Favorites (book_id) VALUES (?)" + ); + } + executeAsATransaction(new Runnable() { + public void run() { + myDatabase.delete("Favorites", null, null); + for (long id : ids) { + mySaveFavoritesStatement.bindLong(1, id); + mySaveFavoritesStatement.execute(); + } + } + }); + } + + protected List loadFavoritesIds() { + final Cursor cursor = myDatabase.rawQuery( + "SELECT book_id FROM Favorites", null + ); + final LinkedList ids = new LinkedList(); + while (cursor.moveToNext()) { + ids.add(cursor.getLong(0)); + } + cursor.close(); + return ids; + } + protected List loadBookmarks(long bookId) { LinkedList list = new LinkedList(); Cursor cursor = myDatabase.rawQuery( @@ -1071,4 +1103,10 @@ public final class SQLiteBooksDatabase extends BooksDatabase { private void updateTables9() { myDatabase.execSQL("CREATE INDEX BookList_BookIndex ON BookList (book_id)"); } + + private void updateTables10() { + myDatabase.execSQL( + "CREATE TABLE IF NOT EXISTS Favorites(" + + "book_id INTEGER UNIQUE NOT NULL REFERENCES Books(book_id))"); + } } diff --git a/src/org/geometerplus/android/fbreader/library/LibraryTreeActivity.java b/src/org/geometerplus/android/fbreader/library/LibraryTreeActivity.java index cd3465642..91bc5b6cc 100644 --- a/src/org/geometerplus/android/fbreader/library/LibraryTreeActivity.java +++ b/src/org/geometerplus/android/fbreader/library/LibraryTreeActivity.java @@ -78,6 +78,7 @@ public class LibraryTreeActivity extends LibraryBaseActivity { } else if (PATH_BY_TAG.equals(path[0])) { tree = Library.byTag(); } else if (PATH_FAVORITES.equals(path[0])) { + tree = Library.favorites(); } for (int i = 1; i < path.length; ++i) { diff --git a/src/org/geometerplus/fbreader/library/BooksDatabase.java b/src/org/geometerplus/fbreader/library/BooksDatabase.java index e4259a9ba..07a04eb78 100644 --- a/src/org/geometerplus/fbreader/library/BooksDatabase.java +++ b/src/org/geometerplus/fbreader/library/BooksDatabase.java @@ -84,6 +84,9 @@ public abstract class BooksDatabase { protected abstract List loadRecentBookIds(); protected abstract void saveRecentBookIds(final List ids); + protected abstract List loadFavoritesIds(); + protected abstract void saveFavoritesIds(final List ids); + protected Bookmark createBookmark(long id, long bookId, String bookTitle, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCounter, String modelId, int paragraphIndex, int wordIndex, int charIndex) { return new Bookmark(id, bookId, bookTitle, text, creationDate, modificationDate, accessDate, accessCounter, modelId, paragraphIndex, wordIndex, charIndex); } diff --git a/src/org/geometerplus/fbreader/library/Library.java b/src/org/geometerplus/fbreader/library/Library.java index d179f8487..05375056b 100644 --- a/src/org/geometerplus/fbreader/library/Library.java +++ b/src/org/geometerplus/fbreader/library/Library.java @@ -36,6 +36,7 @@ public final class Library { private final LibraryTree myLibraryByAuthor = new RootTree(); private final LibraryTree myLibraryByTag = new RootTree(); private final LibraryTree myRecentBooks = new RootTree(); + private final LibraryTree myFavorites = new RootTree(); private final LibraryTree mySearchResult = new RootTree(); private volatile int myState = STATE_NOT_INITIALIZED; @@ -268,6 +269,14 @@ public final class Library { } } + for (long id : db.loadFavoritesIds()) { + Book book = bookById.get(id); + if (book != null) { + myFavorites.createBookSubTree(book, true); + } + } + myFavorites.sortAllChildren(); + db.executeAsATransaction(new Runnable() { public void run() { for (Book book : myBooks) { @@ -309,6 +318,11 @@ public final class Library { return (recentIds.size() > 0) ? Book.getById(recentIds.get(0)) : null; } + public LibraryTree favorites() { + waitForState(STATE_FULLY_INITIALIZED); + return myFavorites; + } + public LibraryTree searchResults() { return mySearchResult; } @@ -340,6 +354,16 @@ public final class Library { db.saveRecentBookIds(ids); } + public static void addBookToFavorites(Book book) { + final BooksDatabase db = BooksDatabase.Instance(); + final List ids = db.loadFavoritesIds(); + final Long bookId = book.getId(); + if (!ids.contains(bookId)) { + ids.add(bookId); + db.saveFavoritesIds(ids); + } + } + public static final int REMOVE_DONT_REMOVE = 0x00; public static final int REMOVE_FROM_LIBRARY = 0x01; public static final int REMOVE_FROM_DISK = 0x02;