Added support for offsets and max counts to the query generator.
Early draft of the ForumStore. Not much to see here yet! Fixed a race condition in forum creation. Fixed a race condition in group creation. Fixed a race condition in forum deletion. Moved four queries to the query generator. Renamed StaticTopicStore to MemoryTopicStore. Renamed StaticUserStore to MemoryUserStore. SimpleSessionCheck is now pluggable. We no longer have any raw queries outside mysql.go or the query generator, yay.
This commit is contained in:
parent
8c1d8d5c64
commit
1ccd4479ae
|
@ -3,6 +3,11 @@ package main
|
||||||
import "log"
|
import "log"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
import "database/sql"
|
||||||
|
|
||||||
|
var db *sql.DB
|
||||||
|
var db_version string
|
||||||
|
var db_collation string = "utf8mb4_general_ci"
|
||||||
|
|
||||||
func init_database() (err error) {
|
func init_database() (err error) {
|
||||||
// Engine specific code
|
// Engine specific code
|
||||||
|
@ -66,6 +71,7 @@ func init_database() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fstore = NewStaticForumStore()
|
||||||
|
|
||||||
log.Print("Loading the settings.")
|
log.Print("Loading the settings.")
|
||||||
err = LoadSettings()
|
err = LoadSettings()
|
||||||
|
|
15
forum.go
15
forum.go
|
@ -41,16 +41,6 @@ type ForumSimple struct
|
||||||
Preset string
|
Preset string
|
||||||
}
|
}
|
||||||
|
|
||||||
/*type ForumStore interface
|
|
||||||
{
|
|
||||||
Get(int) (*Forum, error)
|
|
||||||
CascadeGet(int) (*Forum, error)
|
|
||||||
Update(Forum) error
|
|
||||||
CascadeUpdate(Forum) error
|
|
||||||
Delete(int) error
|
|
||||||
CascadeDelete(int) error
|
|
||||||
}*/
|
|
||||||
|
|
||||||
func LoadForums() error {
|
func LoadForums() error {
|
||||||
//if debug {
|
//if debug {
|
||||||
log.Print("Adding the uncategorised forum")
|
log.Print("Adding the uncategorised forum")
|
||||||
|
@ -95,6 +85,7 @@ func LoadForums() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var forum_update_mutex sync.Mutex
|
var forum_update_mutex sync.Mutex
|
||||||
|
var forum_create_mutex sync.Mutex
|
||||||
func create_forum(forum_name string, forum_desc string, active bool, preset string) (int, error) {
|
func create_forum(forum_name string, forum_desc string, active bool, preset string) (int, error) {
|
||||||
var fid int
|
var fid int
|
||||||
err := forum_entry_exists_stmt.QueryRow().Scan(&fid)
|
err := forum_entry_exists_stmt.QueryRow().Scan(&fid)
|
||||||
|
@ -115,6 +106,7 @@ func create_forum(forum_name string, forum_desc string, active bool, preset stri
|
||||||
return fid, nil
|
return fid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forum_create_mutex.Lock()
|
||||||
res, err := create_forum_stmt.Exec(forum_name, forum_desc, active, preset)
|
res, err := create_forum_stmt.Exec(forum_name, forum_desc, active, preset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -127,15 +119,18 @@ func create_forum(forum_name string, forum_desc string, active bool, preset stri
|
||||||
fid = int(fid64)
|
fid = int(fid64)
|
||||||
|
|
||||||
forums = append(forums, Forum{fid,forum_name,forum_desc,active,preset,0,"",0,"",0,""})
|
forums = append(forums, Forum{fid,forum_name,forum_desc,active,preset,0,"",0,"",0,""})
|
||||||
|
forum_create_mutex.Unlock()
|
||||||
return fid, nil
|
return fid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func delete_forum(fid int) error {
|
func delete_forum(fid int) error {
|
||||||
|
forum_update_mutex.Lock()
|
||||||
_, err := delete_forum_stmt.Exec(fid)
|
_, err := delete_forum_stmt.Exec(fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
forums[fid].Name = ""
|
forums[fid].Name = ""
|
||||||
|
forum_update_mutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Work in progress. Check back later! */
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
import "errors"
|
||||||
|
import "database/sql"
|
||||||
|
import "./query_gen/lib"
|
||||||
|
|
||||||
|
var err_noforum = errors.New("This forum doesn't exist")
|
||||||
|
|
||||||
|
type ForumStore interface
|
||||||
|
{
|
||||||
|
Get(int) (*Forum, error)
|
||||||
|
CascadeGet(int) (*Forum, error)
|
||||||
|
BypassGet(int) (*Forum, error)
|
||||||
|
//Update(Forum) error
|
||||||
|
//CascadeUpdate(Forum) error
|
||||||
|
//Delete(int) error
|
||||||
|
//CascadeDelete(int) error
|
||||||
|
//QuickCreate(string, string, bool, string) (*Forum, error)
|
||||||
|
Exists(int) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaticForumStore struct
|
||||||
|
{
|
||||||
|
get *sql.Stmt
|
||||||
|
get_all *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStaticForumStore() *StaticForumStore {
|
||||||
|
get_stmt, err := qgen.Builder.SimpleSelect("forums","name, desc, active, preset, topicCount, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime","fid = ?","","")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
get_all_stmt, err := qgen.Builder.SimpleSelect("forums","fid, name, desc, active, preset, topicCount, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime","","fid ASC","")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return &StaticForumStore{
|
||||||
|
get: get_stmt,
|
||||||
|
get_all: get_all_stmt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sfs *StaticForumStore) Get(id int) (*Forum, error) {
|
||||||
|
if !((id <= forumCapCount) && (id >= 0) && forums[id].Name!="") {
|
||||||
|
return nil, err_noforum
|
||||||
|
}
|
||||||
|
return &forums[id], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sfs *StaticForumStore) CascadeGet(id int) (*Forum, error) {
|
||||||
|
if !((id <= forumCapCount) && (id >= 0) && forums[id].Name!="") {
|
||||||
|
return nil, err_noforum
|
||||||
|
}
|
||||||
|
return &forums[id], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sfs *StaticForumStore) BypassGet(id int) (*Forum, error) {
|
||||||
|
var forum Forum = Forum{ID:id}
|
||||||
|
err := sfs.get.QueryRow(id).Scan(&forum.Name, &forum.Desc, &forum.Active, &forum.Preset, &forum.TopicCount, &forum.LastTopic, &forum.LastTopicID, &forum.LastReplyer, &forum.LastReplyerID, &forum.LastTopicTime)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &forum, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sfs *StaticForumStore) Exists(id int) bool {
|
||||||
|
return (id <= forumCapCount) && (id >= 0) && forums[id].Name != ""
|
||||||
|
}
|
28
gen_mysql.go
28
gen_mysql.go
|
@ -37,6 +37,10 @@ var get_user_group_stmt *sql.Stmt
|
||||||
var get_emails_by_user_stmt *sql.Stmt
|
var get_emails_by_user_stmt *sql.Stmt
|
||||||
var get_topic_basic_stmt *sql.Stmt
|
var get_topic_basic_stmt *sql.Stmt
|
||||||
var get_activity_entry_stmt *sql.Stmt
|
var get_activity_entry_stmt *sql.Stmt
|
||||||
|
var forum_entry_exists_stmt *sql.Stmt
|
||||||
|
var group_entry_exists_stmt *sql.Stmt
|
||||||
|
var get_topic_replies_offset_stmt *sql.Stmt
|
||||||
|
var get_forum_topics_offset_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_user_stmt *sql.Stmt
|
||||||
var get_topic_by_reply_stmt *sql.Stmt
|
var get_topic_by_reply_stmt *sql.Stmt
|
||||||
|
@ -297,6 +301,30 @@ func gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing forum_entry_exists statement.")
|
||||||
|
forum_entry_exists_stmt, err = db.Prepare("SELECT `fid` FROM `forums` WHERE `name` = '' ORDER BY fid ASC LIMIT 0,1")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing group_entry_exists statement.")
|
||||||
|
group_entry_exists_stmt, err = db.Prepare("SELECT `gid` FROM `users_groups` WHERE `name` = '' ORDER BY gid ASC LIMIT 0,1")
|
||||||
|
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 ?,?")
|
||||||
|
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 ?,?")
|
||||||
|
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 {
|
||||||
|
|
|
@ -55,8 +55,8 @@ func gloinit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cache_topicuser == CACHE_STATIC {
|
if cache_topicuser == CACHE_STATIC {
|
||||||
users = NewStaticUserStore(user_cache_capacity)
|
users = NewMemoryUserStore(user_cache_capacity)
|
||||||
topics = NewStaticTopicStore(topic_cache_capacity)
|
topics = NewMemoryTopicStore(topic_cache_capacity)
|
||||||
} else {
|
} else {
|
||||||
users = NewSqlUserStore()
|
users = NewSqlUserStore()
|
||||||
topics = NewSqlTopicStore()
|
topics = NewSqlTopicStore()
|
||||||
|
|
3
group.go
3
group.go
|
@ -31,6 +31,7 @@ type Group struct
|
||||||
CanSee []int // The IDs of the forums this group can see
|
CanSee []int // The IDs of the forums this group can see
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var group_create_mutex sync.Mutex
|
||||||
func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_banned bool) (int, error) {
|
func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_banned bool) (int, error) {
|
||||||
var gid int
|
var gid int
|
||||||
err := group_entry_exists_stmt.QueryRow().Scan(&gid)
|
err := group_entry_exists_stmt.QueryRow().Scan(&gid)
|
||||||
|
@ -58,6 +59,7 @@ func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_
|
||||||
return gid, nil
|
return gid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_create_mutex.Lock()
|
||||||
var permstr string = "{}"
|
var permstr string = "{}"
|
||||||
res, err := create_group_stmt.Exec(group_name, tag, is_admin, is_mod, is_banned, permstr)
|
res, err := create_group_stmt.Exec(group_name, tag, is_admin, is_mod, is_banned, permstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -73,6 +75,7 @@ func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_
|
||||||
var blankForums []ForumPerms
|
var blankForums []ForumPerms
|
||||||
var blankIntList []int
|
var blankIntList []int
|
||||||
groups = append(groups, Group{gid,group_name,is_mod,is_admin,is_banned,tag,perms,[]byte(permstr),blankForums,blankIntList})
|
groups = append(groups, Group{gid,group_name,is_mod,is_admin,is_banned,tag,perms,[]byte(permstr),blankForums,blankIntList})
|
||||||
|
group_create_mutex.Unlock()
|
||||||
|
|
||||||
// Generate the forum permissions based on the presets...
|
// Generate the forum permissions based on the presets...
|
||||||
fdata := forums
|
fdata := forums
|
||||||
|
|
5
main.go
5
main.go
|
@ -43,6 +43,7 @@ var external_sites map[string]string = make(map[string]string)
|
||||||
var groups []Group
|
var groups []Group
|
||||||
var forums []Forum // The IDs for a forum tend to be low and sequential for the most part, so we can get more performance out of using a slice instead of a map AND it has better concurrency
|
var forums []Forum // The IDs for a forum tend to be low and sequential for the most part, so we can get more performance out of using a slice instead of a map AND it has better concurrency
|
||||||
var forum_perms map[int]map[int]ForumPerms // [gid][fid]Perms
|
var forum_perms map[int]map[int]ForumPerms // [gid][fid]Perms
|
||||||
|
var fstore ForumStore // :soon:
|
||||||
var groupCapCount, forumCapCount int
|
var groupCapCount, forumCapCount int
|
||||||
var static_files map[string]SFile = make(map[string]SFile)
|
var static_files map[string]SFile = make(map[string]SFile)
|
||||||
|
|
||||||
|
@ -185,8 +186,8 @@ func main(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if cache_topicuser == CACHE_STATIC {
|
if cache_topicuser == CACHE_STATIC {
|
||||||
users = NewStaticUserStore(user_cache_capacity)
|
users = NewMemoryUserStore(user_cache_capacity)
|
||||||
topics = NewStaticTopicStore(topic_cache_capacity)
|
topics = NewMemoryTopicStore(topic_cache_capacity)
|
||||||
} else {
|
} else {
|
||||||
users = NewSqlUserStore()
|
users = NewSqlUserStore()
|
||||||
topics = NewSqlTopicStore()
|
topics = NewSqlTopicStore()
|
||||||
|
|
40
mysql.go
40
mysql.go
|
@ -3,23 +3,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "strconv"
|
import "strings"
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
import _ "github.com/go-sql-driver/mysql"
|
import _ "github.com/go-sql-driver/mysql"
|
||||||
import "./query_gen/lib"
|
import "./query_gen/lib"
|
||||||
|
|
||||||
var db *sql.DB
|
|
||||||
var db_version string
|
|
||||||
var db_collation string = "utf8mb4_general_ci"
|
|
||||||
|
|
||||||
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 notify_watchers_stmt *sql.Stmt
|
var notify_watchers_stmt *sql.Stmt
|
||||||
var get_activity_feed_by_watcher_stmt *sql.Stmt
|
var get_activity_feed_by_watcher_stmt *sql.Stmt
|
||||||
var get_activity_count_by_watcher_stmt *sql.Stmt
|
var get_activity_count_by_watcher_stmt *sql.Stmt
|
||||||
|
|
||||||
var forum_entry_exists_stmt *sql.Stmt
|
|
||||||
var group_entry_exists_stmt *sql.Stmt
|
|
||||||
var add_forum_perms_to_forum_admins_stmt *sql.Stmt
|
var add_forum_perms_to_forum_admins_stmt *sql.Stmt
|
||||||
var add_forum_perms_to_forum_staff_stmt *sql.Stmt
|
var add_forum_perms_to_forum_staff_stmt *sql.Stmt
|
||||||
var add_forum_perms_to_forum_members_stmt *sql.Stmt
|
var add_forum_perms_to_forum_members_stmt *sql.Stmt
|
||||||
|
@ -65,18 +56,6 @@ func _init_database() (err error) {
|
||||||
return err
|
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_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 notify_watchers statement.")
|
log.Print("Preparing notify_watchers statement.")
|
||||||
notify_watchers_stmt, err = db.Prepare("INSERT INTO activity_stream_matches(watcher, asid) SELECT activity_subscriptions.user, activity_stream.asid FROM activity_stream INNER JOIN activity_subscriptions ON activity_subscriptions.targetType = activity_stream.elementType and activity_subscriptions.targetID = activity_stream.elementID and activity_subscriptions.user != activity_stream.actor where asid = ?")
|
notify_watchers_stmt, err = db.Prepare("INSERT INTO activity_stream_matches(watcher, asid) SELECT activity_subscriptions.user, activity_stream.asid FROM activity_stream INNER JOIN activity_subscriptions ON activity_subscriptions.targetType = activity_stream.elementType and activity_subscriptions.targetID = activity_stream.elementID and activity_subscriptions.user != activity_stream.actor where asid = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -95,18 +74,6 @@ func _init_database() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing forum_entry_exists statement.")
|
|
||||||
forum_entry_exists_stmt, err = db.Prepare("SELECT `fid` FROM `forums` WHERE `name` = '' order by fid asc limit 1")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing group_entry_exists statement.")
|
|
||||||
group_entry_exists_stmt, err = db.Prepare("SELECT `gid` FROM `users_groups` WHERE `name` = '' order by gid asc limit 1")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing add_forum_perms_to_forum_admins statement.")
|
log.Print("Preparing add_forum_perms_to_forum_admins statement.")
|
||||||
add_forum_perms_to_forum_admins_stmt, err = db.Prepare("INSERT INTO forums_permissions(gid,fid,preset,permissions) SELECT `gid`,? AS fid,? AS preset,? AS permissions FROM users_groups WHERE is_admin = 1")
|
add_forum_perms_to_forum_admins_stmt, err = db.Prepare("INSERT INTO forums_permissions(gid,fid,preset,permissions) SELECT `gid`,? AS fid,? AS preset,? AS permissions FROM users_groups WHERE is_admin = 1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -151,3 +118,8 @@ func _init_database() (err error) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporary hack so that we can move all the raw queries out of the other files and into here
|
||||||
|
func topic_list_query(visible_fids []string) string {
|
||||||
|
return "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 parentID in("+strings.Join(visible_fids,",")+") order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC"
|
||||||
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ func (build *builder) SetAdapter(name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *builder) SimpleSelect(table string, columns string, where string, orderby string/*, offset int, maxCount int*/) (stmt *sql.Stmt, err error) {
|
func (build *builder) SimpleSelect(table string, columns string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleSelect("_builder", table, columns, where, orderby /*, offset, maxCount*/)
|
res, err := build.adapter.SimpleSelect("_builder", table, columns, where, orderby, limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stmt, err
|
return stmt, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type Mysql_Adapter struct
|
type Mysql_Adapter struct
|
||||||
{
|
{
|
||||||
Name string
|
Name string
|
||||||
|
@ -210,7 +208,7 @@ func (adapter *Mysql_Adapter) Purge(name string, table string) (string, error) {
|
||||||
return "DELETE FROM `" + table + "`", nil
|
return "DELETE FROM `" + table + "`", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (adapter *Mysql_Adapter) SimpleSelect(name string, table string, columns string, where string, orderby string/*, offset int, maxCount int*/) (string, error) {
|
func (adapter *Mysql_Adapter) SimpleSelect(name string, table string, columns string, where string, orderby string, limit string) (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")
|
||||||
}
|
}
|
||||||
|
@ -264,12 +262,16 @@ func (adapter *Mysql_Adapter) SimpleSelect(name string, table string, columns st
|
||||||
querystr = querystr[0:len(querystr) - 1]
|
querystr = querystr[0:len(querystr) - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if limit != "" {
|
||||||
|
querystr += " LIMIT " + limit
|
||||||
|
}
|
||||||
|
|
||||||
querystr = strings.TrimSpace(querystr)
|
querystr = strings.TrimSpace(querystr)
|
||||||
adapter.push_statement(name,querystr)
|
adapter.push_statement(name,querystr)
|
||||||
return querystr, nil
|
return querystr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (adapter *Mysql_Adapter) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) (string, error) {
|
func (adapter *Mysql_Adapter) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (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")
|
||||||
}
|
}
|
||||||
|
@ -350,12 +352,16 @@ func (adapter *Mysql_Adapter) SimpleLeftJoin(name string, table1 string, table2
|
||||||
querystr = querystr[0:len(querystr) - 1]
|
querystr = querystr[0:len(querystr) - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if limit != "" {
|
||||||
|
querystr += " LIMIT " + limit
|
||||||
|
}
|
||||||
|
|
||||||
querystr = strings.TrimSpace(querystr)
|
querystr = strings.TrimSpace(querystr)
|
||||||
adapter.push_statement(name,querystr)
|
adapter.push_statement(name,querystr)
|
||||||
return querystr, nil
|
return querystr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (adapter *Mysql_Adapter) SimpleInnerJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) (string, error) {
|
func (adapter *Mysql_Adapter) SimpleInnerJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (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")
|
||||||
}
|
}
|
||||||
|
@ -436,12 +442,16 @@ func (adapter *Mysql_Adapter) SimpleInnerJoin(name string, table1 string, table2
|
||||||
querystr = querystr[0:len(querystr) - 1]
|
querystr = querystr[0:len(querystr) - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if limit != "" {
|
||||||
|
querystr += " LIMIT " + limit
|
||||||
|
}
|
||||||
|
|
||||||
querystr = strings.TrimSpace(querystr)
|
querystr = strings.TrimSpace(querystr)
|
||||||
adapter.push_statement(name,querystr)
|
adapter.push_statement(name,querystr)
|
||||||
return querystr, nil
|
return querystr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (adapter *Mysql_Adapter) SimpleCount(name string, table string, where string/*, offset int, maxCount int*/) (string, error) {
|
func (adapter *Mysql_Adapter) SimpleCount(name string, table string, where string, limit string) (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")
|
||||||
}
|
}
|
||||||
|
@ -472,6 +482,10 @@ func (adapter *Mysql_Adapter) SimpleCount(name string, table string, where strin
|
||||||
querystr = querystr[0:len(querystr) - 4]
|
querystr = querystr[0:len(querystr) - 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if limit != "" {
|
||||||
|
querystr += " LIMIT " + limit
|
||||||
|
}
|
||||||
|
|
||||||
querystr = strings.TrimSpace(querystr)
|
querystr = strings.TrimSpace(querystr)
|
||||||
adapter.push_statement(name,querystr)
|
adapter.push_statement(name,querystr)
|
||||||
return querystr, nil
|
return querystr, nil
|
||||||
|
|
|
@ -56,6 +56,11 @@ type DB_Setter struct {
|
||||||
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now.
|
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DB_Limit struct {
|
||||||
|
Offset string // ? or int
|
||||||
|
MaxCount string // ? or int
|
||||||
|
}
|
||||||
|
|
||||||
type DB_Adapter interface {
|
type DB_Adapter interface {
|
||||||
GetName() string
|
GetName() string
|
||||||
SimpleInsert(string,string,string,string) (string, error)
|
SimpleInsert(string,string,string,string) (string, error)
|
||||||
|
@ -63,10 +68,10 @@ type DB_Adapter interface {
|
||||||
SimpleUpdate(string,string,string,string) (string, error)
|
SimpleUpdate(string,string,string,string) (string, error)
|
||||||
SimpleDelete(string,string,string) (string, error)
|
SimpleDelete(string,string,string) (string, error)
|
||||||
Purge(string,string) (string, error)
|
Purge(string,string) (string, error)
|
||||||
SimpleSelect(string,string,string,string,string/*,int,int*/) (string, error)
|
SimpleSelect(string,string,string,string,string,string) (string, error)
|
||||||
SimpleLeftJoin(string,string,string,string,string,string,string/*,int,int*/) (string, error)
|
SimpleLeftJoin(string,string,string,string,string,string,string,string) (string, error)
|
||||||
SimpleInnerJoin(string,string,string,string,string,string,string/*,int,int*/) (string, error)
|
SimpleInnerJoin(string,string,string,string,string,string,string,string) (string, error)
|
||||||
SimpleCount(string,string,string/*,int,int*/) (string, error)
|
SimpleCount(string,string,string,string) (string, error)
|
||||||
Write() error
|
Write() error
|
||||||
|
|
||||||
// TO-DO: Add a simple query builder
|
// TO-DO: Add a simple query builder
|
||||||
|
|
|
@ -243,6 +243,17 @@ func _process_set(setstr string) (setter []DB_Setter) {
|
||||||
return setter
|
return setter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _process_limit(limitstr string) (limiter DB_Limit) {
|
||||||
|
halves := strings.Split(limitstr,",")
|
||||||
|
if len(halves) == 2 {
|
||||||
|
limiter.Offset = halves[0]
|
||||||
|
limiter.MaxCount = halves[1]
|
||||||
|
} else {
|
||||||
|
limiter.MaxCount = halves[0]
|
||||||
|
}
|
||||||
|
return limiter
|
||||||
|
}
|
||||||
|
|
||||||
func _is_op_byte(char byte) bool {
|
func _is_op_byte(char byte) bool {
|
||||||
return char == '<' || char == '>' || char == '=' || char == '!' || char == '*' || char == '%' || char == '+' || char == '-' || char == '/'
|
return char == '<' || char == '>' || char == '=' || char == '!' || char == '*' || char == '%' || char == '+' || char == '-' || char == '/'
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,92 +51,100 @@ func write_statements(adapter qgen.DB_Adapter) error {
|
||||||
|
|
||||||
func write_selects(adapter qgen.DB_Adapter) error {
|
func write_selects(adapter qgen.DB_Adapter) error {
|
||||||
// url_prefix and url_name will be removed from this query in a later commit
|
// url_prefix and url_name will be removed from this query in a later commit
|
||||||
adapter.SimpleSelect("get_user","users","name, group, is_super_admin, avatar, message, url_prefix, url_name, level","uid = ?","")
|
adapter.SimpleSelect("get_user","users","name, group, is_super_admin, avatar, message, url_prefix, url_name, level","uid = ?","","")
|
||||||
|
|
||||||
// Looking for get_topic? Your statement is in another castle
|
// Looking for get_topic? Your statement is in another castle
|
||||||
|
|
||||||
adapter.SimpleSelect("get_reply","replies","tid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?","")
|
adapter.SimpleSelect("get_reply","replies","tid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_reply","users_replies","uid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress","rid = ?","")
|
adapter.SimpleSelect("get_user_reply","users_replies","uid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress","rid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("login","users","uid, name, password, salt","name = ?","")
|
adapter.SimpleSelect("login","users","uid, name, password, salt","name = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_password","users","password,salt","uid = ?","")
|
adapter.SimpleSelect("get_password","users","password,salt","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("username_exists","users","name","name = ?","")
|
adapter.SimpleSelect("username_exists","users","name","name = ?","","")
|
||||||
|
|
||||||
|
|
||||||
adapter.SimpleSelect("get_settings","settings","name, content, type","","")
|
adapter.SimpleSelect("get_settings","settings","name, content, type","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_setting","settings","content, type","name = ?","")
|
adapter.SimpleSelect("get_setting","settings","content, type","name = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_full_setting","settings","name, type, constraints","name = ?","")
|
adapter.SimpleSelect("get_full_setting","settings","name, type, constraints","name = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_full_settings","settings","name, content, type, constraints","","")
|
adapter.SimpleSelect("get_full_settings","settings","name, content, type, constraints","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_groups","users_groups","gid, name, permissions, is_mod, is_admin, is_banned, tag","","")
|
adapter.SimpleSelect("get_groups","users_groups","gid, name, permissions, is_mod, is_admin, is_banned, tag","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_forums","forums","fid, name, desc, active, preset, topicCount, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime","","fid ASC")
|
adapter.SimpleSelect("get_forums","forums","fid, name, desc, active, preset, topicCount, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime","","fid ASC","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_forums_permissions","forums_permissions","gid, fid, permissions","","gid ASC, fid ASC")
|
adapter.SimpleSelect("get_forums_permissions","forums_permissions","gid, fid, permissions","","gid ASC, fid ASC","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_plugins","plugins","uname, active","","")
|
adapter.SimpleSelect("get_plugins","plugins","uname, active","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_themes","themes","uname, default","","")
|
adapter.SimpleSelect("get_themes","themes","uname, default","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("is_plugin_active","plugins","active","uname = ?","")
|
adapter.SimpleSelect("is_plugin_active","plugins","active","uname = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_users","users","uid, name, group, active, is_super_admin, avatar","","")
|
adapter.SimpleSelect("get_users","users","uid, name, group, active, is_super_admin, avatar","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("is_theme_default","themes","default","uname = ?","")
|
adapter.SimpleSelect("is_theme_default","themes","default","uname = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_modlogs","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","","")
|
adapter.SimpleSelect("get_modlogs","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_reply_tid","replies","tid","rid = ?","")
|
adapter.SimpleSelect("get_reply_tid","replies","tid","rid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_topic_fid","topics","parentID","tid = ?","")
|
adapter.SimpleSelect("get_topic_fid","topics","parentID","tid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_reply_uid","users_replies","uid","rid = ?","")
|
adapter.SimpleSelect("get_user_reply_uid","users_replies","uid","rid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("has_liked_topic","likes","targetItem","sentBy = ? and targetItem = ? and targetType = 'topics'","")
|
adapter.SimpleSelect("has_liked_topic","likes","targetItem","sentBy = ? and targetItem = ? and targetType = 'topics'","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("has_liked_reply","likes","targetItem","sentBy = ? and targetItem = ? and targetType = 'replies'","")
|
adapter.SimpleSelect("has_liked_reply","likes","targetItem","sentBy = ? and targetItem = ? and targetType = 'replies'","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_name","users","name","uid = ?","")
|
adapter.SimpleSelect("get_user_name","users","name","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_rank","users","group, is_super_admin","uid = ?","")
|
adapter.SimpleSelect("get_user_rank","users","group, is_super_admin","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_active","users","active","uid = ?","")
|
adapter.SimpleSelect("get_user_active","users","active","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_user_group","users","group","uid = ?","")
|
adapter.SimpleSelect("get_user_group","users","group","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_emails_by_user","emails","email, validated, token","uid = ?","")
|
adapter.SimpleSelect("get_emails_by_user","emails","email, validated, token","uid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_topic_basic","topics","title, content","tid = ?","")
|
adapter.SimpleSelect("get_topic_basic","topics","title, content","tid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleSelect("get_activity_entry","activity_stream","actor, targetUser, event, elementType, elementID","asid = ?","")
|
adapter.SimpleSelect("get_activity_entry","activity_stream","actor, targetUser, event, elementType, elementID","asid = ?","","")
|
||||||
|
|
||||||
|
adapter.SimpleSelect("forum_entry_exists","forums","fid","name = ''","fid ASC","0,1") // Is '' empty?
|
||||||
|
|
||||||
|
adapter.SimpleSelect("group_entry_exists","users_groups","gid","name = ''","gid ASC","0,1") // Is '' empty?
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func write_left_joins(adapter qgen.DB_Adapter) error {
|
func write_left_joins(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleLeftJoin("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.SimpleLeftJoin("get_topic_replies_offset","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.likeCount, replies.actionType","replies.createdBy = users.uid","tid = ?","","?,?")
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("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.SimpleLeftJoin("get_forum_topics_offset","topics","users","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","topics.createdBy = users.uid","topics.parentID = ?","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC","?,?")
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("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, topics.data","replies.tid = topics.tid","rid = ?","")
|
adapter.SimpleLeftJoin("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.SimpleLeftJoin("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.SimpleLeftJoin("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.SimpleLeftJoin("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.SimpleLeftJoin("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, topics.data","replies.tid = topics.tid","rid = ?","","")
|
||||||
|
|
||||||
adapter.SimpleLeftJoin("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.SimpleLeftJoin("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.SimpleLeftJoin("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.SimpleLeftJoin("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 = ?","","")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func write_inner_joins(adapter qgen.DB_Adapter) error {
|
func write_inner_joins(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleInnerJoin("get_watchers","activity_stream","activity_subscriptions","activity_subscriptions.user","activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor","asid = ?","")
|
adapter.SimpleInnerJoin("get_watchers","activity_stream","activity_subscriptions","activity_subscriptions.user","activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor","asid = ?","","")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -283,7 +291,7 @@ func write_deletes(adapter qgen.DB_Adapter) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func write_simple_counts(adapter qgen.DB_Adapter) error {
|
func write_simple_counts(adapter qgen.DB_Adapter) error {
|
||||||
adapter.SimpleCount("report_exists","topics","data = ? and data != '' and parentID = 1")
|
adapter.SimpleCount("report_exists","topics","data = ? and data != '' and parentID = 1","")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,7 @@ func route_topics(w http.ResponseWriter, r *http.Request){
|
||||||
}
|
}
|
||||||
|
|
||||||
var topicList []TopicsRow
|
var topicList []TopicsRow
|
||||||
rows, err := db.Query("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 parentID in("+strings.Join(fidList,",")+") order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
|
rows, err := db.Query(topic_list_query(fidList))
|
||||||
//rows, err := get_topic_list_stmt.Query()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
InternalError(err,w,r)
|
InternalError(err,w,r)
|
||||||
return
|
return
|
||||||
|
@ -201,7 +200,7 @@ func route_forum(w http.ResponseWriter, r *http.Request, sfid string){
|
||||||
} else {
|
} else {
|
||||||
page = 1
|
page = 1
|
||||||
}
|
}
|
||||||
rows, err := get_forum_topics_offset_stmt.Query(fid,offset)
|
rows, err := get_forum_topics_offset_stmt.Query(fid,offset,items_per_page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
InternalError(err,w,r)
|
InternalError(err,w,r)
|
||||||
return
|
return
|
||||||
|
@ -364,7 +363,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the replies..
|
// Get the replies..
|
||||||
rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset)
|
rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset, items_per_page)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.",w,r,user)
|
LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.",w,r,user)
|
||||||
return
|
return
|
||||||
|
|
|
@ -23,7 +23,7 @@ type TopicStore interface {
|
||||||
GetCapacity() int
|
GetCapacity() int
|
||||||
}
|
}
|
||||||
|
|
||||||
type StaticTopicStore struct {
|
type MemoryTopicStore struct {
|
||||||
items map[int]*Topic
|
items map[int]*Topic
|
||||||
length int
|
length int
|
||||||
capacity int
|
capacity int
|
||||||
|
@ -31,19 +31,19 @@ type StaticTopicStore struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStaticTopicStore(capacity int) *StaticTopicStore {
|
func NewMemoryTopicStore(capacity int) *MemoryTopicStore {
|
||||||
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","")
|
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","","")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return &StaticTopicStore{
|
return &MemoryTopicStore{
|
||||||
items:make(map[int]*Topic),
|
items:make(map[int]*Topic),
|
||||||
capacity:capacity,
|
capacity:capacity,
|
||||||
get:stmt,
|
get:stmt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) Get(id int) (*Topic, error) {
|
func (sts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
||||||
sts.RLock()
|
sts.RLock()
|
||||||
item, ok := sts.items[id]
|
item, ok := sts.items[id]
|
||||||
sts.RUnlock()
|
sts.RUnlock()
|
||||||
|
@ -53,7 +53,7 @@ func (sts *StaticTopicStore) Get(id int) (*Topic, error) {
|
||||||
return item, sql.ErrNoRows
|
return item, sql.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) GetUnsafe(id int) (*Topic, error) {
|
func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) {
|
||||||
item, ok := sts.items[id]
|
item, ok := sts.items[id]
|
||||||
if ok {
|
if ok {
|
||||||
return item, nil
|
return item, nil
|
||||||
|
@ -61,7 +61,7 @@ func (sts *StaticTopicStore) GetUnsafe(id int) (*Topic, error) {
|
||||||
return item, sql.ErrNoRows
|
return item, sql.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
|
func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
|
||||||
sts.RLock()
|
sts.RLock()
|
||||||
topic, ok := sts.items[id]
|
topic, ok := sts.items[id]
|
||||||
sts.RUnlock()
|
sts.RUnlock()
|
||||||
|
@ -77,13 +77,13 @@ func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
|
||||||
return topic, err
|
return topic, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) BypassGet(id int) (*Topic, error) {
|
func (sts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
|
||||||
topic := &Topic{ID:id}
|
topic := &Topic{ID:id}
|
||||||
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
return topic, err
|
return topic, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) Load(id int) error {
|
func (sts *MemoryTopicStore) Load(id int) error {
|
||||||
topic := &Topic{ID:id}
|
topic := &Topic{ID:id}
|
||||||
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -94,7 +94,7 @@ func (sts *StaticTopicStore) Load(id int) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) Set(item *Topic) error {
|
func (sts *MemoryTopicStore) Set(item *Topic) error {
|
||||||
sts.Lock()
|
sts.Lock()
|
||||||
_, ok := sts.items[item.ID]
|
_, ok := sts.items[item.ID]
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -110,7 +110,7 @@ func (sts *StaticTopicStore) Set(item *Topic) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) Add(item *Topic) error {
|
func (sts *MemoryTopicStore) Add(item *Topic) error {
|
||||||
if sts.length >= sts.capacity {
|
if sts.length >= sts.capacity {
|
||||||
return ErrStoreCapacityOverflow
|
return ErrStoreCapacityOverflow
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ func (sts *StaticTopicStore) Add(item *Topic) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) AddUnsafe(item *Topic) error {
|
func (sts *MemoryTopicStore) AddUnsafe(item *Topic) error {
|
||||||
if sts.length >= sts.capacity {
|
if sts.length >= sts.capacity {
|
||||||
return ErrStoreCapacityOverflow
|
return ErrStoreCapacityOverflow
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ func (sts *StaticTopicStore) AddUnsafe(item *Topic) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) Remove(id int) error {
|
func (sts *MemoryTopicStore) Remove(id int) error {
|
||||||
sts.Lock()
|
sts.Lock()
|
||||||
delete(sts.items,id)
|
delete(sts.items,id)
|
||||||
sts.Unlock()
|
sts.Unlock()
|
||||||
|
@ -138,40 +138,35 @@ func (sts *StaticTopicStore) Remove(id int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) RemoveUnsafe(id int) error {
|
func (sts *MemoryTopicStore) RemoveUnsafe(id int) error {
|
||||||
delete(sts.items,id)
|
delete(sts.items,id)
|
||||||
sts.length--
|
sts.length--
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) AddLastTopic(item *Topic, fid int) error {
|
func (sts *MemoryTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||||
// Coming Soon...
|
// Coming Soon...
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) GetLength() int {
|
func (sts *MemoryTopicStore) GetLength() int {
|
||||||
return sts.length
|
return sts.length
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) SetCapacity(capacity int) {
|
func (sts *MemoryTopicStore) SetCapacity(capacity int) {
|
||||||
sts.capacity = capacity
|
sts.capacity = capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts *StaticTopicStore) GetCapacity() int {
|
func (sts *MemoryTopicStore) GetCapacity() int {
|
||||||
return sts.capacity
|
return sts.capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
//type DynamicTopicStore struct {
|
|
||||||
// items_expiries list.List
|
|
||||||
// items map[int]*Topic
|
|
||||||
//}
|
|
||||||
|
|
||||||
type SqlTopicStore struct {
|
type SqlTopicStore struct {
|
||||||
get *sql.Stmt
|
get *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqlTopicStore() *SqlTopicStore {
|
func NewSqlTopicStore() *SqlTopicStore {
|
||||||
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","")
|
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","","")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
3
user.go
3
user.go
|
@ -11,6 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var guest_user User = User{ID:0,Group:6,Perms:GuestPerms}
|
var guest_user User = User{ID:0,Group:6,Perms:GuestPerms}
|
||||||
|
var SimpleSessionCheck func(http.ResponseWriter, *http.Request) (User,bool) = _simple_session_check
|
||||||
|
|
||||||
type User struct
|
type User struct
|
||||||
{
|
{
|
||||||
|
@ -145,7 +146,7 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
|
||||||
return user, noticeList, success
|
return user, noticeList, success
|
||||||
}
|
}
|
||||||
|
|
||||||
func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) {
|
func _simple_session_check(w http.ResponseWriter, r *http.Request) (User,bool) {
|
||||||
// Are there any session cookies..?
|
// Are there any session cookies..?
|
||||||
cookie, err := r.Cookie("uid")
|
cookie, err := r.Cookie("uid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -26,7 +26,7 @@ type UserStore interface {
|
||||||
GetCapacity() int
|
GetCapacity() int
|
||||||
}
|
}
|
||||||
|
|
||||||
type StaticUserStore struct {
|
type MemoryUserStore struct {
|
||||||
items map[int]*User
|
items map[int]*User
|
||||||
length int
|
length int
|
||||||
capacity int
|
capacity int
|
||||||
|
@ -34,19 +34,19 @@ type StaticUserStore struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStaticUserStore(capacity int) *StaticUserStore {
|
func NewMemoryUserStore(capacity int) *MemoryUserStore {
|
||||||
stmt, err := qgen.Builder.SimpleSelect("users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","")
|
stmt, err := qgen.Builder.SimpleSelect("users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","","")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return &StaticUserStore{
|
return &MemoryUserStore{
|
||||||
items:make(map[int]*User),
|
items:make(map[int]*User),
|
||||||
capacity:capacity,
|
capacity:capacity,
|
||||||
get:stmt,
|
get:stmt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) Get(id int) (*User, error) {
|
func (sus *MemoryUserStore) Get(id int) (*User, error) {
|
||||||
sus.RLock()
|
sus.RLock()
|
||||||
item, ok := sus.items[id]
|
item, ok := sus.items[id]
|
||||||
sus.RUnlock()
|
sus.RUnlock()
|
||||||
|
@ -56,7 +56,7 @@ func (sus *StaticUserStore) Get(id int) (*User, error) {
|
||||||
return item, sql.ErrNoRows
|
return item, sql.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) GetUnsafe(id int) (*User, error) {
|
func (sus *MemoryUserStore) GetUnsafe(id int) (*User, error) {
|
||||||
item, ok := sus.items[id]
|
item, ok := sus.items[id]
|
||||||
if ok {
|
if ok {
|
||||||
return item, nil
|
return item, nil
|
||||||
|
@ -64,7 +64,7 @@ func (sus *StaticUserStore) GetUnsafe(id int) (*User, error) {
|
||||||
return item, sql.ErrNoRows
|
return item, sql.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) CascadeGet(id int) (*User, error) {
|
func (sus *MemoryUserStore) CascadeGet(id int) (*User, error) {
|
||||||
sus.RLock()
|
sus.RLock()
|
||||||
user, ok := sus.items[id]
|
user, ok := sus.items[id]
|
||||||
sus.RUnlock()
|
sus.RUnlock()
|
||||||
|
@ -90,7 +90,7 @@ func (sus *StaticUserStore) CascadeGet(id int) (*User, error) {
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) BypassGet(id int) (*User, error) {
|
func (sus *MemoryUserStore) BypassGet(id int) (*User, error) {
|
||||||
user := &User{ID:id,Loggedin:true}
|
user := &User{ID:id,Loggedin:true}
|
||||||
err := sus.get.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 := sus.get.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)
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ func (sus *StaticUserStore) BypassGet(id int) (*User, error) {
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) Load(id int) error {
|
func (sus *MemoryUserStore) Load(id int) error {
|
||||||
user := &User{ID:id,Loggedin:true}
|
user := &User{ID:id,Loggedin:true}
|
||||||
err := sus.get.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 := sus.get.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 err != nil {
|
if err != nil {
|
||||||
|
@ -127,7 +127,7 @@ func (sus *StaticUserStore) Load(id int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) Set(item *User) error {
|
func (sus *MemoryUserStore) Set(item *User) error {
|
||||||
sus.Lock()
|
sus.Lock()
|
||||||
user, ok := sus.items[item.ID]
|
user, ok := sus.items[item.ID]
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -144,7 +144,7 @@ func (sus *StaticUserStore) Set(item *User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) Add(item *User) error {
|
func (sus *MemoryUserStore) Add(item *User) error {
|
||||||
if sus.length >= sus.capacity {
|
if sus.length >= sus.capacity {
|
||||||
return ErrStoreCapacityOverflow
|
return ErrStoreCapacityOverflow
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ func (sus *StaticUserStore) Add(item *User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) AddUnsafe(item *User) error {
|
func (sus *MemoryUserStore) AddUnsafe(item *User) error {
|
||||||
if sus.length >= sus.capacity {
|
if sus.length >= sus.capacity {
|
||||||
return ErrStoreCapacityOverflow
|
return ErrStoreCapacityOverflow
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ func (sus *StaticUserStore) AddUnsafe(item *User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) Remove(id int) error {
|
func (sus *MemoryUserStore) Remove(id int) error {
|
||||||
sus.Lock()
|
sus.Lock()
|
||||||
delete(sus.items,id)
|
delete(sus.items,id)
|
||||||
sus.Unlock()
|
sus.Unlock()
|
||||||
|
@ -172,35 +172,30 @@ func (sus *StaticUserStore) Remove(id int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) RemoveUnsafe(id int) error {
|
func (sus *MemoryUserStore) RemoveUnsafe(id int) error {
|
||||||
delete(sus.items,id)
|
delete(sus.items,id)
|
||||||
sus.length--
|
sus.length--
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) GetLength() int {
|
func (sus *MemoryUserStore) GetLength() int {
|
||||||
return sus.length
|
return sus.length
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) SetCapacity(capacity int) {
|
func (sus *MemoryUserStore) SetCapacity(capacity int) {
|
||||||
sus.capacity = capacity
|
sus.capacity = capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sus *StaticUserStore) GetCapacity() int {
|
func (sus *MemoryUserStore) GetCapacity() int {
|
||||||
return sus.capacity
|
return sus.capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
//type DynamicUserStore struct {
|
|
||||||
// items_expiries list.List
|
|
||||||
// items map[int]*User
|
|
||||||
//}
|
|
||||||
|
|
||||||
type SqlUserStore struct {
|
type SqlUserStore struct {
|
||||||
get *sql.Stmt
|
get *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqlUserStore() *SqlUserStore {
|
func NewSqlUserStore() *SqlUserStore {
|
||||||
stmt, err := qgen.Builder.SimpleSelect("users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","")
|
stmt, err := qgen.Builder.SimpleSelect("users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","","")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue