nrocco / bookmarks

Personal zero-touch bookmarking app in the cloud, with full text search support.
Apache License 2.0
26 stars 6 forks source link

Breaking changes #23

Open nrocco opened 3 years ago

nrocco commented 3 years ago

This open issue keeps track of breaking changes

nrocco commented 3 years ago

Migrate read it later functionality to a more generic tags based implementation:

BEGIN;

-- Migrate thoughts
DROP TABLE IF EXISTS thoughts_fts;
DROP TRIGGER IF EXISTS thoughts_ai;
DROP TRIGGER IF EXISTS thoughts_ad;
DROP TRIGGER IF EXISTS thoughts_au;

ALTER TABLE thoughts RENAME TO thoughts_old;

CREATE TABLE thoughts (
    id CHAR(16) PRIMARY KEY,
    created DATE NOT NULL,
    updated DATE NOT NULL,
    tags JSON NOT NULL DEFAULT '[]',
    content TEXT NOT NULL DEFAULT ''
);

INSERT INTO thoughts (id, created, updated, tags, content)
SELECT id, created, updated, tags, content
FROM thoughts_old;

DROP TABLE thoughts_old;

-- Migrate bookmarks
DROP TABLE IF EXISTS bookmarks_fts;
DROP TRIGGER IF EXISTS bookmarks_ai;
DROP TRIGGER IF EXISTS bookmarks_ad;
DROP TRIGGER IF EXISTS bookmarks_au;

ALTER TABLE bookmarks RENAME TO bookmarks_old;

CREATE TABLE bookmarks (
    id CHAR(16) PRIMARY KEY,
    created DATE DEFAULT (datetime('now')),
    updated DATE DEFAULT (datetime('now')),
    title VARCHAR(64) NOT NULL,
    url VARCHAR(255) UNIQUE NOT NULL,
    excerpt TEXT NOT NULL DEFAULT '',
    content TEXT NOT NULL DEFAULT '',
    tags JSON NOT NULL DEFAULT '[]'
);

INSERT INTO bookmarks (id, created, updated, title, url, excerpt, content, tags)
SELECT id, created, updated, title, url, excerpt, content, CASE WHEN archived=1 THEN '["read-it-later"]' ELSE '[]' END AS tags
FROM bookmarks_old;

DROP TABLE bookmarks_old;

COMMIT;
nrocco commented 3 years ago

Refresh full text search

-- Refresh the bookmarks fts
DROP TABLE IF EXISTS bookmarks_fts;
DROP TRIGGER IF EXISTS bookmarks_ai;
DROP TRIGGER IF EXISTS bookmarks_ad;
DROP TRIGGER IF EXISTS bookmarks_au;

CREATE VIRTUAL TABLE IF NOT EXISTS bookmarks_fts
USING fts5(title, url, content, tags, content=bookmarks, content_rowid=rowid);

INSERT INTO bookmarks_fts(rowid, title, url, content, tags)
SELECT rowid, title, url, content, tags FROM bookmarks;

-- Refresh the thoughts fts
DROP TABLE IF EXISTS thoughts_fts;
DROP TRIGGER IF EXISTS thoughts_ai;
DROP TRIGGER IF EXISTS thoughts_ad;
DROP TRIGGER IF EXISTS thoughts_au;

CREATE VIRTUAL TABLE IF NOT EXISTS thoughts_fts
USING fts5(content, tags, content=thoughts, content_rowid=rowid);

INSERT INTO thoughts_fts(rowid, content, tags)
SELECT rowid, content, tags FROM thoughts;
nrocco commented 3 years ago

Remove all html from bookmark content:

package cmd

import (
    "context"
    "log"

    "github.com/microcosm-cc/bluemonday"
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
    "github.com/nrocco/qb"
    _ "modernc.org/sqlite"
)

var fafaCmd = &cobra.Command{
    Use:   "fafa",
    Short: "Run the Bend web application and rest api",
    RunE: func(cmd *cobra.Command, args []string) error {
        ctx := context.Background()

        db, err := qb.Open(ctx, viper.GetString("storage"))
        if err != nil {
            return err
        }

        bookmarks := []struct{
            ID string
            Content string
        }{}

        query := db.Select(ctx).From("bookmarks").Columns("id", "content").Where("content LIKE '%<%'").Limit(50)
        if _, err := query.Load(&bookmarks); err != nil {
            return err
        }

        textCleaner := bluemonday.StrictPolicy()

        for _, bookmark := range bookmarks {
            log.Printf("==> Fixing %s", bookmark.ID)
            query := db.Update(ctx).Table("bookmarks")
            query.Set("content", textCleaner.Sanitize(bookmark.Content))
            query.Where("id = ?", bookmark.ID)

            if _, err := query.Exec(); err != nil {
                return err
            }
        }

        return nil
    },
}

func init() {
    rootCmd.AddCommand(fafaCmd)
}