Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02e4976a authored by stefan-niedermann's avatar stefan-niedermann Committed by Niedermann IT-Dienstleistungen
Browse files

#528 Save the excerpt in a separate column

parent 3bce16ec
Loading
Loading
Loading
Loading
+5 −12
Original line number Diff line number Diff line
@@ -5,8 +5,6 @@ import androidx.annotation.NonNull;
import java.io.Serializable;
import java.util.Calendar;

import it.niedermann.owncloud.notes.util.NoteUtil;

/**
 * DBNote represents a single note from the local SQLite database with all attributes.
 * It extends CloudNote with attributes required for local data management.
@@ -16,12 +14,12 @@ public class DBNote extends CloudNote implements Item, Serializable {
    private long id;
    private long accountId;
    private DBStatus status;
    private String excerpt = "";
    private String excerpt;

    public DBNote(long id, long remoteId, Calendar modified, String title, String content, boolean favorite, String category, String etag, DBStatus status, long accountId) {
    public DBNote(long id, long remoteId, Calendar modified, String title, String content, boolean favorite, String category, String etag, DBStatus status, long accountId, String excerpt) {
        super(remoteId, modified, title, content, favorite, category, etag);
        this.id = id;
        setExcerpt(content);
        this.excerpt = excerpt;
        this.status = status;
        this.accountId = accountId;
    }
@@ -46,17 +44,12 @@ public class DBNote extends CloudNote implements Item, Serializable {
        return excerpt;
    }

    public void setExcerptDirectly(String content) {
        excerpt = content;
    }

    private void setExcerpt(String content) {
        excerpt = NoteUtil.generateNoteExcerpt(content);
    public void setExcerpt(String excerpt) {
        this.excerpt = excerpt;
    }

    public void setContent(String content) {
        super.setContent(content);
        setExcerpt(content);
    }

    @Override
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public class LoadNotesListTask extends AsyncTask<Void, Void, List<Item>> {
                        matcher.start(), matcher.end(), 0);
            }

            dbNote.setExcerptDirectly(Html.toHtml(spannableString));
            dbNote.setExcerpt(Html.toHtml(spannableString));
        }

        return dbNote;
+74 −31
Original line number Diff line number Diff line
@@ -50,27 +50,31 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {

    private static final String TAG = NoteSQLiteOpenHelper.class.getSimpleName();

    private static final int database_version = 9;
    private static final int database_version = 10;

    private static final String database_name = "OWNCLOUD_NOTES";
    private static final String table_notes = "NOTES";
    private static final String table_accounts = "ACCOUNTS";

    private static final String key_id = "ID";
    private static final String key_account_id = "ACCOUNT_ID";
    private static final String key_remote_id = "REMOTEID";

    private static final String key_url = "URL";
    private static final String key_account_name = "ACCOUNT_NAME";
    private static final String key_username = "USERNAME";

    private static final String key_account_id = "ACCOUNT_ID";
    private static final String key_remote_id = "REMOTEID";
    private static final String key_status = "STATUS";
    private static final String key_title = "TITLE";
    private static final String key_modified = "MODIFIED";
    private static final String key_content = "CONTENT";
    private static final String key_excerpt = "EXCERPT";
    private static final String key_favorite = "FAVORITE";
    private static final String key_category = "CATEGORY";
    private static final String key_etag = "ETAG";

    private static final String[] columns = {key_id, key_remote_id, key_status, key_title, key_modified, key_content, key_favorite, key_category, key_etag};
    private static final String[] columnsWithoutContent = {key_id, key_remote_id, key_status, key_title, key_modified, key_favorite, key_category, key_etag, key_excerpt};
    private static final String[] columns               = {key_id, key_remote_id, key_status, key_title, key_modified, key_favorite, key_category, key_etag, key_excerpt, key_content};
    private static final String default_order = key_favorite + " DESC, " + key_modified + " DESC";

    private static NoteSQLiteOpenHelper instance;
@@ -118,6 +122,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
                key_favorite + " INTEGER DEFAULT 0, " +
                key_category + " TEXT NOT NULL DEFAULT '', " +
                key_etag + " TEXT," +
                key_excerpt + " TEXT NOT NULL DEFAULT '', " +
                "FOREIGN KEY(" + key_account_id + ") REFERENCES " + table_accounts + "(" + key_id + "))");
        createNotesIndexes(db);
    }
@@ -195,7 +200,20 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
                    // Add FOREIGN_KEY constraint
                    final String table_temp = "NOTES_TEMP";
                    db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", table_notes, table_temp));
                    createNotesTable(db, table_notes);

                    db.execSQL("CREATE TABLE " + table_notes + " ( " +
                            key_id + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                            key_remote_id + " INTEGER, " +
                            key_account_id + " INTEGER, " +
                            key_status + " VARCHAR(50), " +
                            key_title + " TEXT, " +
                            key_modified + " INTEGER DEFAULT 0, " +
                            key_content + " TEXT, " +
                            key_favorite + " INTEGER DEFAULT 0, " +
                            key_category + " TEXT NOT NULL DEFAULT '', " +
                            key_etag + " TEXT," +
                            "FOREIGN KEY(" + key_account_id + ") REFERENCES " + table_accounts + "(" + key_id + "))");
                    DatabaseIndexUtil.createIndex(db, table_notes, key_remote_id, key_account_id, key_status, key_favorite, key_category, key_modified);

                    db.execSQL(String.format("INSERT INTO %s(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ", table_notes, key_id, key_account_id, key_remote_id, key_status, key_title, key_modified, key_content, key_favorite, key_category, key_etag)
                            + String.format("SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s", key_id, values.get(key_account_id), key_remote_id, key_status, key_title, key_modified, key_content, key_favorite, key_category, key_etag, table_temp));
@@ -239,6 +257,17 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
                recreateDatabase(db);
            }
        }
        if (oldVersion < 10) {
            db.execSQL("ALTER TABLE " + table_notes + " ADD COLUMN " + key_excerpt + " INTEGER NOT NULL DEFAULT ''");
            Cursor cursor = db.query(table_notes, new String[]{key_id, key_content}, null, null, null, null, null, null);
            while (cursor.moveToNext()) {
                ContentValues values = new ContentValues();
                values.put(key_excerpt, NoteUtil.generateNoteExcerpt(cursor.getString(1)));
                db.update(table_notes, values, key_id + " = ? ", new String[]{cursor.getString(0)});
            }
            cursor.close();
            DatabaseIndexUtil.createIndex(db, table_notes, key_excerpt);
        }
    }

    @Override
@@ -254,7 +283,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    }

    private static void createNotesIndexes(@NonNull SQLiteDatabase db) {
        DatabaseIndexUtil.createIndex(db, table_notes, key_remote_id, key_account_id, key_status, key_favorite, key_category, key_modified);
        DatabaseIndexUtil.createIndex(db, table_notes, key_remote_id, key_account_id, key_status, key_favorite, key_category, key_modified, key_excerpt);
    }

    private static void createAccountIndexes(@NonNull SQLiteDatabase db) {
@@ -271,7 +300,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
     * @param note Note
     */
    public long addNoteAndSync(long accountId, CloudNote note) {
        DBNote dbNote = new DBNote(0, 0, note.getModified(), note.getTitle(), note.getContent(), note.isFavorite(), note.getCategory(), note.getEtag(), DBStatus.LOCAL_EDITED, accountId);
        DBNote dbNote = new DBNote(0, 0, note.getModified(), note.getTitle(), note.getContent(), note.isFavorite(), note.getCategory(), note.getEtag(), DBStatus.LOCAL_EDITED, accountId, NoteUtil.generateNoteExcerpt(note.getContent()));
        long id = addNote(accountId, dbNote);
        notifyNotesChanged();
        getNoteServerSyncHelper().scheduleSync(true);
@@ -307,6 +336,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
        values.put(key_favorite, note.isFavorite());
        values.put(key_category, note.getCategory());
        values.put(key_etag, note.getEtag());
        values.put(key_excerpt, NoteUtil.generateNoteExcerpt(note.getContent()));
        return db.insert(table_notes, null, values);
    }

