package net.bible.service.db.bookmark; import android.content.ContentValues; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import net.bible.service.db.CommonDatabaseHelper; import net.bible.service.db.SQLHelper; import net.bible.service.db.bookmark.BookmarkDatabaseDefinition.BookmarkColumn; import net.bible.service.db.bookmark.BookmarkDatabaseDefinition.BookmarkLabelColumn; import net.bible.service.db.bookmark.BookmarkDatabaseDefinition.LabelColumn; import net.bible.service.db.bookmark.BookmarkDatabaseDefinition.Table; import org.apache.commons.lang3.StringUtils; import org.crosswire.jsword.passage.NoSuchKeyException; import org.crosswire.jsword.passage.VerseRange; import org.crosswire.jsword.passage.VerseRangeFactory; import org.crosswire.jsword.versification.BibleBook; import org.crosswire.jsword.versification.Versification; import org.crosswire.jsword.versification.system.Versifications; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * DAO for bookmark, bookmark_label and label tables * * @author Martin Denham [mjdenham at gmail dot com] * @see gnu.lgpl.License for license details.<br> * The copyright to this program is held by it's author. */ public class BookmarkDBAdapter { // Variable to hold the database instance private SQLiteDatabase db; // Database open/upgrade helper private final SQLiteOpenHelper dbHelper; private static final String TAG = "BookmarkDBAdapter"; public BookmarkDBAdapter() { dbHelper = CommonDatabaseHelper.getInstance(); } public BookmarkDBAdapter open() throws SQLException { try { db = dbHelper.getWritableDatabase(); } catch (SQLiteException ex) { db = dbHelper.getReadableDatabase(); } return this; } public void close() { db.close(); } public BookmarkDto insertBookmark(BookmarkDto bookmark) { // Create a new row of values to insert. ContentValues newValues = new ContentValues(); VerseRange key = bookmark.getVerseRange(); // must save a Key's versification along with the key! String v11nName = key.getVersification().getName(); // Gets the current system time in milliseconds Long now = System.currentTimeMillis(); newValues.put(BookmarkColumn.KEY, key.getOsisRef()); newValues.put(BookmarkColumn.VERSIFICATION, v11nName); newValues.put(BookmarkColumn.CREATED_ON, now); long newId = db.insert(Table.BOOKMARK, null, newValues); return getBookmarkDto(newId); } public boolean removeBookmark(BookmarkDto bookmark) { Log.d(TAG, "Removing bookmark:"+bookmark.getVerseRange()); return db.delete(Table.BOOKMARK, BookmarkColumn._ID + "=" + bookmark.getId(), null) > 0; } public boolean removeLabel(LabelDto label) { Log.d(TAG, "Removing label:"+label.getName()); return db.delete(Table.LABEL, LabelColumn._ID + "=" + label.getId(), null) > 0; } public LabelDto insertLabel(LabelDto label) { // Create a new row of values to insert. ContentValues newValues = new ContentValues(); newValues.put(LabelColumn.NAME, label.getName()); newValues.put(LabelColumn.BOOKMARK_STYLE, label.getBookmarkStyleAsString()); long newId = db.insert(Table.LABEL, null, newValues); return getLabelDto(newId); } public LabelDto updateLabel(LabelDto label) { // Create a new row of values to insert. ContentValues newValues = new ContentValues(); newValues.put(LabelColumn.NAME, label.getName()); newValues.put(LabelColumn.BOOKMARK_STYLE, label.getBookmarkStyleAsString()); long newId = db.update(Table.LABEL, newValues, "_id=?", new String []{String.valueOf(label.getId())}); return getLabelDto(newId); } public boolean removeBookmarkLabelJoin(BookmarkDto bookmark, LabelDto label) { return db.delete(Table.BOOKMARK_LABEL, BookmarkLabelColumn.BOOKMARK_ID + "=" + bookmark.getId()+" AND "+BookmarkLabelColumn.LABEL_ID + "=" + label.getId(), null) > 0; } public List<BookmarkDto> getAllBookmarks() { List<BookmarkDto> allBookmarks = new ArrayList<>(); Cursor c = db.query(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS, null, null, null, null, null); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { BookmarkDto bookmark = getBookmarkDto(c); allBookmarks.add(bookmark); c.moveToNext(); } } } finally { c.close(); } return allBookmarks; } public List<BookmarkDto> getBookmarksInBook(BibleBook book) { Log.d(TAG, "about to getBookmarksInPassage:"+book.getOSIS()); List<BookmarkDto> bookmarkList = new ArrayList<>(); Cursor c = db.query(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS, BookmarkColumn.KEY+" LIKE ?", new String []{String.valueOf(book.getOSIS()+".%")}, null, null, null); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { BookmarkDto bookmark = getBookmarkDto(c); bookmarkList.add(bookmark); c.moveToNext(); } } } finally { c.close(); } Log.d(TAG, "bookmarksInPassage set to " + bookmarkList.size() + " item long list"); return bookmarkList; } public List<BookmarkDto> getBookmarksWithLabel(LabelDto label) { String sql = "SELECT "+SQLHelper.getColumnsForQuery(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS)+ " FROM bookmark "+ "JOIN bookmark_label ON (bookmark._id = bookmark_label.bookmark_id) "+ "JOIN label ON (bookmark_label.label_id = label._id) "+ "WHERE label._id = ? "; List<BookmarkDto> allBookmarks = new ArrayList<>(); String[] args = new String[] {label.getId().toString()}; Cursor c = db.rawQuery(sql, args); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { BookmarkDto bookmark = getBookmarkDto(c); allBookmarks.add(bookmark); c.moveToNext(); } } } finally { c.close(); } return allBookmarks; } public List<BookmarkDto> getUnlabelledBookmarks() { String sql = "SELECT "+SQLHelper.getColumnsForQuery(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS)+ " FROM bookmark "+ " WHERE NOT EXISTS (SELECT * FROM bookmark_label WHERE bookmark._id = bookmark_label.bookmark_id)"; List<BookmarkDto> bookmarks = new ArrayList<>(); Cursor c = db.rawQuery(sql, null); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { BookmarkDto bookmark = getBookmarkDto(c); bookmarks.add(bookmark); c.moveToNext(); } } } finally { c.close(); } return bookmarks; } public List<LabelDto> getAllLabels() { List<LabelDto> allLabels = new ArrayList<>(); Cursor c = db.query(LabelQuery.TABLE, LabelQuery.COLUMNS, null, null, null, null, LabelColumn.NAME); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { LabelDto bookmark = getLabelDto(c); allLabels.add(bookmark); c.moveToNext(); } } } finally { c.close(); } return allLabels; } public List<LabelDto> getBookmarkLabels(BookmarkDto bookmark) { String sql = "SELECT label._id, label.name, label.bookmark_style "+ "FROM label "+ "JOIN bookmark_label ON (label._id = bookmark_label.label_id) "+ "JOIN bookmark ON (bookmark_label.bookmark_id = bookmark._id) "+ "WHERE bookmark._id = ?"; List<LabelDto> labels = new ArrayList<>(); String[] args = new String[] {bookmark.getId().toString()}; Cursor c = db.rawQuery(sql, args); try { if (c.moveToFirst()) { while (!c.isAfterLast()) { LabelDto label = getLabelDto(c); labels.add(label); c.moveToNext(); } } } finally { c.close(); } return labels; } public void insertBookmarkLabelJoin(BookmarkDto bookmark, LabelDto label) { // Create a new row of values to insert. ContentValues newValues = new ContentValues(); newValues.put(BookmarkLabelColumn.BOOKMARK_ID, bookmark.getId()); newValues.put(BookmarkLabelColumn.LABEL_ID, label.getId()); //long newId = db.insert(Table.BOOKMARK_LABEL, null, newValues); } public BookmarkDto getBookmarkDto(long id) { BookmarkDto bookmark = null; Cursor c = db.query(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS, BookmarkColumn._ID+"=?", new String[] {String.valueOf(id)}, null, null, null); try { if (c.moveToFirst()) { bookmark = getBookmarkDto(c); } } finally { c.close(); } return bookmark; } /** * Find bookmark starting at the location specified by key. * If it starts there then the initial part of the key should match. */ public BookmarkDto getBookmarkByStartKey(String key) { BookmarkDto bookmark = null; Cursor c=null; try { // exact match c = db.query(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS, BookmarkColumn.KEY+"=?", new String[] {key}, null, null, null); if (!c.moveToFirst()) { // start of verse range c = db.query(BookmarkQuery.TABLE, BookmarkQuery.COLUMNS, BookmarkColumn.KEY + " LIKE ?", new String[]{key + "-%"}, null, null, null); if (!c.moveToFirst()) { return null; } } bookmark = getBookmarkDto(c); } finally { c.close(); } return bookmark; } /** return Dto from current cursor position or null */ private BookmarkDto getBookmarkDto(Cursor c) { BookmarkDto dto = new BookmarkDto(); try { //Id Long id = c.getLong(BookmarkQuery.ID); dto.setId(id); //Verse String key = c.getString(BookmarkQuery.KEY); Versification v11n=null; if (!c.isNull(BookmarkQuery.VERSIFICATION)) { String v11nString = c.getString(BookmarkQuery.VERSIFICATION); if (!StringUtils.isEmpty(v11nString)) { v11n = Versifications.instance().getVersification(v11nString); } } if (v11n==null) { // use default v11n v11n = Versifications.instance().getVersification(Versifications.DEFAULT_V11N); } dto.setVerseRange(VerseRangeFactory.fromString(v11n, key)); //Created date long created = c.getLong(BookmarkQuery.CREATED_ON); dto.setCreatedOn(new Date(created)); } catch (NoSuchKeyException nke) { Log.e(TAG, "Key error", nke); } return dto; } private LabelDto getLabelDto(long id) { LabelDto label = null; Cursor c = db.query(LabelQuery.TABLE, LabelQuery.COLUMNS, LabelColumn._ID+"=?", new String[] {String.valueOf(id)}, null, null, null); try { if (c.moveToFirst()) { label = getLabelDto(c); } } finally { c.close(); } return label; } /** return Dto from current cursor position or null */ private LabelDto getLabelDto(Cursor c) { LabelDto dto = new LabelDto(); Long id = c.getLong(LabelQuery.ID); dto.setId(id); String name = c.getString(LabelQuery.NAME); dto.setName(name); String style = c.getString(LabelQuery.BOOKMARK_STYLE); dto.setBookmarkStyleFromString(style); return dto; } private interface BookmarkQuery { String TABLE = Table.BOOKMARK; String[] COLUMNS = new String[] {BookmarkColumn._ID, BookmarkColumn.KEY, BookmarkColumn.VERSIFICATION, BookmarkColumn.CREATED_ON}; int ID = 0; int KEY = 1; int VERSIFICATION = 2; int CREATED_ON = 3; } private interface LabelQuery { String TABLE = Table.LABEL; String[] COLUMNS = new String[] {LabelColumn._ID, LabelColumn.NAME, LabelColumn.BOOKMARK_STYLE}; int ID = 0; int NAME = 1; int BOOKMARK_STYLE = 2; } }