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:
parent
3d430e7d83
commit
4f843d5431
7 changed files with 160 additions and 36 deletions
|
@ -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()
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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, ",") + ")"
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue