1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-16 12:06:23 -07:00

(Re)add next and previous page links

Add not-yet-used function to remove old threads that are past the board's limit
Also add functions to simplify querying with transactions
This commit is contained in:
Eggbertx 2023-01-18 12:35:40 -08:00
parent 3d430e7d83
commit 4f843d5431
7 changed files with 160 additions and 36 deletions

View file

@ -66,6 +66,13 @@ func main() {
gcutil.LogFatal().Err(err).Send()
}
for _, board := range gcsql.AllBoards {
if _, err = board.DeleteOldThreads(); err != nil {
fmt.Printf("Error deleting old threads for board /%s/: %s", board.Dir, err)
os.Exit(1)
}
}
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
posting.InitPosting()

View file

@ -195,8 +195,7 @@ func BuildBoardPages(board *gcsql.Board) error {
}
// Create the archive pages.
boardCfg := config.GetBoardConfig(board.Dir)
catalog.fillPages(boardCfg.ThreadsPerPage, catalogThreads)
catalog.fillPages(boardConfig.ThreadsPerPage, catalogThreads)
// Create array of page wrapper objects, and open the file.
var catalogPages boardCatalog
@ -238,17 +237,29 @@ func BuildBoardPages(board *gcsql.Board) error {
// Render the boardpage template
captchaCfg := config.GetSiteConfig().Captcha
if err = serverutil.MinifyTemplate(gctemplates.BoardPage, map[string]interface{}{
numThreads := len(threads)
numPages := numThreads / boardConfig.ThreadsPerPage
if (numThreads % boardConfig.ThreadsPerPage) > 0 {
numPages++
}
data := map[string]interface{}{
"boards": gcsql.AllBoards,
"sections": gcsql.AllSections,
"threads": page.Threads,
"numPages": len(threads) / boardConfig.ThreadsPerPage,
"numPages": numPages,
"currentPage": catalog.currentPage,
"board": board,
"boardConfig": boardCfg,
"boardConfig": boardConfig,
"useCaptcha": captchaCfg.UseCaptcha(),
"captcha": captchaCfg,
}, currentPageFile, "text/html"); err != nil {
}
if catalog.currentPage > 1 {
data["prevPage"] = catalog.currentPage - 1
}
if catalog.currentPage < numPages {
data["nextPage"] = catalog.currentPage + 1
}
if err = serverutil.MinifyTemplate(gctemplates.BoardPage, data, currentPageFile, "text/html"); err != nil {
errEv.Err(err).
Caller().Send()
return fmt.Errorf("failed building /%s/ boardpage: %s", board.Dir, err.Error())

View file

@ -59,26 +59,13 @@ func ApproveAppeal(appealID int, staffID int) error {
return err
}
defer tx.Rollback()
stmt, err := PrepareSQL(deactivateQuery, tx)
if err != nil {
if _, err = ExecTxSQL(tx, deactivateQuery, appealID); err != nil {
return err
}
defer func() {
stmt.Close()
}()
if _, err = stmt.Exec(appealID); err != nil {
if _, err = ExecTxSQL(tx, deactivateAppealQuery, appealID, staffID); err != nil {
return err
}
if stmt, err = PrepareSQL(deactivateAppealQuery, tx); err != nil {
return err
}
if _, err = stmt.Exec(appealID, staffID); err != nil {
return err
}
if stmt, err = PrepareSQL(deleteAppealQuery, tx); err != nil {
return err
}
if _, err = stmt.Exec(appealID); err != nil {
if _, err = ExecTxSQL(tx, deleteAppealQuery, appealID); err != nil {
return err
}
return tx.Commit()

View file

@ -143,20 +143,10 @@ func (ipb *IPBan) Deactivate(staffID int) error {
return err
}
defer tx.Rollback()
stmt1, err := PrepareSQL(deactivateQuery, tx)
if err != nil {
if _, err = ExecTxSQL(tx, deactivateQuery, ipb.ID); err != nil {
return err
}
if _, err = stmt1.Exec(ipb.ID); err != nil {
return err
}
stmt2, err := PrepareSQL(auditInsertQuery, tx)
if err != nil {
return err
}
if _, err = stmt2.Exec(ipb.ID); err != nil {
if _, err = ExecTxSQL(tx, auditInsertQuery, ipb.ID); err != nil {
return err
}
return tx.Commit()

View file

@ -266,6 +266,71 @@ func (board *Board) Delete() error {
return err
}
// DeleteOldThreads deletes old threads that exceed the limit set by board.MaxThreads and returns the posts in those
// threads
func (board *Board) DeleteOldThreads() ([]int, error) {
if board.MaxThreads < 1 {
return nil, nil
}
tx, err := BeginTx()
if err != nil {
return nil, err
}
defer tx.Rollback()
rows, err := QueryTxSQL(tx, `SELECT id FROM DBPREFIXthreads WHERE board_id = ? AND !is_deleted ORDER BY last_bump DESC`,
board.ID)
if err != nil {
return nil, err
}
defer rows.Close()
var threadIDs []interface{}
var id int
var threadsProccessed int
for rows.Next() {
threadsProccessed++
if threadsProccessed <= board.MaxThreads {
continue
}
if err = rows.Scan(&id); err != nil {
return nil, err
}
threadIDs = append(threadIDs, id)
}
if threadIDs == nil {
// no threads to trim
return nil, nil
}
idSetStr := createArrayPlaceholder(threadIDs)
if _, err = ExecTxSQL(tx, `UPDATE DBPREFIXthreads SET is_deleted = TRUE WHERE id in `+idSetStr,
threadIDs...); err != nil {
return nil, err
}
if rows, err = QueryTxSQL(tx, `SELECT id FROM DBPREFIXposts WHERE thread_id in `+idSetStr,
threadIDs...); err != nil {
return nil, err
}
defer rows.Close()
var postIDs []int
for rows.Next() {
if err = rows.Scan(&id); err != nil {
return nil, err
}
postIDs = append(postIDs, id)
}
if _, err = ExecTxSQL(tx, `UPDATE DBPREFIXposts SET is_deleted = TRUE WHERE thread_id in `+idSetStr,
threadIDs...); err != nil {
return nil, err
}
return postIDs, tx.Commit()
}
func (board *Board) GetThreads(onlyNotDeleted bool, orderLastByBump bool) ([]Thread, error) {
query := selectThreadsBaseSQL + " WHERE board_id = ?"
if onlyNotDeleted {

View file

@ -89,8 +89,8 @@ Example:
var intVal int
var stringVal string
result, err := gcsql.ExecSQL(db, "mysql",
"INSERT INTO tablename (intval,stringval) VALUES(?,?)", intVal, stringVal)
result, err := gcsql.ExecSQL("INSERT INTO tablename (intval,stringval) VALUES(?,?)",
intVal, stringVal)
*/
func ExecSQL(query string, values ...interface{}) (sql.Result, error) {
if gcdb == nil {
@ -99,6 +99,29 @@ func ExecSQL(query string, values ...interface{}) (sql.Result, error) {
return gcdb.ExecSQL(query, values...)
}
/*
ExecTxSQL automatically escapes the given values and caches the statement
Example:
tx, err := BeginTx()
// do error handling stuff
defer tx.Rollback()
var intVal int
var stringVal string
result, err := gcsql.ExecTxSQL(tx, "INSERT INTO tablename (intval,stringval) VALUES(?,?)",
intVal, stringVal)
*/
func ExecTxSQL(tx *sql.Tx, query string, values ...interface{}) (sql.Result, error) {
if gcdb == nil {
return nil, ErrNotConnected
}
stmt, err := PrepareSQL(query, tx)
if err != nil {
return nil, err
}
return stmt.Exec(values...)
}
/*
QueryRowSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query
@ -140,6 +163,32 @@ func QuerySQL(query string, a ...interface{}) (*sql.Rows, error) {
return gcdb.QuerySQL(query, a...)
}
/*
QueryTxSQL gets all rows from the db using the transaction tx with the values in values[] and fills the
respective pointers in out[]. Automatically escapes the given values and caches the query
Example:
tx, err := BeginTx()
// do error handling stuff
defer tx.Rollback()
rows, err := sqlutil.QueryTxSQL(tx, "SELECT * FROM table")
if err == nil {
for rows.Next() {
var intVal int
var stringVal string
rows.Scan(&intVal, &stringVal)
// do something with intVal and stringVal
}
}
*/
func QueryTxSQL(tx *sql.Tx, query string, a ...interface{}) (*sql.Rows, error) {
stmt, err := PrepareSQL(query, tx)
if err != nil {
return nil, err
}
return stmt.Query(a...)
}
func ParseSQLTimeString(str string) (time.Time, error) {
var t time.Time
var err error
@ -247,3 +296,12 @@ func interfaceSlice(args ...interface{}) []interface{} {
}
return true, nil
} */
// createArrayPlaceholder creates a string of ?s based on the size of arr
func createArrayPlaceholder(arr []interface{}) string {
params := make([]string, len(arr))
for p := range params {
params[p] = "?"
}
return "(" + strings.Join(params, ",") + ")"
}

View file

@ -37,6 +37,9 @@
<a href="#">Scroll to top</a><br/>
<table id="pages">
<tr>
{{- with .prevPage -}}
<td><a href="{{webPath "/" $.board.Dir (printf "%d.html" $.prevPage) }}">Prev</a></td>
{{- end -}}
<td>{{range $_,$i := makeLoop .numPages 1 -}}
{{- if eq $.currentPage $i -}}
[<b>{{$i}}</b>]
@ -44,6 +47,9 @@
[<a href="{{boardPagePath $.board $i}}">{{$i}}</a>]
{{- end -}}
{{- end}}</td>
{{- with .nextPage -}}
<td><a href="{{webPath "/" $.board.Dir (printf "%d.html" $.nextPage) }}">Next</a></td>
{{- end -}}
</tr>
</table>
<span id="boardmenu-bottom">