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)
GetUnsafe(id int) (interface{}, error)
CascadeGet(id int) (interface{}, error)
BypassGet(id int) (interface{}, error)
Set(item interface{}) error
Add(item interface{}) error
AddUnsafe(item interface{}) error

View File

@ -1,4 +1,5 @@
/* This file was generated by Gosora's Query Generator */
// +build !pgsql !sqlite !mssql
package main
import "log"
@ -15,7 +16,20 @@ var get_settings_stmt *sql.Stmt
var get_setting_stmt *sql.Stmt
var get_full_setting_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_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) {
if debug {
@ -88,11 +102,89 @@ func gen_mysql() (err error) {
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.")
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 {
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
}

View File

@ -1,7 +1,7 @@
package main
import (
"log"
// "log"
// "fmt"
"strconv"
"net"
@ -152,13 +152,15 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
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)
if err != nil {
InternalError(err,w,r)
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)
wcount := word_count(content)
@ -208,7 +210,6 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
return
}
//topic.Sticky = true
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
@ -264,7 +265,6 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
return
}
//topic.Sticky = false
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
@ -316,14 +316,14 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
// Get the Reply ID..
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 {
InternalErrorJSQ(err,w,r,is_js)
return
}
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 {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return
@ -377,7 +377,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
}
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 {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return
@ -400,7 +400,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js)
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" {
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
} else {
@ -460,7 +460,7 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
// Get the Reply ID..
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 {
InternalErrorJSQ(err,w,r,is_js)
return
@ -508,7 +508,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
}
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 {
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
return
@ -527,7 +527,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalErrorJSQ(err,w,r,is_js)
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" {
//http.Redirect(w,r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)

View File

@ -1,4 +1,5 @@
/* Copyright Azareal 2016 - 2017 */
// +build !pgsql !sqlite !mssql
package main
import "database/sql"
@ -12,13 +13,8 @@ var db *sql.DB
var db_version string
var db_collation string = "utf8mb4_general_ci"
var get_topic_user_stmt *sql.Stmt
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_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_forum_topics_offset_stmt *sql.Stmt
var create_topic_stmt *sql.Stmt
var create_report_stmt *sql.Stmt
var create_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 add_modlog_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) {
if(dbpassword != ""){
@ -118,48 +118,18 @@ func init_database() (err error) {
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.")
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 {
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.")
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 {
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.")
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 {
@ -560,6 +530,30 @@ func init_database() (err error) {
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.")
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
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 {
InternalError(err,w,r)
return
@ -98,7 +98,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
}
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 {
InternalError(err,w,r)
return
@ -115,7 +115,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
}
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 {
InternalError(err,w,r)
return
@ -123,7 +123,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var reportInterval string = "week"
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 {
InternalError(err,w,r)
return
@ -770,7 +770,7 @@ func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request, unam
}
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 {
LocalError("The plugin you're trying to deactivate isn't active",w,r,user)
return
@ -807,7 +807,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
}
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 {
InternalError(err,w,r)
return
@ -1481,7 +1481,7 @@ func route_panel_themes_default(w http.ResponseWriter, r *http.Request, uname st
}
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 {
InternalError(err,w,r)
return
@ -1542,7 +1542,7 @@ func route_panel_logs_mod(w http.ResponseWriter, r *http.Request){
return
}
rows, err := db.Query("select action, elementID, elementType, ipaddress, actorID, doneAt from moderation_logs")
rows, err := get_modlogs_stmt.Query()
if err != nil {
InternalError(err,w,r)
return

View File

@ -1,7 +1,7 @@
/* WIP Under Construction */
package main
//import "fmt"
import "fmt"
import "strings"
import "log"
import "os"
@ -17,10 +17,18 @@ type DB_Column struct
Type string // function or column
}
type DB_Field struct
{
Name string
Type string
}
type DB_Where struct
{
Left string
Right string
LeftTable string
LeftColumn string
RightTable string
RightColumn string
Operator string
LeftType string
RightType string
@ -42,8 +50,8 @@ type DB_Order struct
type DB_Adapter interface {
get_name() string
simple_insert(string,string,string,[]string,[]bool) error
//simple_replace(string,string,[]string,[]string,[]bool) error
simple_insert(string,string,string,string) error
//simple_replace(string,string,[]string,string) error
simple_update() error
simple_select(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("get_settings","settings","name, content, type","","")
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("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_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
}
@ -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
var outwhere DB_Where
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.Right, parseOffset = _get_identifier(segment, parseOffset + 1)
outwhere.LeftType = _get_identifier_type(outwhere.Left)
outwhere.RightType = _get_identifier_type(outwhere.Right)
right, parseOffset = _get_identifier(segment, parseOffset + 1)
outwhere.LeftType = _get_identifier_type(left)
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)
}
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 {
if ('a' <= identifier[0] && identifier[0] <= 'z') || ('A' <= identifier[0] && identifier[0] <= 'Z') {
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)
}
func _skip_function_call(segment string, i int) int {
var brace_count int = 1
for ; i < len(segment); i++ {
if segment[i] == '(' {
func _skip_function_call(data string, index int) int {
var brace_count int
for ;index < len(data); index++{
char := data[index]
if char == '(' {
fmt.Println("Enter brace")
brace_count++
} else if segment[i] == ')' {
} else if char == ')' {
brace_count--
}
if brace_count == 0 {
return i
fmt.Println("Exit brace")
if brace_count == 0 {
fmt.Println("Exit function segment")
return index
}
}
}
return i
return index
}
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
}
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 == "" {
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")
}
// 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 + "("
// 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 colslice {
querystr += "`" + column + "`,"
for _, column := range _process_columns(columns) {
if column.Type == "function" {
querystr += column.Left + ","
} else {
querystr += "`" + column.Left + "`,"
}
}
// Remove the trailing comma
querystr = querystr[0:len(querystr) - 1]
querystr += ") VALUES ("
for fid, field := range fields {
if !noquotes && quoteWhat[fid] {
querystr += "'" + field + "',"
} else {
querystr += field + ","
}
for _, field := range _process_fields(fields) {
querystr += field.Name + ","
}
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
if len(where) != 0 {
querystr += " WHERE"
//fmt.Println("where",where)
//fmt.Println("_process_where(where)",_process_where(where))
querystr += " " + "WHERE"
for _, loc := range _process_where(where) {
var lquote, rquote string
var left, right string
if loc.LeftType == "column" {
lquote = "`"
left = "`" + loc.LeftColumn + "`"
} else {
left = loc.LeftColumn
}
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]
}
@ -172,16 +171,27 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
if len(where) != 0 {
querystr += " " + "WHERE"
for _, loc := range _process_where(where) {
var lquote, rquote string
if loc.LeftType == "column" {
lquote = "`"
var left, right string
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 {
@ -198,6 +208,7 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
func (adapter *Mysql_Adapter) write() error {
out := `/* This file was generated by Gosora's Query Generator */
// +build !pgsql !sqlite !mssql
package main
import "log"

View File

@ -487,7 +487,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
}
// 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 {
InternalError(err,w,r)
return
@ -765,9 +765,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
return
}
var words int
var fid int
var createdBy int
var words, fid, createdBy int
err = db.QueryRow("select parentID, words, createdBy from topics where tid = ?", tid).Scan(&fid,&words,&createdBy)
if err == sql.ErrNoRows {
PreError("The requested topic doesn't exist.",w,r)
@ -786,7 +784,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
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 {
InternalError(err,w,r)
return
@ -866,9 +864,7 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
return
}
var tid int
var words int
var createdBy int
var tid, words, createdBy int
err = db.QueryRow("select tid, words, createdBy from replies where rid = ?", rid).Scan(&tid, &words, &createdBy)
if err == sql.ErrNoRows {
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
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 {
PreError("The parent topic doesn't exist.",w,r)
return

View File

@ -91,6 +91,7 @@ type TopicStore interface {
Get(id int) (*Topic, error)
GetUnsafe(id int) (*Topic, error)
CascadeGet(id int) (*Topic, error)
BypassGet(id int) (*Topic, error)
Set(item *Topic) error
Add(item *Topic) error
AddUnsafe(item *Topic) error
@ -146,6 +147,12 @@ func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
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 {
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)
@ -254,6 +261,12 @@ func (sus *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
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 {
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)

33
user.go
View File

@ -54,6 +54,7 @@ type UserStore interface {
Get(id int) (*User, error)
GetUnsafe(id int) (*User, error)
CascadeGet(id int) (*User, error)
BypassGet(id int) (*User, error)
Set(item *User) error
Add(item *User) error
AddUnsafe(item *User) error
@ -120,6 +121,22 @@ func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
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 {
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)
@ -275,6 +292,22 @@ func (sus *SqlUserStore) CascadeGet(id int) (*User, error) {
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[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) Load(id int) error {
user := &User{ID:id}
// Simplify this into a quick check whether the user exists