@@ -317,7 +347,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
     * @return requested Note
     */
    public DBNote getNote(long accountId, long id) {
        List<DBNote> notes = getNotesCustom(accountId, key_id + " = ? AND " + key_status + " != ? AND " + key_account_id + " = ? ", new String[]{String.valueOf(id), DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, null);
        List<DBNote> notes = getNotesCustom(accountId, key_id + " = ? AND " + key_status + " != ? AND " + key_account_id + " = ? ", new String[]{String.valueOf(id), DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, null, false);
        return notes.isEmpty() ? null : notes.get(0);
    }

@@ -331,21 +361,21 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
     */
    @NonNull
    @WorkerThread
    private List<DBNote> getNotesCustom(long accountId, @NonNull String selection, @NonNull String[] selectionArgs, @Nullable String orderBy) {
        return this.getNotesCustom(accountId, selection, selectionArgs, orderBy, null);
    private List<DBNote> getNotesCustom(long accountId, @NonNull String selection, @NonNull String[] selectionArgs, @Nullable String orderBy, boolean pruneContent) {
        return this.getNotesCustom(accountId, selection, selectionArgs, orderBy, null, pruneContent);
    }

    @NonNull
    @WorkerThread
    private List<DBNote> getNotesCustom(long accountId, @NonNull String selection, @NonNull String[] selectionArgs, @Nullable String orderBy, @Nullable String limit) {
    private List<DBNote> getNotesCustom(long accountId, @NonNull String selection, @NonNull String[] selectionArgs, @Nullable String orderBy, @Nullable String limit, boolean pruneContent) {
        SQLiteDatabase db = getReadableDatabase();
        if (selectionArgs.length > 2) {
            Log.v(TAG, selection + "   ----   " + selectionArgs[0] + " " + selectionArgs[1] + " " + selectionArgs[2]);
        }
        Cursor cursor = db.query(table_notes, columns, selection, selectionArgs, null, null, orderBy, limit);
        Cursor cursor = db.query(table_notes, pruneContent ? columnsWithoutContent : columns, selection, selectionArgs, null, null, orderBy, limit);
        List<DBNote> notes = new ArrayList<>();
        while (cursor.moveToNext()) {
            notes.add(getNoteFromCursor(accountId, cursor));
            notes.add(getNoteFromCursor(accountId, cursor, pruneContent));
        }
        cursor.close();
        return notes;
@@ -355,19 +385,33 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
     * Creates a DBNote object from the current row of a Cursor.
     *
     * @param cursor database cursor
     * @param pruneContent
     * @return DBNote
     */
    @NonNull
    private DBNote getNoteFromCursor(long accountId, @NonNull Cursor cursor) {
    private DBNote getNoteFromCursor(long accountId, @NonNull Cursor cursor, boolean pruneContent) {
        validateAccountId(accountId);
        Calendar modified = Calendar.getInstance();
        modified.setTimeInMillis(cursor.getLong(4) * 1000);
        return new DBNote(cursor.getLong(0), cursor.getLong(1), modified, cursor.getString(3), cursor.getString(5), cursor.getInt(6) > 0, cursor.getString(7), cursor.getString(8), DBStatus.parse(cursor.getString(2)), accountId);

        return new DBNote(
                cursor.getLong(0),
                cursor.getLong(1),
                modified,
                cursor.getString(3),
                pruneContent ? "" : cursor.getString(9),
                cursor.getInt(5) > 0,
                cursor.getString(6),
                cursor.getString(7),
                DBStatus.parse(cursor.getString(2)),
                accountId,
                pruneContent ? cursor.getString(8) : ""
        );
    }

    public void debugPrintFullDB(long accountId) {
        validateAccountId(accountId);
        List<DBNote> notes = getNotesCustom(accountId, "", new String[]{}, default_order);
        List<DBNote> notes = getNotesCustom(accountId, "", new String[]{}, default_order, false);
        Log.v(TAG, "Full Database (" + notes.size() + " notes):");
        for (DBNote note : notes) {
            Log.v(TAG, "     " + note);
@@ -397,14 +441,14 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    @WorkerThread
    public List<DBNote> getNotes(long accountId) {
        validateAccountId(accountId);
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, default_order);
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, default_order, false);
    }

    @NonNull
    @WorkerThread
    public List<DBNote> getRecentNotes(long accountId) {
        validateAccountId(accountId);
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, key_modified + " DESC", "4");
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.LOCAL_DELETED.getTitle(), "" + accountId}, key_modified + " DESC", "4", true);
    }

    /**
@@ -447,7 +491,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
        }

        String order = category == null ? default_order : key_category + ", " + key_title;
        return getNotesCustom(accountId, TextUtils.join(" AND ", where), args.toArray(new String[]{}), order);
        return getNotesCustom(accountId, TextUtils.join(" AND ", where), args.toArray(new String[]{}), order, true);
    }

    /**
@@ -459,7 +503,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    @WorkerThread
    List<DBNote> getLocalModifiedNotes(long accountId) {
        validateAccountId(accountId);
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.VOID.getTitle(), "" + accountId}, null);
        return getNotesCustom(accountId, key_status + " != ? AND " + key_account_id + " = ?", new String[]{DBStatus.VOID.getTitle(), "" + accountId}, null, false);
    }

    @NonNull
@@ -555,9 +599,9 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
        //debugPrintFullDB();
        DBNote newNote;
        if (newContent == null) {
            newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), oldNote.getModified(), oldNote.getTitle(), oldNote.getContent(), oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, accountId);
            newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), oldNote.getModified(), oldNote.getTitle(), oldNote.getContent(), oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, accountId, NoteUtil.generateNoteExcerpt(oldNote.getContent()));
        } else {
            newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), Calendar.getInstance(), NoteUtil.generateNonEmptyNoteTitle(newContent, getContext()), newContent, oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, accountId);
            newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), Calendar.getInstance(), NoteUtil.generateNonEmptyNoteTitle(newContent, getContext()), newContent, oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, accountId, NoteUtil.generateNoteExcerpt(oldNote.getContent()));
        }
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
@@ -566,6 +610,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
        values.put(key_category, newNote.getCategory());
        values.put(key_modified, newNote.getModified().getTimeInMillis() / 1000);
        values.put(key_content, newNote.getContent());
        values.put(key_excerpt, newNote.getExcerpt());
        int rows = db.update(table_notes, values, key_id + " = ? AND (" + key_content + " != ? OR " + key_category + " != ?)", new String[]{String.valueOf(newNote.getId()), newNote.getContent(), newNote.getCategory()});
        // if data was changed, set new status and schedule sync (with callback); otherwise invoke callback directly.
        if (rows > 0) {
@@ -610,6 +655,7 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
        values.put(key_favorite, remoteNote.isFavorite());
        values.put(key_category, remoteNote.getCategory());
        values.put(key_etag, remoteNote.getEtag());
        values.put(key_excerpt, NoteUtil.generateNoteExcerpt(remoteNote.getContent()));
        String whereClause;
        String[] whereArgs;
        if (forceUnchangedDBNoteState != null) {
@@ -703,7 +749,6 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    }

    /**
     *
     * @param url         URL to the root of the used Nextcloud instance without trailing slash
     * @param username    Username of the account
     * @param accountName Composed by the username and the host of the URL, separated by @-sign
@@ -719,7 +764,6 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    }

    /**
     *
     * @param accountId account which should be read
     * @return a LocalAccount object for the given accountId
     */
@@ -780,7 +824,6 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
    }

    /**
     *
     * @param accountId the id of the account that should be deleted
     * @throws IllegalArgumentException if no account has been deleted by the given accountId
     */