This commit's a little on the technical side, but don't worry. I have some interesting features coming up!

Added BypassGet() to the topic and user caches.
Moved 13 more queries to the query generator.
The query generator now supports simple insert queries.
Removed the pointless console logging for reply and topic deletions. We have modlogs for that.
The MySQL files now have build tags to make it easy for you to disable them for other database engines. Those will be coming after the query generator is done.
Moved a bunch of inline queries into more appropriate locations.
Rewrote _process_where and DB_Where to better handle joins.

Atom's continuing it's pointless crusade against trailing tabs.
This commit is contained in:
Azareal 2017-06-06 15:41:06 +01:00
parent 93d00b0337
commit 07a10ae9f4
10 changed files with 449 additions and 211 deletions

View File

@ -15,6 +15,7 @@ type DataStore interface {
Get(id int) (interface{}, error) Get(id int) (interface{}, error)
GetUnsafe(id int) (interface{}, error) GetUnsafe(id int) (interface{}, error)
CascadeGet(id int) (interface{}, error) CascadeGet(id int) (interface{}, error)
BypassGet(id int) (interface{}, error)
Set(item interface{}) error Set(item interface{}) error
Add(item interface{}) error Add(item interface{}) error
AddUnsafe(item interface{}) error AddUnsafe(item interface{}) error

View File

@ -1,4 +1,5 @@
/* This file was generated by Gosora's Query Generator */ /* This file was generated by Gosora's Query Generator */
// +build !pgsql !sqlite !mssql
package main package main
import "log" import "log"
@ -15,7 +16,20 @@ var get_settings_stmt *sql.Stmt
var get_setting_stmt *sql.Stmt var get_setting_stmt *sql.Stmt
var get_full_setting_stmt *sql.Stmt var get_full_setting_stmt *sql.Stmt
var is_plugin_active_stmt *sql.Stmt var is_plugin_active_stmt *sql.Stmt
var get_users_stmt *sql.Stmt
var is_theme_default_stmt *sql.Stmt
var get_modlogs_stmt *sql.Stmt
var get_reply_tid_stmt *sql.Stmt
var get_topic_fid_stmt *sql.Stmt
var get_user_reply_uid_stmt *sql.Stmt
var has_liked_topic_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt var get_topic_list_stmt *sql.Stmt
var get_topic_user_stmt *sql.Stmt
var get_topic_by_reply_stmt *sql.Stmt
var get_topic_replies_stmt *sql.Stmt
var get_forum_topics_stmt *sql.Stmt
var get_profile_replies_stmt *sql.Stmt
var create_topic_stmt *sql.Stmt
func gen_mysql() (err error) { func gen_mysql() (err error) {
if debug { if debug {
@ -88,11 +102,89 @@ func gen_mysql() (err error) {
return err return err
} }
log.Print("Preparing get_users statement.")
get_users_stmt, err = db.Prepare("SELECT `uid`,`name`,`group`,`active`,`is_super_admin`,`avatar` FROM users")
if err != nil {
return err
}
log.Print("Preparing is_theme_default statement.")
is_theme_default_stmt, err = db.Prepare("SELECT `default` FROM themes WHERE `uname` = ?")
if err != nil {
return err
}
log.Print("Preparing get_modlogs statement.")
get_modlogs_stmt, err = db.Prepare("SELECT `action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt` FROM moderation_logs")
if err != nil {
return err
}
log.Print("Preparing get_reply_tid statement.")
get_reply_tid_stmt, err = db.Prepare("SELECT `tid` FROM replies WHERE `rid` = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_fid statement.")
get_topic_fid_stmt, err = db.Prepare("SELECT `parentID` FROM topics WHERE `tid` = ?")
if err != nil {
return err
}
log.Print("Preparing get_user_reply_uid statement.")
get_user_reply_uid_stmt, err = db.Prepare("SELECT `uid` FROM users_replies WHERE `rid` = ?")
if err != nil {
return err
}
log.Print("Preparing has_liked_topic statement.")
has_liked_topic_stmt, err = db.Prepare("SELECT `targetItem` FROM likes WHERE `sentBy` = ? AND `targetItem` = ? AND `targetType` = 'topics'")
if err != nil {
return err
}
log.Print("Preparing get_topic_list statement.") log.Print("Preparing get_topic_list statement.")
get_topic_list_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`createdAt`,`topics`.`parentID`,`users`.`name`,`users`.`avatar` FROM topics LEFT JOIN users ON `topics`.`createdBy`=`users`.`uid` ORDER BY topics.sticky DESC,topics.lastReplyAt DESC,topics.createdBy DESC") get_topic_list_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`createdAt`,`topics`.`parentID`,`users`.`name`,`users`.`avatar` FROM topics LEFT JOIN users ON `topics`.`createdBy`=`users`.`uid` ORDER BY topics.sticky DESC,topics.lastReplyAt DESC,topics.createdBy DESC")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_topic_user statement.")
get_topic_user_stmt, err = db.Prepare("SELECT `topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`createdAt`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`parentID`,`topics`.`ipaddress`,`topics`.`postCount`,`topics`.`likeCount`,`users`.`name`,`users`.`avatar`,`users`.`group`,`users`.`url_prefix`,`users`.`url_name`,`users`.`level` FROM topics LEFT JOIN users ON `topics`.`createdBy`=`users`.`uid` WHERE `tid` = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_by_reply statement.")
get_topic_by_reply_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`createdAt`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`parentID`,`topics`.`ipaddress`,`topics`.`postCount`,`topics`.`likeCount` FROM replies LEFT JOIN topics ON `replies`.`tid`=`topics`.`tid` WHERE `rid` = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_replies statement.")
get_topic_replies_stmt, err = db.Prepare("SELECT `replies`.`rid`,`replies`.`content`,`replies`.`createdBy`,`replies`.`createdAt`,`replies`.`lastEdit`,`replies`.`lastEditBy`,`users`.`avatar`,`users`.`name`,`users`.`group`,`users`.`url_prefix`,`users`.`url_name`,`users`.`level`,`replies`.`ipaddress` FROM replies LEFT JOIN users ON `replies`.`createdBy`=`users`.`uid` WHERE `tid` = ?")
if err != nil {
return err
}
log.Print("Preparing get_forum_topics statement.")
get_forum_topics_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`createdAt`,`topics`.`lastReplyAt`,`topics`.`parentID`,`users`.`name`,`users`.`avatar` FROM topics LEFT JOIN users ON `topics`.`createdBy`=`users`.`uid` WHERE `topics`.`parentID` = ? ORDER BY topics.sticky DESC,topics.lastReplyAt DESC,topics.createdBy DESC")
if err != nil {
return err
}
log.Print("Preparing get_profile_replies statement.")
get_profile_replies_stmt, err = db.Prepare("SELECT `users_replies`.`rid`,`users_replies`.`content`,`users_replies`.`createdBy`,`users_replies`.`createdAt`,`users_replies`.`lastEdit`,`users_replies`.`lastEditBy`,`users`.`avatar`,`users`.`name`,`users`.`group` FROM users_replies LEFT JOIN users ON `users_replies`.`createdBy`=`users`.`uid` WHERE `users_replies`.`uid` = ?")
if err != nil {
return err
}
log.Print("Preparing create_topic statement.")
create_topic_stmt, err = db.Prepare("INSERT INTO topics(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,NOW(),NOW(),?,?,?)")
if err != nil {
return err
}
return nil return nil
} }

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"log" // "log"
// "fmt" // "fmt"
"strconv" "strconv"
"net" "net"
@ -15,20 +15,20 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
PreError("Bad Form",w,r) PreError("Bad Form",w,r)
return return
} }
is_js := r.PostFormValue("js") is_js := r.PostFormValue("js")
if is_js == "" { if is_js == "" {
is_js = "0" is_js = "0"
} }
var tid, fid int var tid, fid int
tid, err = strconv.Atoi(r.URL.Path[len("/topic/edit/submit/"):]) tid, err = strconv.Atoi(r.URL.Path[len("/topic/edit/submit/"):])
if err != nil { if err != nil {
PreErrorJSQ("The provided TopicID is not a valid number.",w,r,is_js) PreErrorJSQ("The provided TopicID is not a valid number.",w,r,is_js)
return return
} }
var old_is_closed bool var old_is_closed bool
err = db.QueryRow("select parentID, is_closed from topics where tid = ?", tid).Scan(&fid,&old_is_closed) err = db.QueryRow("select parentID, is_closed from topics where tid = ?", tid).Scan(&fid,&old_is_closed)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -38,7 +38,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,fid) user, ok := SimpleForumSessionCheck(w,r,fid)
if !ok { if !ok {
return return
@ -47,24 +47,24 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
NoPermissionsJSQ(w,r,user,is_js) NoPermissionsJSQ(w,r,user,is_js)
return return
} }
topic_name := r.PostFormValue("topic_name") topic_name := r.PostFormValue("topic_name")
topic_status := r.PostFormValue("topic_status") topic_status := r.PostFormValue("topic_status")
is_closed := (topic_status == "closed") is_closed := (topic_status == "closed")
topic_content := html.EscapeString(r.PostFormValue("topic_content")) topic_content := html.EscapeString(r.PostFormValue("topic_content"))
_, err = edit_topic_stmt.Exec(topic_name, preparse_message(topic_content), parse_message(html.EscapeString(preparse_message(topic_content))), is_closed, tid) _, err = edit_topic_stmt.Exec(topic_name, preparse_message(topic_content), parse_message(html.EscapeString(preparse_message(topic_content))), is_closed, tid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
return return
} }
if old_is_closed != is_closed { if old_is_closed != is_closed {
var action string var action string
if is_closed { if is_closed {
@ -72,7 +72,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
} else { } else {
action = "unlock" action = "unlock"
} }
err = addModLog(action,tid,"topic",ipaddress,user.ID) err = addModLog(action,tid,"topic",ipaddress,user.ID)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
@ -83,7 +83,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
_, err = add_replies_to_topic_stmt.Exec(1, tid) _, err = add_replies_to_topic_stmt.Exec(1, tid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
@ -95,13 +95,13 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
} }
err = topics.Load(tid) err = topics.Load(tid)
if err != nil { if err != nil {
LocalErrorJSQ("This topic no longer exists!",w,r,user,is_js) LocalErrorJSQ("This topic no longer exists!",w,r,user,is_js)
return return
} }
if is_js == "0" { if is_js == "0" {
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther) http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
} else { } else {
@ -115,7 +115,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
PreError("The provided TopicID is not a valid number.",w,r) PreError("The provided TopicID is not a valid number.",w,r)
return return
} }
var content string var content string
var createdBy, fid int var createdBy, fid int
err = db.QueryRow("select content, createdBy, parentID from topics where tid = ?", tid).Scan(&content, &createdBy, &fid) err = db.QueryRow("select content, createdBy, parentID from topics where tid = ?", tid).Scan(&content, &createdBy, &fid)
@ -126,7 +126,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,fid) user, ok := SimpleForumSessionCheck(w,r,fid)
if !ok { if !ok {
return return
@ -135,13 +135,13 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
_, err = delete_topic_stmt.Exec(tid) _, err = delete_topic_stmt.Exec(tid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -152,28 +152,30 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
// Might need soft-delete before we can do an action reply for this
/*_, err = create_action_reply_stmt.Exec(tid,"delete",ipaddress,user.ID) /*_, err = create_action_reply_stmt.Exec(tid,"delete",ipaddress,user.ID)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
}*/ }*/
log.Print("The topic '" + strconv.Itoa(tid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".") //log.Print("Topic #" + strconv.Itoa(tid) + " was deleted by User #" + strconv.Itoa(user.ID))
http.Redirect(w,r,"/",http.StatusSeeOther) http.Redirect(w,r,"/",http.StatusSeeOther)
wcount := word_count(content) wcount := word_count(content)
err = decrease_post_user_stats(wcount,createdBy,true,user) err = decrease_post_user_stats(wcount,createdBy,true,user)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
_, err = remove_topics_from_forum_stmt.Exec(1, fid) _, err = remove_topics_from_forum_stmt.Exec(1, fid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
forums[fid].TopicCount -= 1 forums[fid].TopicCount -= 1
topics.Remove(tid) topics.Remove(tid)
} }
@ -184,7 +186,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
PreError("The provided TopicID is not a valid number.",w,r) PreError("The provided TopicID is not a valid number.",w,r)
return return
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreError("The topic you tried to pin doesn't exist.",w,r) PreError("The topic you tried to pin doesn't exist.",w,r)
@ -193,7 +195,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,topic.ParentID) user, ok := SimpleForumSessionCheck(w,r,topic.ParentID)
if !ok { if !ok {
return return
@ -202,14 +204,13 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
_, err = stick_topic_stmt.Exec(tid) _, err = stick_topic_stmt.Exec(tid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
//topic.Sticky = true
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -225,7 +226,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = topics.Load(tid) err = topics.Load(tid)
if err != nil { if err != nil {
LocalError("This topic doesn't exist!",w,r,user) LocalError("This topic doesn't exist!",w,r,user)
@ -240,7 +241,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
PreError("The provided TopicID is not a valid number.",w,r) PreError("The provided TopicID is not a valid number.",w,r)
return return
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreError("The topic you tried to unpin doesn't exist.",w,r) PreError("The topic you tried to unpin doesn't exist.",w,r)
@ -249,7 +250,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,topic.ParentID) user, ok := SimpleForumSessionCheck(w,r,topic.ParentID)
if !ok { if !ok {
return return
@ -258,14 +259,13 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
_, err = unstick_topic_stmt.Exec(tid) _, err = unstick_topic_stmt.Exec(tid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
//topic.Sticky = false
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -281,7 +281,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = topics.Load(tid) err = topics.Load(tid)
if err != nil { if err != nil {
LocalError("This topic doesn't exist!",w,r,user) LocalError("This topic doesn't exist!",w,r,user)
@ -294,36 +294,36 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
PreError("Bad Form",w,r) PreError("Bad Form",w,r)
return return
} }
is_js := r.PostFormValue("js") is_js := r.PostFormValue("js")
if is_js == "" { if is_js == "" {
is_js = "0" is_js = "0"
} }
rid, err := strconv.Atoi(r.URL.Path[len("/reply/edit/submit/"):]) rid, err := strconv.Atoi(r.URL.Path[len("/reply/edit/submit/"):])
if err != nil { if err != nil {
PreErrorJSQ("The provided Reply ID is not a valid number.",w,r,is_js) PreErrorJSQ("The provided Reply ID is not a valid number.",w,r,is_js)
return return
} }
content := html.EscapeString(preparse_message(r.PostFormValue("edit_item"))) content := html.EscapeString(preparse_message(r.PostFormValue("edit_item")))
_, err = edit_reply_stmt.Exec(content, parse_message(content), rid) _, err = edit_reply_stmt.Exec(content, parse_message(content), rid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
// Get the Reply ID.. // Get the Reply ID..
var tid int var tid int
err = db.QueryRow("select tid from replies where rid = ?", rid).Scan(&tid) err = get_reply_tid_stmt.QueryRow(rid).Scan(&tid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
var fid int var fid int
err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid) err = get_topic_fid_stmt.QueryRow(tid).Scan(&fid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js) PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return return
@ -331,7 +331,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,fid) user, ok := SimpleForumSessionCheck(w,r,fid)
if !ok { if !ok {
return return
@ -340,7 +340,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
NoPermissionsJSQ(w,r,user,is_js) NoPermissionsJSQ(w,r,user,is_js)
return return
} }
if is_js == "0" { if is_js == "0" {
http.Redirect(w,r, "/topic/" + strconv.Itoa(tid) + "#reply-" + strconv.Itoa(rid), http.StatusSeeOther) http.Redirect(w,r, "/topic/" + strconv.Itoa(tid) + "#reply-" + strconv.Itoa(rid), http.StatusSeeOther)
} else { } else {
@ -352,19 +352,19 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
PreError("Bad Form",w,r) PreError("Bad Form",w,r)
return return
} }
is_js := r.PostFormValue("is_js") is_js := r.PostFormValue("is_js")
if is_js == "" { if is_js == "" {
is_js = "0" is_js = "0"
} }
rid, err := strconv.Atoi(r.URL.Path[len("/reply/delete/submit/"):]) rid, err := strconv.Atoi(r.URL.Path[len("/reply/delete/submit/"):])
if err != nil { if err != nil {
PreErrorJSQ("The provided Reply ID is not a valid number.",w,r,is_js) PreErrorJSQ("The provided Reply ID is not a valid number.",w,r,is_js)
return return
} }
var tid, createdBy int var tid, createdBy int
var content string var content string
err = db.QueryRow("select tid, content, createdBy from replies where rid = ?", rid).Scan(&tid, &content, &createdBy) err = db.QueryRow("select tid, content, createdBy from replies where rid = ?", rid).Scan(&tid, &content, &createdBy)
@ -375,9 +375,9 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
var fid int var fid int
err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid) err = get_topic_fid_stmt.QueryRow(tid).Scan(&fid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js) PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return return
@ -385,7 +385,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
user, ok := SimpleForumSessionCheck(w,r,fid) user, ok := SimpleForumSessionCheck(w,r,fid)
if !ok { if !ok {
return return
@ -394,19 +394,19 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
NoPermissionsJSQ(w,r,user,is_js) NoPermissionsJSQ(w,r,user,is_js)
return return
} }
_, err = delete_reply_stmt.Exec(rid) _, err = delete_reply_stmt.Exec(rid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
log.Print("The reply '" + strconv.Itoa(rid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".") //log.Print("Reply #" + strconv.Itoa(rid) + " was deleted by User #" + strconv.Itoa(user.ID))
if is_js == "0" { if is_js == "0" {
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther) //http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
} else { } else {
w.Write(success_json_bytes) w.Write(success_json_bytes)
} }
wcount := word_count(content) wcount := word_count(content)
err = decrease_post_user_stats(wcount, createdBy, false, user) err = decrease_post_user_stats(wcount, createdBy, false, user)
if err != nil { if err != nil {
@ -417,7 +417,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -428,7 +428,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = topics.Load(tid) err = topics.Load(tid)
if err != nil { if err != nil {
LocalError("This topic no longer exists!",w,r,user) LocalError("This topic no longer exists!",w,r,user)
@ -441,43 +441,43 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
if !ok { if !ok {
return return
} }
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
LocalError("Bad Form",w,r,user) LocalError("Bad Form",w,r,user)
return return
} }
is_js := r.PostFormValue("js") is_js := r.PostFormValue("js")
if is_js == "" { if is_js == "" {
is_js = "0" is_js = "0"
} }
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/edit/submit/"):]) rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/edit/submit/"):])
if err != nil { if err != nil {
LocalErrorJSQ("The provided Reply ID is not a valid number.",w,r,user,is_js) LocalErrorJSQ("The provided Reply ID is not a valid number.",w,r,user,is_js)
return return
} }
// Get the Reply ID.. // Get the Reply ID..
var uid int var uid int
err = db.QueryRow("select uid from users_replies where rid = ?", rid).Scan(&uid) err = get_user_reply_uid_stmt.QueryRow(rid).Scan(&uid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
if user.ID != uid && !user.Perms.EditReply { if user.ID != uid && !user.Perms.EditReply {
NoPermissionsJSQ(w,r,user,is_js) NoPermissionsJSQ(w,r,user,is_js)
return return
} }
content := html.EscapeString(preparse_message(r.PostFormValue("edit_item"))) content := html.EscapeString(preparse_message(r.PostFormValue("edit_item")))
_, err = edit_profile_reply_stmt.Exec(content, parse_message(content), rid) _, err = edit_profile_reply_stmt.Exec(content, parse_message(content), rid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
if is_js == "0" { if is_js == "0" {
http.Redirect(w,r,"/user/" + strconv.Itoa(uid) + "#reply-" + strconv.Itoa(rid), http.StatusSeeOther) http.Redirect(w,r,"/user/" + strconv.Itoa(uid) + "#reply-" + strconv.Itoa(rid), http.StatusSeeOther)
} else { } else {
@ -490,25 +490,25 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
if !ok { if !ok {
return return
} }
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
LocalError("Bad Form",w,r,user) LocalError("Bad Form",w,r,user)
return return
} }
is_js := r.PostFormValue("is_js") is_js := r.PostFormValue("is_js")
if is_js == "" { if is_js == "" {
is_js = "0" is_js = "0"
} }
rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/delete/submit/"):]) rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/delete/submit/"):])
if err != nil { if err != nil {
LocalErrorJSQ("The provided Reply ID is not a valid number.",w,r,user,is_js) LocalErrorJSQ("The provided Reply ID is not a valid number.",w,r,user,is_js)
return return
} }
var uid int var uid int
err = db.QueryRow("select uid from users_replies where rid = ?", rid).Scan(&uid) err = get_user_reply_uid_stmt.QueryRow(rid).Scan(&uid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js) LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
return return
@ -516,19 +516,19 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
if user.ID != uid && !user.Perms.DeleteReply { if user.ID != uid && !user.Perms.DeleteReply {
NoPermissionsJSQ(w,r,user,is_js) NoPermissionsJSQ(w,r,user,is_js)
return return
} }
_, err = delete_profile_reply_stmt.Exec(rid) _, err = delete_profile_reply_stmt.Exec(rid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
log.Print("The reply '" + strconv.Itoa(rid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".") //log.Print("The profile post '" + strconv.Itoa(rid) + "' was deleted by User #" + strconv.Itoa(user.ID))
if is_js == "0" { if is_js == "0" {
//http.Redirect(w,r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther) //http.Redirect(w,r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
} else { } else {
@ -545,13 +545,13 @@ func route_ban(w http.ResponseWriter, r *http.Request) {
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/"):]) uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/"):])
if err != nil { if err != nil {
LocalError("The provided User ID is not a valid number.",w,r,user) LocalError("The provided User ID is not a valid number.",w,r,user)
return return
} }
var uname string var uname string
err = db.QueryRow("select name from users where uid = ?", uid).Scan(&uname) err = db.QueryRow("select name from users where uid = ?", uid).Scan(&uname)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -561,10 +561,10 @@ func route_ban(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
confirm_msg := "Are you sure you want to ban '" + uname + "'?" confirm_msg := "Are you sure you want to ban '" + uname + "'?"
yousure := AreYouSure{"/users/ban/submit/" + strconv.Itoa(uid),confirm_msg} yousure := AreYouSure{"/users/ban/submit/" + strconv.Itoa(uid),confirm_msg}
pi := Page{"Ban User",user,noticeList,tList,yousure} pi := Page{"Ban User",user,noticeList,tList,yousure}
templates.ExecuteTemplate(w,"areyousure.html",pi) templates.ExecuteTemplate(w,"areyousure.html",pi)
} }
@ -582,7 +582,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
SecurityError(w,r,user) SecurityError(w,r,user)
return return
} }
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/submit/"):]) uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/submit/"):])
if err != nil { if err != nil {
LocalError("The provided User ID is not a valid number.",w,r,user) LocalError("The provided User ID is not a valid number.",w,r,user)
@ -592,7 +592,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
LocalError("Sigh, are you really trying to ban me? Do you despise so much? Despite all of our adventures over at /arcane-tower/...?",w,r,user) LocalError("Sigh, are you really trying to ban me? Do you despise so much? Despite all of our adventures over at /arcane-tower/...?",w,r,user)
return return
} }
var group int var group int
var is_super_admin bool var is_super_admin bool
err = db.QueryRow("select `group`,`is_super_admin` from `users` where `uid` = ?", uid).Scan(&group, &is_super_admin) err = db.QueryRow("select `group`,`is_super_admin` from `users` where `uid` = ?", uid).Scan(&group, &is_super_admin)
@ -603,7 +603,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
if is_super_admin || groups[group].Is_Admin || groups[group].Is_Mod { if is_super_admin || groups[group].Is_Admin || groups[group].Is_Mod {
LocalError("You may not ban another staff member.",w,r,user) LocalError("You may not ban another staff member.",w,r,user)
return return
@ -612,18 +612,18 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
LocalError("Why are you trying to ban yourself? Stop that.",w,r,user) LocalError("Why are you trying to ban yourself? Stop that.",w,r,user)
return return
} }
if groups[group].Is_Banned { if groups[group].Is_Banned {
LocalError("The user you're trying to unban is already banned.",w,r,user) LocalError("The user you're trying to unban is already banned.",w,r,user)
return return
} }
_, err = change_group_stmt.Exec(4, uid) _, err = change_group_stmt.Exec(4, uid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -634,7 +634,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = users.Load(uid) err = users.Load(uid)
if err != nil { if err != nil {
LocalError("This user no longer exists!",w,r,user) LocalError("This user no longer exists!",w,r,user)
@ -656,13 +656,13 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
SecurityError(w,r,user) SecurityError(w,r,user)
return return
} }
uid, err := strconv.Atoi(r.URL.Path[len("/users/unban/"):]) uid, err := strconv.Atoi(r.URL.Path[len("/users/unban/"):])
if err != nil { if err != nil {
LocalError("The provided User ID is not a valid number.",w,r,user) LocalError("The provided User ID is not a valid number.",w,r,user)
return return
} }
var uname string var uname string
var group int var group int
err = db.QueryRow("select `name`, `group` from users where `uid` = ?", uid).Scan(&uname, &group) err = db.QueryRow("select `name`, `group` from users where `uid` = ?", uid).Scan(&uname, &group)
@ -673,18 +673,18 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
if !groups[group].Is_Banned { if !groups[group].Is_Banned {
LocalError("The user you're trying to unban isn't banned.",w,r,user) LocalError("The user you're trying to unban isn't banned.",w,r,user)
return return
} }
_, err = change_group_stmt.Exec(default_group, uid) _, err = change_group_stmt.Exec(default_group, uid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -695,7 +695,7 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = users.Load(uid) err = users.Load(uid)
if err != nil { if err != nil {
LocalError("This user no longer exists!",w,r,user) LocalError("This user no longer exists!",w,r,user)
@ -717,13 +717,13 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
SecurityError(w,r,user) SecurityError(w,r,user)
return return
} }
uid, err := strconv.Atoi(r.URL.Path[len("/users/activate/"):]) uid, err := strconv.Atoi(r.URL.Path[len("/users/activate/"):])
if err != nil { if err != nil {
LocalError("The provided User ID is not a valid number.",w,r,user) LocalError("The provided User ID is not a valid number.",w,r,user)
return return
} }
var uname string var uname string
var active bool var active bool
err = db.QueryRow("select `name`,`active` from users where `uid` = ?", uid).Scan(&uname, &active) err = db.QueryRow("select `name`,`active` from users where `uid` = ?", uid).Scan(&uname, &active)
@ -734,7 +734,7 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
if active { if active {
LocalError("The account you're trying to activate has already been activated.",w,r,user) LocalError("The account you're trying to activate has already been activated.",w,r,user)
return return
@ -744,13 +744,13 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
_, err = change_group_stmt.Exec(default_group, uid) _, err = change_group_stmt.Exec(default_group, uid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
LocalError("Bad IP",w,r,user) LocalError("Bad IP",w,r,user)
@ -761,7 +761,7 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = users.Load(uid) err = users.Load(uid)
if err != nil { if err != nil {
LocalError("This user no longer exists!",w,r,user) LocalError("This user no longer exists!",w,r,user)

View File

@ -1,4 +1,5 @@
/* Copyright Azareal 2016 - 2017 */ /* Copyright Azareal 2016 - 2017 */
// +build !pgsql !sqlite !mssql
package main package main
import "database/sql" import "database/sql"
@ -12,13 +13,8 @@ var db *sql.DB
var db_version string var db_version string
var db_collation string = "utf8mb4_general_ci" var db_collation string = "utf8mb4_general_ci"
var get_topic_user_stmt *sql.Stmt var get_topic_replies_offset_stmt *sql.Stmt // I'll need to rewrite this one to stop it hard-coding the per page setting before moving it to the query generator
var get_topic_by_reply_stmt *sql.Stmt
var get_topic_replies_stmt *sql.Stmt
var get_topic_replies_offset_stmt *sql.Stmt
var get_forum_topics_stmt *sql.Stmt
var get_forum_topics_offset_stmt *sql.Stmt var get_forum_topics_offset_stmt *sql.Stmt
var create_topic_stmt *sql.Stmt
var create_report_stmt *sql.Stmt var create_report_stmt *sql.Stmt
var create_reply_stmt *sql.Stmt var create_reply_stmt *sql.Stmt
var create_action_reply_stmt *sql.Stmt var create_action_reply_stmt *sql.Stmt
@ -88,6 +84,10 @@ var add_theme_stmt *sql.Stmt
var update_theme_stmt *sql.Stmt var update_theme_stmt *sql.Stmt
var add_modlog_entry_stmt *sql.Stmt var add_modlog_entry_stmt *sql.Stmt
var add_adminlog_entry_stmt *sql.Stmt var add_adminlog_entry_stmt *sql.Stmt
var todays_post_count_stmt *sql.Stmt
var todays_topic_count_stmt *sql.Stmt
var todays_report_count_stmt *sql.Stmt
var todays_newuser_count_stmt *sql.Stmt
func init_database() (err error) { func init_database() (err error) {
if(dbpassword != ""){ if(dbpassword != ""){
@ -118,48 +118,18 @@ func init_database() (err error) {
return err return err
} }
log.Print("Preparing get_topic_user statement.")
get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_by_reply statement.")
get_topic_by_reply_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount from replies left join topics on replies.tid = topics.tid where rid = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_replies statement.")
get_topic_replies_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_replies_offset statement.") log.Print("Preparing get_topic_replies_offset statement.")
get_topic_replies_offset_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.actionType from replies left join users on replies.createdBy = users.uid where tid = ? limit ?, " + strconv.Itoa(items_per_page)) get_topic_replies_offset_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.actionType from replies left join users on replies.createdBy = users.uid where tid = ? limit ?, " + strconv.Itoa(items_per_page))
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_forum_topics statement.")
get_forum_topics_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc")
if err != nil {
return err
}
log.Print("Preparing get_forum_topics_offset statement.") log.Print("Preparing get_forum_topics_offset statement.")
get_forum_topics_offset_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, topics.postCount, topics.likeCount, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC limit ?, " + strconv.Itoa(items_per_page)) get_forum_topics_offset_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, topics.postCount, topics.likeCount, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC limit ?, " + strconv.Itoa(items_per_page))
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing create_topic statement.")
create_topic_stmt, err = db.Prepare("insert into topics(parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy) VALUES(?,?,?,?,NOW(),NOW(),?,?,?)")
if err != nil {
return err
}
log.Print("Preparing create_report statement.") log.Print("Preparing create_report statement.")
create_report_stmt, err = db.Prepare("INSERT INTO topics(title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class) VALUES(?,?,?,NOW(),NOW(),?,?,1,'report')") create_report_stmt, err = db.Prepare("INSERT INTO topics(title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class) VALUES(?,?,?,NOW(),NOW(),?,?,1,'report')")
if err != nil { if err != nil {
@ -560,6 +530,30 @@ func init_database() (err error) {
return err return err
} }
log.Print("Preparing todays_post_count statement.")
todays_post_count_stmt, err = db.Prepare("select count(*) from replies where createdAt BETWEEN (now() - interval 1 day) and now()")
if err != nil {
return err
}
log.Print("Preparing todays_topic_count statement.")
todays_topic_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now()")
if err != nil {
return err
}
log.Print("Preparing todays_report_count statement.")
todays_report_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now() and parentID = 1")
if err != nil {
return err
}
log.Print("Preparing todays_newuser_count statement.")
todays_newuser_count_stmt, err = db.Prepare("select count(*) from users where createdAt BETWEEN (now() - interval 1 day) and now()")
if err != nil {
return err
}
log.Print("Loading the usergroups.") log.Print("Loading the usergroups.")
groups = append(groups, Group{ID:0,Name:"System"}) groups = append(groups, Group{ID:0,Name:"System"})

View File

@ -81,7 +81,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
} }
var postCount int var postCount int
err = db.QueryRow("select count(*) from replies where createdAt BETWEEN (now() - interval 1 day) and now()").Scan(&postCount) err = todays_post_count_stmt.QueryRow().Scan(&postCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -98,7 +98,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
} }
var topicCount int var topicCount int
err = db.QueryRow("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now()").Scan(&topicCount) err = todays_topic_count_stmt.QueryRow().Scan(&topicCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -115,7 +115,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
} }
var reportCount int var reportCount int
err = db.QueryRow("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now() and parentID = 1").Scan(&reportCount) err = todays_report_count_stmt.QueryRow().Scan(&reportCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -123,7 +123,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var reportInterval string = "week" var reportInterval string = "week"
var newUserCount int var newUserCount int
err = db.QueryRow("select count(*) from users where createdAt BETWEEN (now() - interval 1 day) and now()").Scan(&newUserCount) err = todays_newuser_count_stmt.QueryRow().Scan(&newUserCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -770,7 +770,7 @@ func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request, unam
} }
var active bool var active bool
err := db.QueryRow("select active from plugins where uname = ?", uname).Scan(&active) err := is_plugin_active_stmt.QueryRow(uname).Scan(&active)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
LocalError("The plugin you're trying to deactivate isn't active",w,r,user) LocalError("The plugin you're trying to deactivate isn't active",w,r,user)
return return
@ -807,7 +807,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
} }
var userList []interface{} var userList []interface{}
rows, err := db.Query("select `uid`,`name`,`group`,`active`,`is_super_admin`,`avatar` from users") rows, err := get_users_stmt.Query()
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -1481,7 +1481,7 @@ func route_panel_themes_default(w http.ResponseWriter, r *http.Request, uname st
} }
var isDefault bool var isDefault bool
err := db.QueryRow("select `default` from `themes` where `uname` = ?", uname).Scan(&isDefault) err := is_theme_default_stmt.QueryRow(uname).Scan(&isDefault)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -1542,7 +1542,7 @@ func route_panel_logs_mod(w http.ResponseWriter, r *http.Request){
return return
} }
rows, err := db.Query("select action, elementID, elementType, ipaddress, actorID, doneAt from moderation_logs") rows, err := get_modlogs_stmt.Query()
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return

View File

@ -1,7 +1,7 @@
/* WIP Under Construction */ /* WIP Under Construction */
package main package main
//import "fmt" import "fmt"
import "strings" import "strings"
import "log" import "log"
import "os" import "os"
@ -17,10 +17,18 @@ type DB_Column struct
Type string // function or column Type string // function or column
} }
type DB_Field struct
{
Name string
Type string
}
type DB_Where struct type DB_Where struct
{ {
Left string LeftTable string
Right string LeftColumn string
RightTable string
RightColumn string
Operator string Operator string
LeftType string LeftType string
RightType string RightType string
@ -42,8 +50,8 @@ type DB_Order struct
type DB_Adapter interface { type DB_Adapter interface {
get_name() string get_name() string
simple_insert(string,string,string,[]string,[]bool) error simple_insert(string,string,string,string) error
//simple_replace(string,string,[]string,[]string,[]bool) error //simple_replace(string,string,[]string,string) error
simple_update() error simple_update() error
simple_select(string,string,string,string,string/*,int,int*/) error simple_select(string,string,string,string,string/*,int,int*/) error
simple_left_join(string,string,string,string,string,string,string/*,int,int*/) error simple_left_join(string,string,string,string,string,string,string/*,int,int*/) error
@ -76,6 +84,7 @@ func write_statements(adapter DB_Adapter) error {
adapter.simple_select("username_exists","users","name","name = ?","") adapter.simple_select("username_exists","users","name","name = ?","")
adapter.simple_select("get_settings","settings","name, content, type","","") adapter.simple_select("get_settings","settings","name, content, type","","")
adapter.simple_select("get_setting","settings","content, type","name = ?","") adapter.simple_select("get_setting","settings","content, type","name = ?","")
@ -84,9 +93,37 @@ func write_statements(adapter DB_Adapter) error {
adapter.simple_select("is_plugin_active","plugins","active","uname = ?","") adapter.simple_select("is_plugin_active","plugins","active","uname = ?","")
adapter.simple_select("get_users","users","uid, name, group, active, is_super_admin, avatar","","")
adapter.simple_select("is_theme_default","themes","default","uname = ?","")
adapter.simple_select("get_modlogs","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","","")
adapter.simple_select("get_reply_tid","replies","tid","rid = ?","")
adapter.simple_select("get_topic_fid","topics","parentID","tid = ?","")
adapter.simple_select("get_user_reply_uid","users_replies","uid","rid = ?","")
adapter.simple_select("has_liked_topic","likes","targetItem","sentBy = ? and targetItem = ? and targetType = 'topics'","")
/*"select targetItem from likes where sentBy = ? and targetItem = ? and targetType = 'replies'"*/
adapter.simple_left_join("get_topic_list","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC") adapter.simple_left_join("get_topic_list","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
adapter.simple_left_join("get_topic_user","topics","users","topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level","topics.createdBy = users.uid","tid = ?","")
adapter.simple_left_join("get_topic_by_reply","replies","topics","topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount","replies.tid = topics.tid","rid = ?","")
adapter.simple_left_join("get_topic_replies","replies","users","replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress","replies.createdBy = users.uid","tid = ?","")
adapter.simple_left_join("get_forum_topics","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","topics.parentID = ?","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc")
adapter.simple_left_join("get_profile_replies","users_replies","users","users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group","users_replies.createdBy = users.uid","users_replies.uid = ?","")
adapter.simple_insert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,NOW(),NOW(),?,?,?")
return nil return nil
} }
@ -175,16 +212,73 @@ func _process_where(wherestr string) (where []DB_Where) {
// TO-DO: Subparse the contents of a function and spit out a DB_Function struct // TO-DO: Subparse the contents of a function and spit out a DB_Function struct
var outwhere DB_Where var outwhere DB_Where
var parseOffset int var parseOffset int
outwhere.Left, parseOffset = _get_identifier(segment, parseOffset) var left, right string
left, parseOffset = _get_identifier(segment, parseOffset)
outwhere.Operator, parseOffset = _get_operator(segment, parseOffset + 1) outwhere.Operator, parseOffset = _get_operator(segment, parseOffset + 1)
outwhere.Right, parseOffset = _get_identifier(segment, parseOffset + 1) right, parseOffset = _get_identifier(segment, parseOffset + 1)
outwhere.LeftType = _get_identifier_type(outwhere.Left) outwhere.LeftType = _get_identifier_type(left)
outwhere.RightType = _get_identifier_type(outwhere.Right) outwhere.RightType = _get_identifier_type(right)
left_operand := strings.Split(left,".")
right_operand := strings.Split(right,".")
if len(left_operand) == 2 {
outwhere.LeftTable = strings.TrimSpace(left_operand[0])
outwhere.LeftColumn = strings.TrimSpace(left_operand[1])
} else {
outwhere.LeftColumn = strings.TrimSpace(left_operand[0])
}
if len(right_operand) == 2 {
outwhere.RightTable = strings.TrimSpace(right_operand[0])
outwhere.RightColumn = strings.TrimSpace(right_operand[1])
} else {
outwhere.RightColumn = strings.TrimSpace(right_operand[0])
}
where = append(where,outwhere) where = append(where,outwhere)
} }
return where return where
} }
func _process_fields(fieldstr string) (fields []DB_Field) {
fmt.Println("_Entering _process_fields")
if fieldstr == "" {
return fields
}
var buffer string
var last_item int
fieldstr += ","
for i := 0; i < len(fieldstr); i++ {
if fieldstr[i] == '(' {
var pre_i int
pre_i = i
i = _skip_function_call(fieldstr,i-1)
fmt.Println("msg prior to i",fieldstr[0:i])
fmt.Println("len(fieldstr)",len(fieldstr))
fmt.Println("pre_i",pre_i)
fmt.Println("last_item",last_item)
fmt.Println("pre_i",string(fieldstr[pre_i]))
fmt.Println("last_item",string(fieldstr[last_item]))
fmt.Println("fieldstr[pre_i:i+1]",fieldstr[pre_i:i+1])
fmt.Println("fieldstr[last_item:i+1]",fieldstr[last_item:i+1])
fields = append(fields,DB_Field{Name:fieldstr[last_item:i+1],Type:_get_identifier_type(fieldstr[last_item:i+1])})
buffer = ""
last_item = i + 2
} else if fieldstr[i] == ',' && buffer != "" {
fields = append(fields,DB_Field{Name:buffer,Type:_get_identifier_type(buffer)})
buffer = ""
last_item = i + 1
} else if (fieldstr[i] > 32) && fieldstr[i] != ',' && fieldstr[i] != ')' {
buffer += string(fieldstr[i])
}
}
fmt.Println("fields",fields)
return fields
}
func _get_identifier_type(identifier string) string { func _get_identifier_type(identifier string) string {
if ('a' <= identifier[0] && identifier[0] <= 'z') || ('A' <= identifier[0] && identifier[0] <= 'Z') { if ('a' <= identifier[0] && identifier[0] <= 'z') || ('A' <= identifier[0] && identifier[0] <= 'Z') {
if identifier[len(identifier) - 1] == ')' { if identifier[len(identifier) - 1] == ')' {
@ -229,19 +323,23 @@ func _get_operator(segment string, startOffset int) (out string, i int) {
return strings.TrimSpace(segment[startOffset:]), (i - 1) return strings.TrimSpace(segment[startOffset:]), (i - 1)
} }
func _skip_function_call(segment string, i int) int { func _skip_function_call(data string, index int) int {
var brace_count int = 1 var brace_count int
for ; i < len(segment); i++ { for ;index < len(data); index++{
if segment[i] == '(' { char := data[index]
if char == '(' {
fmt.Println("Enter brace")
brace_count++ brace_count++
} else if segment[i] == ')' { } else if char == ')' {
brace_count-- brace_count--
} fmt.Println("Exit brace")
if brace_count == 0 { if brace_count == 0 {
return i fmt.Println("Exit function segment")
return index
}
} }
} }
return i return index
} }
func write_file(name string, content string) (err error) { func write_file(name string, content string) (err error) {

View File

@ -20,7 +20,7 @@ func (adapter *Mysql_Adapter) get_name() string {
return adapter.Name return adapter.Name
} }
func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns string, fields []string, quoteWhat []bool) error { func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns string, fields string) error {
if name == "" { if name == "" {
return errors.New("You need a name for this statement") return errors.New("You need a name for this statement")
} }
@ -34,28 +34,23 @@ func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns s
return errors.New("No input data found for simple_insert") return errors.New("No input data found for simple_insert")
} }
// Slice up the user friendly strings into something easier to process
var colslice []string = strings.Split(strings.TrimSpace(columns),",")
var noquotes bool = (len(quoteWhat) == 0)
var querystr string = "INSERT INTO " + table + "(" var querystr string = "INSERT INTO " + table + "("
// Escape the column names, just in case we've used a reserved keyword // Escape the column names, just in case we've used a reserved keyword
// TO-DO: Subparse the columns to allow functions and AS keywords for _, column := range _process_columns(columns) {
for _, column := range colslice { if column.Type == "function" {
querystr += "`" + column + "`," querystr += column.Left + ","
} else {
querystr += "`" + column.Left + "`,"
}
} }
// Remove the trailing comma // Remove the trailing comma
querystr = querystr[0:len(querystr) - 1] querystr = querystr[0:len(querystr) - 1]
querystr += ") VALUES (" querystr += ") VALUES ("
for fid, field := range fields { for _, field := range _process_fields(fields) {
if !noquotes && quoteWhat[fid] { querystr += field.Name + ","
querystr += "'" + field + "',"
} else {
querystr += field + ","
}
} }
querystr = querystr[0:len(querystr) - 1] querystr = querystr[0:len(querystr) - 1]
@ -93,20 +88,24 @@ func (adapter *Mysql_Adapter) simple_select(name string, table string, columns s
querystr += " FROM " + table querystr += " FROM " + table
if len(where) != 0 { if len(where) != 0 {
querystr += " WHERE" querystr += " " + "WHERE"
//fmt.Println("where",where)
//fmt.Println("_process_where(where)",_process_where(where))
for _, loc := range _process_where(where) { for _, loc := range _process_where(where) {
var lquote, rquote string var left, right string
if loc.LeftType == "column" { if loc.LeftType == "column" {
lquote = "`" left = "`" + loc.LeftColumn + "`"
} else {
left = loc.LeftColumn
} }
if loc.RightType == "column" { if loc.RightType == "column" {
rquote = "`" right = "`" + loc.RightColumn + "`"
} else {
right = loc.RightColumn
} }
querystr += " " + lquote + loc.Left + lquote + " " + loc.Operator + " " + rquote + loc.Right + rquote + " AND "
querystr += " " + left + " " + loc.Operator + " " + right + " AND "
} }
// Remove the trailing AND
querystr = querystr[0:len(querystr) - 4] querystr = querystr[0:len(querystr) - 4]
} }
@ -172,16 +171,27 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
if len(where) != 0 { if len(where) != 0 {
querystr += " " + "WHERE" querystr += " " + "WHERE"
for _, loc := range _process_where(where) { for _, loc := range _process_where(where) {
var lquote, rquote string var left, right string
if loc.LeftType == "column" {
lquote = "`" if loc.LeftTable != "" {
left = "`" + loc.LeftTable + "`.`" + loc.LeftColumn + "`"
} else if loc.LeftType == "column" {
left = "`" + loc.LeftColumn + "`"
} else {
left = loc.LeftColumn
} }
if loc.RightType == "column" {
rquote = "`" if loc.RightTable != "" {
right = "`" + loc.RightTable + "`.`" + loc.RightColumn + "`"
} else if loc.RightType == "column" {
right = "`" + loc.RightColumn + "`"
} else {
right = loc.RightColumn
} }
querystr += " " + lquote + loc.Left + lquote + " " + loc.Operator + " " + rquote + loc.Right + rquote + " AND "
querystr += " " + left + " " + loc.Operator + " " + right + " AND "
} }
querystr = querystr[0:len(querystr) - 3] querystr = querystr[0:len(querystr) - 4]
} }
if len(orderby) != 0 { if len(orderby) != 0 {
@ -198,6 +208,7 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
func (adapter *Mysql_Adapter) write() error { func (adapter *Mysql_Adapter) write() error {
out := `/* This file was generated by Gosora's Query Generator */ out := `/* This file was generated by Gosora's Query Generator */
// +build !pgsql !sqlite !mssql
package main package main
import "log" import "log"

View File

@ -487,7 +487,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
} }
// Get the replies.. // Get the replies..
rows, err := db.Query("select users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group from users_replies left join users ON users_replies.createdBy = users.uid where users_replies.uid = ?", puser.ID) rows, err := get_profile_replies_stmt.Query(puser.ID)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -765,9 +765,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
var words int var words, fid, createdBy int
var fid int
var createdBy int
err = db.QueryRow("select parentID, words, createdBy from topics where tid = ?", tid).Scan(&fid,&words,&createdBy) err = db.QueryRow("select parentID, words, createdBy from topics where tid = ?", tid).Scan(&fid,&words,&createdBy)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreError("The requested topic doesn't exist.",w,r) PreError("The requested topic doesn't exist.",w,r)
@ -786,7 +784,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
err = db.QueryRow("select targetItem from likes where sentBy = ? and targetItem = ? and targetType = 'topics'", user.ID, tid).Scan(&tid) err = has_liked_topic_stmt.QueryRow(user.ID, tid).Scan(&tid)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -866,9 +864,7 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
return return
} }
var tid int var tid, words, createdBy int
var words int
var createdBy int
err = db.QueryRow("select tid, words, createdBy from replies where rid = ?", rid).Scan(&tid, &words, &createdBy) err = db.QueryRow("select tid, words, createdBy from replies where rid = ?", rid).Scan(&tid, &words, &createdBy)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreError("You can't like something which doesn't exist!",w,r) PreError("You can't like something which doesn't exist!",w,r)
@ -879,7 +875,7 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
} }
var fid int var fid int
err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid) err = get_topic_fid_stmt.QueryRow(tid).Scan(&fid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
PreError("The parent topic doesn't exist.",w,r) PreError("The parent topic doesn't exist.",w,r)
return return

View File

@ -91,6 +91,7 @@ type TopicStore interface {
Get(id int) (*Topic, error) Get(id int) (*Topic, error)
GetUnsafe(id int) (*Topic, error) GetUnsafe(id int) (*Topic, error)
CascadeGet(id int) (*Topic, error) CascadeGet(id int) (*Topic, error)
BypassGet(id int) (*Topic, error)
Set(item *Topic) error Set(item *Topic) error
Add(item *Topic) error Add(item *Topic) error
AddUnsafe(item *Topic) error AddUnsafe(item *Topic) error
@ -146,6 +147,12 @@ func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
return topic, err return topic, err
} }
func (sts *StaticTopicStore) BypassGet(id int) (*Topic, error) {
topic := &Topic{ID:id}
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)
return topic, err
}
func (sts *StaticTopicStore) Load(id int) error { func (sts *StaticTopicStore) Load(id int) error {
topic := &Topic{ID:id} topic := &Topic{ID:id}
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount) err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)
@ -254,6 +261,12 @@ func (sus *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
return &topic, err return &topic, err
} }
func (sts *SqlTopicStore) BypassGet(id int) (*Topic, error) {
topic := &Topic{ID:id}
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)
return topic, err
}
func (sus *SqlTopicStore) Load(id int) error { func (sus *SqlTopicStore) Load(id int) error {
topic := Topic{ID:id} topic := Topic{ID:id}
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount) err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)

67
user.go
View File

@ -54,6 +54,7 @@ type UserStore interface {
Get(id int) (*User, error) Get(id int) (*User, error)
GetUnsafe(id int) (*User, error) GetUnsafe(id int) (*User, error)
CascadeGet(id int) (*User, error) CascadeGet(id int) (*User, error)
BypassGet(id int) (*User, error)
Set(item *User) error Set(item *User) error
Add(item *User) error Add(item *User) error
AddUnsafe(item *User) error AddUnsafe(item *User) error
@ -101,10 +102,10 @@ func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
if ok { if ok {
return user, nil return user, nil
} }
user = &User{ID:id,Loggedin:true} user = &User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" { if user.Avatar != "" {
if user.Avatar[0] == '.' { if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
@ -120,6 +121,22 @@ func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
return user, err return user, err
} }
func (sts *StaticUserStore) BypassGet(id int) (*User, error) {
user := &User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" {
if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
}
} else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
}
user.Tag = groups[user.Group].Tag
init_user_perms(user)
return user, err
}
func (sts *StaticUserStore) Load(id int) error { func (sts *StaticUserStore) Load(id int) error {
user := &User{ID:id,Loggedin:true} user := &User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
@ -127,7 +144,7 @@ func (sts *StaticUserStore) Load(id int) error {
sts.Remove(id) sts.Remove(id)
return err return err
} }
if user.Avatar != "" { if user.Avatar != "" {
if user.Avatar[0] == '.' { if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
@ -230,7 +247,7 @@ func NewSqlUserStore() *SqlUserStore {
func (sus *SqlUserStore) Get(id int) (*User, error) { func (sus *SqlUserStore) Get(id int) (*User, error) {
user := User{ID:id,Loggedin:true} user := User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" { if user.Avatar != "" {
if user.Avatar[0] == '.' { if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
@ -246,7 +263,7 @@ func (sus *SqlUserStore) Get(id int) (*User, error) {
func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) { func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) {
user := User{ID:id,Loggedin:true} user := User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" { if user.Avatar != "" {
if user.Avatar[0] == '.' { if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
@ -262,7 +279,23 @@ func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) {
func (sus *SqlUserStore) CascadeGet(id int) (*User, error) { func (sus *SqlUserStore) CascadeGet(id int) (*User, error) {
user := User{ID:id,Loggedin:true} user := User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" {
if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
}
} else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
}
user.Tag = groups[user.Group].Tag
init_user_perms(&user)
return &user, err
}
func (sus *SqlUserStore) BypassGet(id int) (*User, error) {
user := User{ID:id,Loggedin:true}
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if user.Avatar != "" { if user.Avatar != "" {
if user.Avatar[0] == '.' { if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
@ -312,13 +345,13 @@ func SetPassword(uid int, password string) (error) {
if err != nil { if err != nil {
return err return err
} }
password = password + salt password = password + salt
hashed_password, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) hashed_password, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil { if err != nil {
return err return err
} }
_, err = set_password_stmt.Exec(string(hashed_password), salt, uid) _, err = set_password_stmt.Exec(string(hashed_password), salt, uid)
if err != nil { if err != nil {
return err return err
@ -331,10 +364,10 @@ func SendValidationEmail(username string, email string, token string) bool {
if enable_ssl { if enable_ssl {
schema = "s" schema = "s"
} }
subject := "Validate Your Email @ " + site_name subject := "Validate Your Email @ " + site_name
msg := "Dear " + username + ", following your registration on our forums, we ask you to validate your email, so that we can confirm that this email actually belongs to you.\n\nClick on the following link to do so. http" + schema + "://" + site_url + "/user/edit/token/" + token + "\n\nIf you haven't created an account here, then please feel free to ignore this email.\nWe're sorry for the inconvenience this may have caused." msg := "Dear " + username + ", following your registration on our forums, we ask you to validate your email, so that we can confirm that this email actually belongs to you.\n\nClick on the following link to do so. http" + schema + "://" + site_url + "/user/edit/token/" + token + "\n\nIf you haven't created an account here, then please feel free to ignore this email.\nWe're sorry for the inconvenience this may have caused."
return SendEmail(email, subject, msg) return SendEmail(email, subject, msg)
} }
@ -409,7 +442,7 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) {
if err != nil { if err != nil {
return guest_user, true return guest_user, true
} }
// Is this session valid..? // Is this session valid..?
user, err := users.CascadeGet(uid) user, err := users.CascadeGet(uid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -418,17 +451,17 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) {
InternalError(err,w,r) InternalError(err,w,r)
return guest_user, false return guest_user, false
} }
if user.Session == "" || cookie.Value != user.Session { if user.Session == "" || cookie.Value != user.Session {
return guest_user, true return guest_user, true
} }
if user.Is_Super_Admin { if user.Is_Super_Admin {
user.Perms = AllPerms user.Perms = AllPerms
} else { } else {
user.Perms = groups[user.Group].Perms user.Perms = groups[user.Group].Perms
} }
host, _, err := net.SplitHostPort(r.RemoteAddr) host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
PreError("Bad IP",w,r) PreError("Bad IP",w,r)
@ -450,7 +483,7 @@ func words_to_score(wcount int, topic bool) (score int) {
} else { } else {
score = 1 score = 1
} }
if wcount > settings["megapost_min_chars"].(int) { if wcount > settings["megapost_min_chars"].(int) {
score += 4 score += 4
} else if wcount > settings["bigpost_min_chars"].(int) { } else if wcount > settings["bigpost_min_chars"].(int) {
@ -469,7 +502,7 @@ func increase_post_user_stats(wcount int, uid int, topic bool, user User) error
} }
base_score = 2 base_score = 2
} }
if wcount > settings["megapost_min_chars"].(int) { if wcount > settings["megapost_min_chars"].(int) {
_, err := increment_user_megaposts_stmt.Exec(1,1,1,uid) _, err := increment_user_megaposts_stmt.Exec(1,1,1,uid)
if err != nil { if err != nil {
@ -508,7 +541,7 @@ func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error
} }
base_score = -2 base_score = -2
} }
if wcount > settings["megapost_min_chars"].(int) { if wcount > settings["megapost_min_chars"].(int) {
_, err := increment_user_megaposts_stmt.Exec(-1,-1,-1,uid) _, err := increment_user_megaposts_stmt.Exec(-1,-1,-1,uid)
if err != nil { if err != nil {