diff --git a/DB.go b/DB.go index 1c80dc1..68e57d2 100644 --- a/DB.go +++ b/DB.go @@ -117,13 +117,18 @@ func (this *WikiDB) assertSchema() error { return nil } +type TitleInfo struct { + TitleID int64 + Title string + IsDeleted bool +} + type Article struct { - ID int64 - TitleID int64 - Modified int64 - Body []byte - Author string - Title string + TitleInfo + ArticleID int64 + Modified int64 + Body []byte + Author string } func (this *WikiDB) GetArticleById(articleId int) (*Article, error) { @@ -132,7 +137,7 @@ func (this *WikiDB) GetArticleById(articleId int) (*Article, error) { } func (this *WikiDB) GetRevision(revId int) (*Article, error) { - row := this.db.QueryRow(`SELECT articles.*, titles.title FROM articles JOIN titles ON articles.article=titles.id WHERE articles.id = ?`, revId) + row := this.db.QueryRow(`SELECT articles.*, titles.title, titles.is_deleted FROM articles JOIN titles ON articles.article=titles.id WHERE articles.id = ?`, revId) return this.parseArticleWithTitle(row) } @@ -164,8 +169,8 @@ func (this *WikiDB) SaveArticle(title, author, body string, expectBaseRev int64) } } - if !isNewArticle && a.ID != expectBaseRev { - return ArticleAlteredError{got: expectBaseRev, expected: a.ID} + if !isNewArticle && a.ArticleID != expectBaseRev { + return ArticleAlteredError{got: expectBaseRev, expected: a.ArticleID} } zBody, err := gzdeflate([]byte(body), this.compressionLevel) @@ -193,6 +198,13 @@ func (this *WikiDB) SaveArticle(title, author, body string, expectBaseRev int64) return err } + // Update is-deleted flag + isDeleted := 0 + if body == bbcodeIsDeleted { + isDeleted = 1 + } + _, err = this.db.Exec(`UPDATE titles SET is_deleted = ? WHERE id = ?`, isDeleted, titleId) + return nil } @@ -209,7 +221,7 @@ func (this *WikiDB) GetRevisionHistory(title string) ([]Article, error) { ret := make([]Article, 0) for rows.Next() { a := Article{} - err := rows.Scan(&a.ID, &a.Modified, &a.Author) + err := rows.Scan(&a.ArticleID, &a.Modified, &a.Author) if err != nil { return nil, err } @@ -235,7 +247,7 @@ func (this *WikiDB) GetNextOldestRevision(revision int) (int, error) { func (this *WikiDB) GetRecentChanges(offset int, limit int) ([]Article, error) { rows, err := this.db.Query( - `SELECT articles.id, articles.modified, articles.author, titles.title FROM articles JOIN titles ON articles.article=titles.id ORDER BY modified DESC ` + + `SELECT articles.id, articles.modified, articles.author, titles.title, titles.is_deleted FROM articles JOIN titles ON articles.article=titles.id ORDER BY modified DESC ` + fmt.Sprintf(`LIMIT %d OFFSET %d`, limit, offset), ) if err != nil { @@ -246,7 +258,7 @@ func (this *WikiDB) GetRecentChanges(offset int, limit int) ([]Article, error) { ret := make([]Article, 0, limit) for rows.Next() { a := Article{} - err := rows.Scan(&a.ID, &a.Modified, &a.Author, &a.Title) + err := rows.Scan(&a.ArticleID, &a.Modified, &a.Author, &a.Title, &a.IsDeleted) if err != nil { return nil, err } @@ -266,17 +278,23 @@ func (this *WikiDB) TotalRevisions() (int64, error) { return ret, nil } -func (this *WikiDB) ListTitles() ([]string, error) { - rows, err := this.db.Query(`SELECT title FROM titles ORDER BY title ASC`) +func (this *WikiDB) ListTitles(includeDeleted bool) ([]TitleInfo, error) { + stmt := `SELECT id, title, is_deleted FROM titles` + if !includeDeleted { + stmt += ` WHERE is_deleted = 0` + } + stmt += ` ORDER BY title ASC` + + rows, err := this.db.Query(stmt) if err != nil { return nil, err } defer rows.Close() - ret := make([]string, 0) + ret := make([]TitleInfo, 0) for rows.Next() { - var title string - err = rows.Scan(&title) + var title TitleInfo + err = rows.Scan(&title.TitleID, &title.Title, &title.IsDeleted) if err != nil { return nil, err } @@ -289,7 +307,7 @@ func (this *WikiDB) ListTitles() ([]string, error) { func (this *WikiDB) parseArticle(row *sql.Row) (*Article, error) { a := Article{} var gzBody []byte - err := row.Scan(&a.ID, &a.TitleID, &a.Modified, &gzBody, &a.Author) + err := row.Scan(&a.ArticleID, &a.TitleID, &a.Modified, &gzBody, &a.Author) if err != nil { return nil, err } @@ -307,7 +325,7 @@ func (this *WikiDB) parseArticle(row *sql.Row) (*Article, error) { func (this *WikiDB) parseArticleWithTitle(row *sql.Row) (*Article, error) { a := Article{} var gzBody []byte - err := row.Scan(&a.ID, &a.TitleID, &a.Modified, &gzBody, &a.Author, &a.Title) + err := row.Scan(&a.ArticleID, &a.TitleID, &a.Modified, &gzBody, &a.Author, &a.Title, &a.IsDeleted) if err != nil { return nil, err } diff --git a/WikiServer.go b/WikiServer.go index b58df7f..c79175a 100644 --- a/WikiServer.go +++ b/WikiServer.go @@ -148,14 +148,14 @@ func (this *WikiServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } else if remainingPath == "random" { - titles, err := this.db.ListTitles() + titles, err := this.db.ListTitles(false) // "Random page" mode does not include deleted pages if err != nil { this.serveInternalError(w, r, err) return } chosenArticle := titles[rand.Intn(len(titles))] - this.serveRedirect(w, this.opts.ExpectBaseURL+`view/`+url.PathEscape(chosenArticle)) + this.serveRedirect(w, this.opts.ExpectBaseURL+`view/`+url.PathEscape(chosenArticle.Title)) return } else if strings.HasPrefix(remainingPath, "view/") { diff --git a/rDiff.go b/rDiff.go index 37ee819..81101f4 100644 --- a/rDiff.go +++ b/rDiff.go @@ -53,9 +53,9 @@ func (this *WikiServer) routeDiff(w http.ResponseWriter, r *http.Request, oldRev pto.Content = template.HTML( `
` + string(b.Bytes()) + ``, ) diff --git a/rHistory.go b/rHistory.go index b6cff5c..1bf808a 100644 --- a/rHistory.go +++ b/rHistory.go @@ -37,7 +37,7 @@ func (this *WikiServer) routeHistory(w http.ResponseWriter, r *http.Request, art compareRow := `