Refactored query_gen into a library.
Moved topic store and user store into their own files. Tweaked topic store to stop it accessing globals.
This commit is contained in:
parent
29d9d07cde
commit
af09013a25
3
cache.go
3
cache.go
@ -7,9 +7,6 @@ const CACHE_SQL int = 2
|
||||
|
||||
var ErrStoreCapacityOverflow = errors.New("This datastore has already reached it's max capacity")
|
||||
|
||||
var users UserStore
|
||||
var topics TopicStore
|
||||
|
||||
type DataStore interface {
|
||||
Load(id int) error
|
||||
Get(id int) (interface{}, error)
|
||||
|
4
mysql.go
4
mysql.go
@ -2,12 +2,12 @@
|
||||
// +build !pgsql !sqlite !mssql
|
||||
package main
|
||||
|
||||
import "database/sql"
|
||||
import _ "github.com/go-sql-driver/mysql"
|
||||
import "log"
|
||||
import "fmt"
|
||||
import "strconv"
|
||||
import "encoding/json"
|
||||
import "database/sql"
|
||||
import _ "github.com/go-sql-driver/mysql"
|
||||
|
||||
var db *sql.DB
|
||||
var db_version string
|
||||
|
7
query_gen/lib/builder.go
Normal file
7
query_gen/lib/builder.go
Normal file
@ -0,0 +1,7 @@
|
||||
/* WIP Under Construction */
|
||||
package qgen
|
||||
|
||||
type Builder struct
|
||||
{
|
||||
|
||||
}
|
@ -1,26 +1,38 @@
|
||||
/* WIP Under Construction */
|
||||
package main
|
||||
package qgen
|
||||
|
||||
//import "fmt"
|
||||
import "strings"
|
||||
import "errors"
|
||||
|
||||
func init() {
|
||||
db_registry = append(db_registry,&Mysql_Adapter{Name:"mysql"})
|
||||
DB_Registry = append(DB_Registry,
|
||||
&Mysql_Adapter{Name:"mysql",Buffer:make(map[string]string)},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
type Mysql_Adapter struct
|
||||
{
|
||||
Name string
|
||||
Stmts string
|
||||
Body string
|
||||
Buffer map[string]string
|
||||
BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) get_name() string {
|
||||
func (adapter *Mysql_Adapter) GetName() string {
|
||||
return adapter.Name
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns string, fields string) error {
|
||||
func (adapter *Mysql_Adapter) GetStmt(name string) string {
|
||||
return adapter.Buffer[name]
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) GetStmts() map[string]string {
|
||||
return adapter.Buffer
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) SimpleInsert(name string, table string, columns string, fields string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -28,10 +40,10 @@ func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns s
|
||||
return errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_insert")
|
||||
return errors.New("No columns found for SimpleInsert")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return errors.New("No input data found for simple_insert")
|
||||
return errors.New("No input data found for SimpleInsert")
|
||||
}
|
||||
|
||||
var querystr string = "INSERT INTO `" + table + "`("
|
||||
@ -54,11 +66,11 @@ func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns s
|
||||
}
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
|
||||
adapter.write_statement(name,querystr + ")")
|
||||
adapter.push_statement(name,querystr + ")")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_replace(name string, table string, columns string, fields string) error {
|
||||
func (adapter *Mysql_Adapter) SimpleReplace(name string, table string, columns string, fields string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -66,10 +78,10 @@ func (adapter *Mysql_Adapter) simple_replace(name string, table string, columns
|
||||
return errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_insert")
|
||||
return errors.New("No columns found for SimpleInsert")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return errors.New("No input data found for simple_insert")
|
||||
return errors.New("No input data found for SimpleInsert")
|
||||
}
|
||||
|
||||
var querystr string = "REPLACE INTO `" + table + "`("
|
||||
@ -92,11 +104,11 @@ func (adapter *Mysql_Adapter) simple_replace(name string, table string, columns
|
||||
}
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
|
||||
adapter.write_statement(name,querystr + ")")
|
||||
adapter.push_statement(name,querystr + ")")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_update(name string, table string, set string, where string) error {
|
||||
func (adapter *Mysql_Adapter) SimpleUpdate(name string, table string, set string, where string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -148,11 +160,11 @@ func (adapter *Mysql_Adapter) simple_update(name string, table string, set strin
|
||||
querystr = querystr[0:len(querystr) - 4]
|
||||
}
|
||||
|
||||
adapter.write_statement(name,querystr)
|
||||
adapter.push_statement(name,querystr)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_delete(name string, table string, where string) error {
|
||||
func (adapter *Mysql_Adapter) SimpleDelete(name string, table string, where string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -183,23 +195,23 @@ func (adapter *Mysql_Adapter) simple_delete(name string, table string, where str
|
||||
}
|
||||
querystr = querystr[0:len(querystr) - 4]
|
||||
|
||||
adapter.write_statement(name,strings.TrimSpace(querystr))
|
||||
adapter.push_statement(name,strings.TrimSpace(querystr))
|
||||
return nil
|
||||
}
|
||||
|
||||
// We don't want to accidentally wipe tables, so we'll have a seperate method for purging tables instead
|
||||
func (adapter *Mysql_Adapter) purge(name string, table string) error {
|
||||
func (adapter *Mysql_Adapter) Purge(name string, table string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
if table == "" {
|
||||
return errors.New("You need a name for this table")
|
||||
}
|
||||
adapter.write_statement(name,"DELETE FROM `" + table + "`")
|
||||
adapter.push_statement(name,"DELETE FROM `" + table + "`")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_select(name string, table string, columns string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
func (adapter *Mysql_Adapter) SimpleSelect(name string, table string, columns string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -207,7 +219,7 @@ func (adapter *Mysql_Adapter) simple_select(name string, table string, columns s
|
||||
return errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_select")
|
||||
return errors.New("No columns found for SimpleSelect")
|
||||
}
|
||||
|
||||
// Slice up the user friendly strings into something easier to process
|
||||
@ -254,11 +266,11 @@ func (adapter *Mysql_Adapter) simple_select(name string, table string, columns s
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
}
|
||||
|
||||
adapter.write_statement(name,strings.TrimSpace(querystr))
|
||||
adapter.push_statement(name,strings.TrimSpace(querystr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
func (adapter *Mysql_Adapter) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -269,10 +281,10 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
|
||||
return errors.New("You need a name for the right table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_left_join")
|
||||
return errors.New("No columns found for SimpleLeftJoin")
|
||||
}
|
||||
if len(joiners) == 0 {
|
||||
return errors.New("No joiners found for simple_left_join")
|
||||
return errors.New("No joiners found for SimpleLeftJoin")
|
||||
}
|
||||
|
||||
var querystr string = "SELECT "
|
||||
@ -339,11 +351,11 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
}
|
||||
|
||||
adapter.write_statement(name,strings.TrimSpace(querystr))
|
||||
adapter.push_statement(name,strings.TrimSpace(querystr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_inner_join(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
func (adapter *Mysql_Adapter) SimpleInnerJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
@ -354,10 +366,10 @@ func (adapter *Mysql_Adapter) simple_inner_join(name string, table1 string, tabl
|
||||
return errors.New("You need a name for the right table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_inner_join")
|
||||
return errors.New("No columns found for SimpleInnerJoin")
|
||||
}
|
||||
if len(joiners) == 0 {
|
||||
return errors.New("No joiners found for simple_inner_join")
|
||||
return errors.New("No joiners found for SimpleInnerJoin")
|
||||
}
|
||||
|
||||
var querystr string = "SELECT "
|
||||
@ -424,11 +436,24 @@ func (adapter *Mysql_Adapter) simple_inner_join(name string, table1 string, tabl
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
}
|
||||
|
||||
adapter.write_statement(name,strings.TrimSpace(querystr))
|
||||
adapter.push_statement(name,strings.TrimSpace(querystr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) write() error {
|
||||
func (adapter *Mysql_Adapter) Write() error {
|
||||
var stmts, body string
|
||||
|
||||
for _, name := range adapter.BufferOrder {
|
||||
stmts += "var " + name + "_stmt *sql.Stmt\n"
|
||||
body += `
|
||||
log.Print("Preparing ` + name + ` statement.")
|
||||
` + name + `_stmt, err = db.Prepare("` + adapter.Buffer[name] + `")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
out := `// Code generated by. DO NOT EDIT.
|
||||
/* This file was generated by Gosora's Query Generator. The thing above is to tell GH this file is generated. */
|
||||
// +build !pgsql !sqlite !mssql
|
||||
@ -437,12 +462,12 @@ package main
|
||||
import "log"
|
||||
import "database/sql"
|
||||
|
||||
` + adapter.Stmts + `
|
||||
` + stmts + `
|
||||
func gen_mysql() (err error) {
|
||||
if debug {
|
||||
log.Print("Building the generated statements")
|
||||
}
|
||||
` + adapter.Body + `
|
||||
` + body + `
|
||||
return nil
|
||||
}
|
||||
`
|
||||
@ -450,14 +475,7 @@ func gen_mysql() (err error) {
|
||||
}
|
||||
|
||||
// Internal method, not exposed in the interface
|
||||
func (adapter *Mysql_Adapter) write_statement(name string, querystr string ) {
|
||||
adapter.Stmts += "var " + name + "_stmt *sql.Stmt\n"
|
||||
|
||||
adapter.Body += `
|
||||
log.Print("Preparing ` + name + ` statement.")
|
||||
` + name + `_stmt, err = db.Prepare("` + querystr + `")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
`
|
||||
func (adapter *Mysql_Adapter) push_statement(name string, querystr string ) {
|
||||
adapter.Buffer[name] = querystr
|
||||
adapter.BufferOrder = append(adapter.BufferOrder,name)
|
||||
}
|
81
query_gen/lib/querygen.go
Normal file
81
query_gen/lib/querygen.go
Normal file
@ -0,0 +1,81 @@
|
||||
/* WIP Under Construction */
|
||||
package qgen
|
||||
|
||||
import "errors"
|
||||
|
||||
var DB_Registry []DB_Adapter
|
||||
var No_Adapter = errors.New("This adapter doesn't exist")
|
||||
|
||||
type DB_Column struct
|
||||
{
|
||||
Table string
|
||||
Left string // Could be a function or a column, so I'm naming this Left
|
||||
Alias string // aka AS Blah, if it's present
|
||||
Type string // function or column
|
||||
}
|
||||
|
||||
type DB_Field struct
|
||||
{
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type DB_Where struct
|
||||
{
|
||||
LeftTable string
|
||||
LeftColumn string
|
||||
RightTable string
|
||||
RightColumn string
|
||||
Operator string
|
||||
LeftType string
|
||||
RightType string
|
||||
}
|
||||
|
||||
type DB_Joiner struct
|
||||
{
|
||||
LeftTable string
|
||||
LeftColumn string
|
||||
RightTable string
|
||||
RightColumn string
|
||||
Operator string
|
||||
}
|
||||
|
||||
type DB_Order struct
|
||||
{
|
||||
Column string
|
||||
Order string
|
||||
}
|
||||
|
||||
type DB_Token struct {
|
||||
Contents string
|
||||
Type string // function, operator, column, number, string, substitute
|
||||
}
|
||||
|
||||
type DB_Setter struct {
|
||||
Column string
|
||||
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now.
|
||||
}
|
||||
|
||||
type DB_Adapter interface {
|
||||
GetName() string
|
||||
SimpleInsert(string,string,string,string) error
|
||||
SimpleReplace(string,string,string,string) error
|
||||
SimpleUpdate(string,string,string,string) error
|
||||
SimpleDelete(string,string,string) error
|
||||
Purge(string,string) error
|
||||
SimpleSelect(string,string,string,string,string/*,int,int*/) error
|
||||
SimpleLeftJoin(string,string,string,string,string,string,string/*,int,int*/) error
|
||||
SimpleInnerJoin(string,string,string,string,string,string,string/*,int,int*/) error
|
||||
Write() error
|
||||
|
||||
// TO-DO: Add a simple query builder
|
||||
}
|
||||
|
||||
func GetAdapter(name string) (adap DB_Adapter, err error) {
|
||||
for _, adapter := range DB_Registry {
|
||||
if adapter.GetName() == name {
|
||||
return adapter, nil
|
||||
}
|
||||
}
|
||||
return adap, No_Adapter
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
/* WIP Under Construction */
|
||||
package main
|
||||
package qgen
|
||||
|
||||
//import "fmt"
|
||||
import "strings"
|
||||
import "os"
|
||||
|
||||
type _statement struct
|
||||
{
|
||||
Name string
|
||||
Body string
|
||||
}
|
||||
|
||||
func _process_columns(colstr string) (columns []DB_Column) {
|
||||
if colstr == "" {
|
||||
return columns
|
@ -2,85 +2,18 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
var db_registry []DB_Adapter
|
||||
var blank_order []DB_Order
|
||||
|
||||
type DB_Column struct
|
||||
{
|
||||
Table string
|
||||
Left string // Could be a function or a column, so I'm naming this Left
|
||||
Alias string // aka AS Blah, if it's present
|
||||
Type string // function or column
|
||||
}
|
||||
|
||||
type DB_Field struct
|
||||
{
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type DB_Where struct
|
||||
{
|
||||
LeftTable string
|
||||
LeftColumn string
|
||||
RightTable string
|
||||
RightColumn string
|
||||
Operator string
|
||||
LeftType string
|
||||
RightType string
|
||||
}
|
||||
|
||||
type DB_Joiner struct
|
||||
{
|
||||
LeftTable string
|
||||
LeftColumn string
|
||||
RightTable string
|
||||
RightColumn string
|
||||
Operator string
|
||||
}
|
||||
|
||||
type DB_Order struct
|
||||
{
|
||||
Column string
|
||||
Order string
|
||||
}
|
||||
|
||||
type DB_Token struct {
|
||||
Contents string
|
||||
Type string // function, operator, column, number, string, substitute
|
||||
}
|
||||
|
||||
type DB_Setter struct {
|
||||
Column string
|
||||
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now.
|
||||
}
|
||||
|
||||
type DB_Adapter interface {
|
||||
get_name() string
|
||||
simple_insert(string,string,string,string) error
|
||||
simple_replace(string,string,string,string) error
|
||||
simple_update(string,string,string,string) error
|
||||
simple_delete(string,string,string) error
|
||||
purge(string,string) error
|
||||
simple_select(string,string,string,string,string/*,int,int*/) error
|
||||
simple_left_join(string,string,string,string,string,string,string/*,int,int*/) error
|
||||
simple_inner_join(string,string,string,string,string,string,string/*,int,int*/) error
|
||||
write() error
|
||||
|
||||
// TO-DO: Add a simple query builder
|
||||
}
|
||||
import "./lib"
|
||||
|
||||
func main() {
|
||||
log.Println("Running the query generator")
|
||||
for _, adapter := range db_registry {
|
||||
log.Println("Building the queries for the " + adapter.get_name() + " adapter")
|
||||
for _, adapter := range qgen.DB_Registry {
|
||||
log.Println("Building the queries for the " + adapter.GetName() + " adapter")
|
||||
write_statements(adapter)
|
||||
adapter.write()
|
||||
adapter.Write()
|
||||
}
|
||||
}
|
||||
|
||||
func write_statements(adapter DB_Adapter) error {
|
||||
func write_statements(adapter qgen.DB_Adapter) error {
|
||||
err := write_selects(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -112,219 +45,219 @@ func write_statements(adapter DB_Adapter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_selects(adapter 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
|
||||
adapter.simple_select("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 = ?","")
|
||||
|
||||
adapter.simple_select("get_full_user","users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","")
|
||||
adapter.SimpleSelect("get_full_user","users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_topic","topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","")
|
||||
adapter.SimpleSelect("get_topic","topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","")
|
||||
|
||||
adapter.simple_select("get_reply","replies","content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?","")
|
||||
adapter.SimpleSelect("get_reply","replies","content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?","")
|
||||
|
||||
adapter.simple_select("login","users","uid, name, password, salt","name = ?","")
|
||||
adapter.SimpleSelect("login","users","uid, name, password, salt","name = ?","")
|
||||
|
||||
adapter.simple_select("get_password","users","password,salt","uid = ?","")
|
||||
adapter.SimpleSelect("get_password","users","password,salt","uid = ?","")
|
||||
|
||||
adapter.simple_select("username_exists","users","name","name = ?","")
|
||||
adapter.SimpleSelect("username_exists","users","name","name = ?","")
|
||||
|
||||
|
||||
adapter.simple_select("get_settings","settings","name, content, type","","")
|
||||
adapter.SimpleSelect("get_settings","settings","name, content, type","","")
|
||||
|
||||
adapter.simple_select("get_setting","settings","content, type","name = ?","")
|
||||
adapter.SimpleSelect("get_setting","settings","content, type","name = ?","")
|
||||
|
||||
adapter.simple_select("get_full_setting","settings","name, type, constraints","name = ?","")
|
||||
adapter.SimpleSelect("get_full_setting","settings","name, type, constraints","name = ?","")
|
||||
|
||||
adapter.simple_select("is_plugin_active","plugins","active","uname = ?","")
|
||||
adapter.SimpleSelect("is_plugin_active","plugins","active","uname = ?","")
|
||||
|
||||
adapter.simple_select("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.simple_select("is_theme_default","themes","default","uname = ?","")
|
||||
adapter.SimpleSelect("is_theme_default","themes","default","uname = ?","")
|
||||
|
||||
adapter.simple_select("get_modlogs","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","","")
|
||||
adapter.SimpleSelect("get_modlogs","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","","")
|
||||
|
||||
adapter.simple_select("get_reply_tid","replies","tid","rid = ?","")
|
||||
adapter.SimpleSelect("get_reply_tid","replies","tid","rid = ?","")
|
||||
|
||||
adapter.simple_select("get_topic_fid","topics","parentID","tid = ?","")
|
||||
adapter.SimpleSelect("get_topic_fid","topics","parentID","tid = ?","")
|
||||
|
||||
adapter.simple_select("get_user_reply_uid","users_replies","uid","rid = ?","")
|
||||
adapter.SimpleSelect("get_user_reply_uid","users_replies","uid","rid = ?","")
|
||||
|
||||
adapter.simple_select("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.simple_select("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.simple_select("get_user_name","users","name","uid = ?","")
|
||||
adapter.SimpleSelect("get_user_name","users","name","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_user_rank","users","group, is_super_admin","uid = ?","")
|
||||
adapter.SimpleSelect("get_user_rank","users","group, is_super_admin","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_user_active","users","active","uid = ?","")
|
||||
adapter.SimpleSelect("get_user_active","users","active","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_user_group","users","group","uid = ?","")
|
||||
adapter.SimpleSelect("get_user_group","users","group","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_emails_by_user","emails","email, validated","uid = ?","")
|
||||
adapter.SimpleSelect("get_emails_by_user","emails","email, validated","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_topic_basic","topics","title, content","tid = ?","")
|
||||
adapter.SimpleSelect("get_topic_basic","topics","title, content","tid = ?","")
|
||||
|
||||
adapter.simple_select("get_activity_entry","activity_stream","actor, targetUser, event, elementType, elementID","asid = ?","")
|
||||
adapter.SimpleSelect("get_activity_entry","activity_stream","actor, targetUser, event, elementType, elementID","asid = ?","")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_left_joins(adapter DB_Adapter) error {
|
||||
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")
|
||||
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.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.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.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, topics.data","replies.tid = topics.tid","rid = ?","")
|
||||
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.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.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.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.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.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.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
|
||||
}
|
||||
|
||||
func write_inner_joins(adapter DB_Adapter) error {
|
||||
adapter.simple_inner_join("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 = ?","")
|
||||
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 = ?","")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_inserts(adapter DB_Adapter) error {
|
||||
adapter.simple_insert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,NOW(),NOW(),?,?,?")
|
||||
func write_inserts(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleInsert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,NOW(),NOW(),?,?,?")
|
||||
|
||||
adapter.simple_insert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,NOW(),NOW(),?,?,1,'report'")
|
||||
adapter.SimpleInsert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,NOW(),NOW(),?,?,1,'report'")
|
||||
|
||||
adapter.simple_insert("create_reply","replies","tid,content,parsed_content,createdAt,ipaddress,words,createdBy","?,?,?,NOW(),?,?,?")
|
||||
adapter.SimpleInsert("create_reply","replies","tid,content,parsed_content,createdAt,ipaddress,words,createdBy","?,?,?,NOW(),?,?,?")
|
||||
|
||||
adapter.simple_insert("create_action_reply","replies","tid,actionType,ipaddress,createdBy","?,?,?,?")
|
||||
adapter.SimpleInsert("create_action_reply","replies","tid,actionType,ipaddress,createdBy","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("create_like","likes","weight, targetItem, targetType, sentBy","?,?,?,?")
|
||||
adapter.SimpleInsert("create_like","likes","weight, targetItem, targetType, sentBy","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_activity","activity_stream","actor,targetUser,event,elementType,elementID","?,?,?,?,?")
|
||||
adapter.SimpleInsert("add_activity","activity_stream","actor,targetUser,event,elementType,elementID","?,?,?,?,?")
|
||||
|
||||
adapter.simple_insert("notify_one","activity_stream_matches","watcher,asid","?,?")
|
||||
adapter.SimpleInsert("notify_one","activity_stream_matches","watcher,asid","?,?")
|
||||
|
||||
// Add an admin version of register_stmt with more flexibility?
|
||||
// create_account_stmt, err = db.Prepare("INSERT INTO
|
||||
adapter.simple_insert("register","users","name, email, password, salt, group, is_super_admin, session, active, message","?,?,?,?,?,0,?,?,''")
|
||||
adapter.SimpleInsert("register","users","name, email, password, salt, group, is_super_admin, session, active, message","?,?,?,?,?,0,?,?,''")
|
||||
|
||||
adapter.simple_insert("add_email","emails","email, uid, validated, token","?,?,?,?")
|
||||
adapter.SimpleInsert("add_email","emails","email, uid, validated, token","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("create_profile_reply","users_replies","uid,content,parsed_content,createdAt,createdBy","?,?,?,NOW(),?")
|
||||
adapter.SimpleInsert("create_profile_reply","users_replies","uid,content,parsed_content,createdAt,createdBy","?,?,?,NOW(),?")
|
||||
|
||||
adapter.simple_insert("add_subscription","activity_subscriptions","user,targetID,targetType,level","?,?,?,2")
|
||||
adapter.SimpleInsert("add_subscription","activity_subscriptions","user,targetID,targetType,level","?,?,?,2")
|
||||
|
||||
adapter.simple_insert("create_forum","forums","name, desc, active, preset","?,?,?,?")
|
||||
adapter.SimpleInsert("create_forum","forums","name, desc, active, preset","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_forum_perms_to_forum","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
adapter.SimpleInsert("add_forum_perms_to_forum","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_plugin","plugins","uname,active","?,?")
|
||||
adapter.SimpleInsert("add_plugin","plugins","uname,active","?,?")
|
||||
|
||||
adapter.simple_insert("add_theme","themes","uname,default","?,?")
|
||||
adapter.SimpleInsert("add_theme","themes","uname,default","?,?")
|
||||
|
||||
|
||||
adapter.simple_insert("create_group","users_groups","name, tag, is_admin, is_mod, is_banned, permissions","?,?,?,?,?,?")
|
||||
adapter.SimpleInsert("create_group","users_groups","name, tag, is_admin, is_mod, is_banned, permissions","?,?,?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_modlog_entry","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
adapter.SimpleInsert("add_modlog_entry","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
|
||||
adapter.simple_insert("add_adminlog_entry","administration_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
adapter.SimpleInsert("add_adminlog_entry","administration_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_replaces(adapter DB_Adapter) error {
|
||||
adapter.simple_replace("add_forum_perms_to_group","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
func write_replaces(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleReplace("add_forum_perms_to_group","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_updates(adapter DB_Adapter) error {
|
||||
adapter.simple_update("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyAt = NOW()","tid = ?")
|
||||
func write_updates(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleUpdate("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyAt = NOW()","tid = ?")
|
||||
|
||||
adapter.simple_update("remove_replies_from_topic","topics","postCount = postCount - ?","tid = ?")
|
||||
adapter.SimpleUpdate("remove_replies_from_topic","topics","postCount = postCount - ?","tid = ?")
|
||||
|
||||
adapter.simple_update("add_topics_to_forum","forums","topicCount = topicCount + ?","fid = ?")
|
||||
adapter.SimpleUpdate("add_topics_to_forum","forums","topicCount = topicCount + ?","fid = ?")
|
||||
|
||||
adapter.simple_update("remove_topics_from_forum","forums","topicCount = topicCount - ?","fid = ?")
|
||||
adapter.SimpleUpdate("remove_topics_from_forum","forums","topicCount = topicCount - ?","fid = ?")
|
||||
|
||||
adapter.simple_update("update_forum_cache","forums","lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW()","fid = ?")
|
||||
adapter.SimpleUpdate("update_forum_cache","forums","lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW()","fid = ?")
|
||||
|
||||
adapter.simple_update("add_likes_to_topic","topics","likeCount = likeCount + ?","tid = ?")
|
||||
adapter.SimpleUpdate("add_likes_to_topic","topics","likeCount = likeCount + ?","tid = ?")
|
||||
|
||||
adapter.simple_update("add_likes_to_reply","replies","likeCount = likeCount + ?","rid = ?")
|
||||
adapter.SimpleUpdate("add_likes_to_reply","replies","likeCount = likeCount + ?","rid = ?")
|
||||
|
||||
adapter.simple_update("edit_topic","topics","title = ?, content = ?, parsed_content = ?, is_closed = ?","tid = ?")
|
||||
adapter.SimpleUpdate("edit_topic","topics","title = ?, content = ?, parsed_content = ?, is_closed = ?","tid = ?")
|
||||
|
||||
adapter.simple_update("edit_reply","replies","content = ?, parsed_content = ?","rid = ?")
|
||||
adapter.SimpleUpdate("edit_reply","replies","content = ?, parsed_content = ?","rid = ?")
|
||||
|
||||
adapter.simple_update("stick_topic","topics","sticky = 1","tid = ?")
|
||||
adapter.SimpleUpdate("stick_topic","topics","sticky = 1","tid = ?")
|
||||
|
||||
adapter.simple_update("unstick_topic","topics","sticky = 0","tid = ?")
|
||||
adapter.SimpleUpdate("unstick_topic","topics","sticky = 0","tid = ?")
|
||||
|
||||
adapter.simple_update("update_last_ip","users","last_ip = ?","uid = ?")
|
||||
adapter.SimpleUpdate("update_last_ip","users","last_ip = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("update_session","users","session = ?","uid = ?")
|
||||
adapter.SimpleUpdate("update_session","users","session = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("logout","users","session = ''","uid = ?")
|
||||
adapter.SimpleUpdate("logout","users","session = ''","uid = ?")
|
||||
|
||||
adapter.simple_update("set_password","users","password = ?, salt = ?","uid = ?")
|
||||
adapter.SimpleUpdate("set_password","users","password = ?, salt = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("set_avatar","users","avatar = ?","uid = ?")
|
||||
adapter.SimpleUpdate("set_avatar","users","avatar = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("set_username","users","name = ?","uid = ?")
|
||||
adapter.SimpleUpdate("set_username","users","name = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("change_group","users","group = ?","uid = ?")
|
||||
adapter.SimpleUpdate("change_group","users","group = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("activate_user","users","active = 1","uid = ?")
|
||||
adapter.SimpleUpdate("activate_user","users","active = 1","uid = ?")
|
||||
|
||||
adapter.simple_update("update_user_level","users","level = ?","uid = ?")
|
||||
adapter.SimpleUpdate("update_user_level","users","level = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_score","users","score = score + ?","uid = ?")
|
||||
adapter.SimpleUpdate("increment_user_score","users","score = score + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_posts","users","posts = posts + ?","uid = ?")
|
||||
adapter.SimpleUpdate("increment_user_posts","users","posts = posts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_bigposts","users","posts = posts + ?, bigposts = bigposts + ?","uid = ?")
|
||||
adapter.SimpleUpdate("increment_user_bigposts","users","posts = posts + ?, bigposts = bigposts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_megaposts","users","posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?","uid = ?")
|
||||
adapter.SimpleUpdate("increment_user_megaposts","users","posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_topics","users","topics = topics + ?","uid = ?")
|
||||
adapter.SimpleUpdate("increment_user_topics","users","topics = topics + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("edit_profile_reply","users_replies","content = ?, parsed_content = ?","rid = ?")
|
||||
adapter.SimpleUpdate("edit_profile_reply","users_replies","content = ?, parsed_content = ?","rid = ?")
|
||||
|
||||
//delete_forum_stmt, err = db.Prepare("delete from forums where fid = ?")
|
||||
adapter.simple_update("delete_forum","forums","name= '', active = 0","fid = ?")
|
||||
adapter.SimpleUpdate("delete_forum","forums","name= '', active = 0","fid = ?")
|
||||
|
||||
adapter.simple_update("update_forum","forums","name = ?, desc = ?, active = ?, preset = ?","fid = ?")
|
||||
adapter.SimpleUpdate("update_forum","forums","name = ?, desc = ?, active = ?, preset = ?","fid = ?")
|
||||
|
||||
adapter.simple_update("update_setting","settings","content = ?","name = ?")
|
||||
adapter.SimpleUpdate("update_setting","settings","content = ?","name = ?")
|
||||
|
||||
adapter.simple_update("update_plugin","plugins","active = ?","uname = ?")
|
||||
adapter.SimpleUpdate("update_plugin","plugins","active = ?","uname = ?")
|
||||
|
||||
adapter.simple_update("update_theme","themes","default = ?","uname = ?")
|
||||
adapter.SimpleUpdate("update_theme","themes","default = ?","uname = ?")
|
||||
|
||||
adapter.simple_update("update_user","users","name = ?, email = ?, group = ?","uid = ?")
|
||||
adapter.SimpleUpdate("update_user","users","name = ?, email = ?, group = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("update_group_perms","users_groups","permissions = ?","gid = ?")
|
||||
adapter.SimpleUpdate("update_group_perms","users_groups","permissions = ?","gid = ?")
|
||||
|
||||
adapter.simple_update("update_group_rank","users_groups","is_admin = ?, is_mod = ?, is_banned = ?","gid = ?")
|
||||
adapter.SimpleUpdate("update_group_rank","users_groups","is_admin = ?, is_mod = ?, is_banned = ?","gid = ?")
|
||||
|
||||
adapter.simple_update("update_group","users_groups","name = ?, tag = ?","gid = ?")
|
||||
adapter.SimpleUpdate("update_group","users_groups","name = ?, tag = ?","gid = ?")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_deletes(adapter DB_Adapter) error {
|
||||
adapter.simple_delete("delete_reply","replies","rid = ?")
|
||||
func write_deletes(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleDelete("delete_reply","replies","rid = ?")
|
||||
|
||||
adapter.simple_delete("delete_topic","topics","tid = ?")
|
||||
adapter.SimpleDelete("delete_topic","topics","tid = ?")
|
||||
|
||||
|
||||
adapter.simple_delete("delete_profile_reply","users_replies","rid = ?")
|
||||
adapter.SimpleDelete("delete_profile_reply","users_replies","rid = ?")
|
||||
|
||||
adapter.simple_delete("delete_forum_perms_by_forum","forums_permissions","fid = ?")
|
||||
adapter.SimpleDelete("delete_forum_perms_by_forum","forums_permissions","fid = ?")
|
||||
|
||||
return nil
|
||||
}
|
218
topic.go
218
topic.go
@ -1,9 +1,7 @@
|
||||
package main
|
||||
//import "fmt"
|
||||
import "sync"
|
||||
import "strconv"
|
||||
import "html/template"
|
||||
import "database/sql"
|
||||
|
||||
type Topic struct
|
||||
{
|
||||
@ -88,222 +86,6 @@ type TopicsRow struct
|
||||
ForumName string //TopicsRow
|
||||
}
|
||||
|
||||
type TopicStore interface {
|
||||
Load(id int) error
|
||||
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
|
||||
Remove(id int) error
|
||||
RemoveUnsafe(id int) error
|
||||
AddLastTopic(item *Topic, fid int) error
|
||||
GetLength() int
|
||||
GetCapacity() int
|
||||
}
|
||||
|
||||
type StaticTopicStore struct {
|
||||
items map[int]*Topic
|
||||
length int
|
||||
capacity int
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewStaticTopicStore(capacity int) *StaticTopicStore {
|
||||
return &StaticTopicStore{items:make(map[int]*Topic),capacity:capacity}
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Get(id int) (*Topic, error) {
|
||||
sts.mu.RLock()
|
||||
item, ok := sts.items[id]
|
||||
sts.mu.RUnlock()
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetUnsafe(id int) (*Topic, error) {
|
||||
item, ok := sts.items[id]
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
|
||||
sts.mu.RLock()
|
||||
topic, ok := sts.items[id]
|
||||
sts.mu.RUnlock()
|
||||
if ok {
|
||||
return topic, nil
|
||||
}
|
||||
|
||||
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, &topic.Data)
|
||||
if err == nil {
|
||||
sts.Add(topic)
|
||||
}
|
||||
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, &topic.Data)
|
||||
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, &topic.Data)
|
||||
if err == nil {
|
||||
sts.Set(topic)
|
||||
} else {
|
||||
sts.Remove(id)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Set(item *Topic) error {
|
||||
sts.mu.Lock()
|
||||
_, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.items[item.ID] = item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.mu.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
}
|
||||
sts.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Add(item *Topic) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.mu.Lock()
|
||||
sts.items[item.ID] = item
|
||||
sts.mu.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) AddUnsafe(item *Topic) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Remove(id int) error {
|
||||
sts.mu.Lock()
|
||||
delete(sts.items,id)
|
||||
sts.mu.Unlock()
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) RemoveUnsafe(id int) error {
|
||||
delete(sts.items,id)
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
// Coming Soon...
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetLength() int {
|
||||
return sts.length
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) SetCapacity(capacity int) {
|
||||
sts.capacity = capacity
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetCapacity() int {
|
||||
return sts.capacity
|
||||
}
|
||||
|
||||
//type DynamicTopicStore struct {
|
||||
// items_expiries list.List
|
||||
// items map[int]*Topic
|
||||
//}
|
||||
|
||||
type SqlTopicStore struct {
|
||||
}
|
||||
|
||||
func NewSqlTopicStore() *SqlTopicStore {
|
||||
return &SqlTopicStore{}
|
||||
}
|
||||
|
||||
func (sus *SqlTopicStore) Get(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, &topic.Data)
|
||||
return &topic, err
|
||||
}
|
||||
|
||||
func (sus *SqlTopicStore) GetUnsafe(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, &topic.Data)
|
||||
return &topic, err
|
||||
}
|
||||
|
||||
func (sus *SqlTopicStore) CascadeGet(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, &topic.Data)
|
||||
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, &topic.Data)
|
||||
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, &topic.Data)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sus *SqlTopicStore) Set(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlTopicStore) Add(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlTopicStore) AddUnsafe(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlTopicStore) Remove(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlTopicStore) RemoveUnsafe(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
// Coming Soon...
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) GetCapacity() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (sus *SqlTopicStore) GetLength() int {
|
||||
// Return the total number of topics on the forums
|
||||
return 0
|
||||
}
|
||||
|
||||
func get_topicuser(tid int) (TopicUser,error) {
|
||||
if cache_topicuser != CACHE_SQL {
|
||||
topic, err := topics.Get(tid)
|
||||
|
223
topic_store.go
Normal file
223
topic_store.go
Normal file
@ -0,0 +1,223 @@
|
||||
package main
|
||||
|
||||
import "sync"
|
||||
import "database/sql"
|
||||
|
||||
var topics TopicStore
|
||||
|
||||
type TopicStore interface {
|
||||
Load(id int) error
|
||||
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
|
||||
Remove(id int) error
|
||||
RemoveUnsafe(id int) error
|
||||
AddLastTopic(item *Topic, fid int) error
|
||||
GetLength() int
|
||||
GetCapacity() int
|
||||
}
|
||||
|
||||
type StaticTopicStore struct {
|
||||
items map[int]*Topic
|
||||
length int
|
||||
capacity int
|
||||
get *sql.Stmt
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewStaticTopicStore(capacity int) *StaticTopicStore {
|
||||
return &StaticTopicStore{items:make(map[int]*Topic),capacity:capacity,get:get_topic_stmt}
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Get(id int) (*Topic, error) {
|
||||
sts.RLock()
|
||||
item, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetUnsafe(id int) (*Topic, error) {
|
||||
item, ok := sts.items[id]
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
|
||||
sts.RLock()
|
||||
topic, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return topic, nil
|
||||
}
|
||||
|
||||
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)
|
||||
if err == nil {
|
||||
sts.Add(topic)
|
||||
}
|
||||
return topic, err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) BypassGet(id int) (*Topic, error) {
|
||||
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)
|
||||
return topic, err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Load(id int) error {
|
||||
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)
|
||||
if err == nil {
|
||||
sts.Set(topic)
|
||||
} else {
|
||||
sts.Remove(id)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Set(item *Topic) error {
|
||||
sts.Lock()
|
||||
_, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.items[item.ID] = item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
}
|
||||
sts.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Add(item *Topic) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.Lock()
|
||||
sts.items[item.ID] = item
|
||||
sts.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) AddUnsafe(item *Topic) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Remove(id int) error {
|
||||
sts.Lock()
|
||||
delete(sts.items,id)
|
||||
sts.Unlock()
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) RemoveUnsafe(id int) error {
|
||||
delete(sts.items,id)
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
// Coming Soon...
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetLength() int {
|
||||
return sts.length
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) SetCapacity(capacity int) {
|
||||
sts.capacity = capacity
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) GetCapacity() int {
|
||||
return sts.capacity
|
||||
}
|
||||
|
||||
//type DynamicTopicStore struct {
|
||||
// items_expiries list.List
|
||||
// items map[int]*Topic
|
||||
//}
|
||||
|
||||
type SqlTopicStore struct {
|
||||
get *sql.Stmt
|
||||
}
|
||||
|
||||
func NewSqlTopicStore() *SqlTopicStore {
|
||||
return &SqlTopicStore{get_topic_stmt}
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) Get(id int) (*Topic, error) {
|
||||
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)
|
||||
return &topic, err
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) GetUnsafe(id int) (*Topic, error) {
|
||||
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)
|
||||
return &topic, err
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
|
||||
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)
|
||||
return &topic, err
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) BypassGet(id int) (*Topic, error) {
|
||||
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)
|
||||
return topic, err
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) Load(id int) error {
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sts *SqlTopicStore) Set(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) Add(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) AddUnsafe(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) Remove(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) RemoveUnsafe(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
// Coming Soon...
|
||||
return nil
|
||||
}
|
||||
func (sts *SqlTopicStore) GetCapacity() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (sts *SqlTopicStore) GetLength() int {
|
||||
return 0 // Return the total number of topics on the forums?
|
||||
}
|
281
user.go
281
user.go
@ -2,8 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"sync"
|
||||
"strings"
|
||||
"strconv"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -49,285 +47,6 @@ type Email struct
|
||||
Token string
|
||||
}
|
||||
|
||||
type UserStore interface {
|
||||
Load(id int) error
|
||||
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
|
||||
//SetConn(conn interface{}) error
|
||||
//GetConn() interface{}
|
||||
Remove(id int) error
|
||||
RemoveUnsafe(id int) error
|
||||
GetLength() int
|
||||
GetCapacity() int
|
||||
}
|
||||
|
||||
type StaticUserStore struct {
|
||||
items map[int]*User
|
||||
length int
|
||||
capacity int
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewStaticUserStore(capacity int) *StaticUserStore {
|
||||
return &StaticUserStore{items:make(map[int]*User),capacity:capacity}
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Get(id int) (*User, error) {
|
||||
sts.RLock()
|
||||
item, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetUnsafe(id int) (*User, error) {
|
||||
item, ok := sts.items[id]
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
|
||||
sts.RLock()
|
||||
user, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
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)
|
||||
if err == nil {
|
||||
sts.Set(user)
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
sts.Remove(id)
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
sts.Set(user)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Set(item *User) error {
|
||||
sts.Lock()
|
||||
user, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.Unlock()
|
||||
*user = *item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
sts.Unlock()
|
||||
sts.length++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Add(item *User) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.Lock()
|
||||
sts.items[item.ID] = item
|
||||
sts.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) AddUnsafe(item *User) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Remove(id int) error {
|
||||
sts.Lock()
|
||||
delete(sts.items,id)
|
||||
sts.Unlock()
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) RemoveUnsafe(id int) error {
|
||||
delete(sts.items,id)
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetLength() int {
|
||||
return sts.length
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) SetCapacity(capacity int) {
|
||||
sts.capacity = capacity
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetCapacity() int {
|
||||
return sts.capacity
|
||||
}
|
||||
|
||||
//type DynamicUserStore struct {
|
||||
// items_expiries list.List
|
||||
// items map[int]*User
|
||||
//}
|
||||
|
||||
type SqlUserStore struct {
|
||||
}
|
||||
|
||||
func NewSqlUserStore() *SqlUserStore {
|
||||
return &SqlUserStore{}
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) Get(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) GetUnsafe(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) CascadeGet(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) 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
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sus *SqlUserStore) Set(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) Add(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) AddUnsafe(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) Remove(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) RemoveUnsafe(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) GetCapacity() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) GetLength() int {
|
||||
return 0 // Return the total number of users registered on the forums?
|
||||
}
|
||||
|
||||
func SetPassword(uid int, password string) (error) {
|
||||
salt, err := GenerateSafeString(saltLength)
|
||||
if err != nil {
|
||||
|
287
user_store.go
Normal file
287
user_store.go
Normal file
@ -0,0 +1,287 @@
|
||||
package main
|
||||
|
||||
import "sync"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "database/sql"
|
||||
|
||||
var users UserStore
|
||||
|
||||
type UserStore interface {
|
||||
Load(id int) error
|
||||
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
|
||||
//SetConn(conn interface{}) error
|
||||
//GetConn() interface{}
|
||||
Remove(id int) error
|
||||
RemoveUnsafe(id int) error
|
||||
GetLength() int
|
||||
GetCapacity() int
|
||||
}
|
||||
|
||||
type StaticUserStore struct {
|
||||
items map[int]*User
|
||||
length int
|
||||
capacity int
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewStaticUserStore(capacity int) *StaticUserStore {
|
||||
return &StaticUserStore{items:make(map[int]*User),capacity:capacity}
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Get(id int) (*User, error) {
|
||||
sts.RLock()
|
||||
item, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetUnsafe(id int) (*User, error) {
|
||||
item, ok := sts.items[id]
|
||||
if ok {
|
||||
return item, nil
|
||||
}
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
|
||||
sts.RLock()
|
||||
user, ok := sts.items[id]
|
||||
sts.RUnlock()
|
||||
if ok {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
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)
|
||||
if err == nil {
|
||||
sts.Set(user)
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
sts.Remove(id)
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
sts.Set(user)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Set(item *User) error {
|
||||
sts.Lock()
|
||||
user, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.Unlock()
|
||||
*user = *item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
sts.Unlock()
|
||||
sts.length++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Add(item *User) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.Lock()
|
||||
sts.items[item.ID] = item
|
||||
sts.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) AddUnsafe(item *User) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
sts.items[item.ID] = item
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Remove(id int) error {
|
||||
sts.Lock()
|
||||
delete(sts.items,id)
|
||||
sts.Unlock()
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) RemoveUnsafe(id int) error {
|
||||
delete(sts.items,id)
|
||||
sts.length--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetLength() int {
|
||||
return sts.length
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) SetCapacity(capacity int) {
|
||||
sts.capacity = capacity
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) GetCapacity() int {
|
||||
return sts.capacity
|
||||
}
|
||||
|
||||
//type DynamicUserStore struct {
|
||||
// items_expiries list.List
|
||||
// items map[int]*User
|
||||
//}
|
||||
|
||||
type SqlUserStore struct {
|
||||
}
|
||||
|
||||
func NewSqlUserStore() *SqlUserStore {
|
||||
return &SqlUserStore{}
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) Get(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) GetUnsafe(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) CascadeGet(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) 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
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sus *SqlUserStore) Set(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) Add(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) AddUnsafe(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) Remove(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) RemoveUnsafe(id int) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) GetCapacity() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) GetLength() int {
|
||||
return 0 // Return the total number of users registered on the forums?
|
||||
}
|
Loading…
Reference in New Issue
Block a user