2019-09-29 04:56:39 +00:00
package common
import (
"database/sql"
2020-02-09 10:00:08 +00:00
//"log"
"time"
2019-09-29 04:56:39 +00:00
qgen "github.com/Azareal/Gosora/query_gen"
)
2019-10-06 22:20:37 +00:00
var GroupPromotions GroupPromotionStore
2019-09-29 04:56:39 +00:00
type GroupPromotion struct {
ID int
From int
To int
TwoWay bool
2020-02-09 10:00:08 +00:00
Level int
Posts int
MinTime int
RegisteredFor int
2019-09-29 04:56:39 +00:00
}
type GroupPromotionStore interface {
2019-10-06 22:20:37 +00:00
GetByGroup ( gid int ) ( gps [ ] * GroupPromotion , err error )
2019-09-29 04:56:39 +00:00
Get ( id int ) ( * GroupPromotion , error )
2020-02-09 10:00:08 +00:00
PromoteIfEligible ( u * User , level , posts int , registeredAt time . Time ) error
2019-09-29 04:56:39 +00:00
Delete ( id int ) error
2020-02-09 10:00:08 +00:00
Create ( from , to int , twoWay bool , level , posts , registeredFor int ) ( int , error )
2019-09-29 04:56:39 +00:00
}
type DefaultGroupPromotionStore struct {
getByGroup * sql . Stmt
get * sql . Stmt
delete * sql . Stmt
create * sql . Stmt
2020-02-09 10:00:08 +00:00
getByUser * sql . Stmt
getByUserMins * sql . Stmt
updateUser * sql . Stmt
updateGeneric * sql . Stmt
2019-09-29 04:56:39 +00:00
}
func NewDefaultGroupPromotionStore ( acc * qgen . Accumulator ) ( * DefaultGroupPromotionStore , error ) {
ugp := "users_groups_promotions"
2020-02-09 10:00:08 +00:00
prs := & DefaultGroupPromotionStore {
getByGroup : acc . Select ( ugp ) . Columns ( "pid, from_gid, to_gid, two_way, level, posts, minTime, registeredFor" ) . Where ( "from_gid=? OR to_gid=?" ) . Prepare ( ) ,
get : acc . Select ( ugp ) . Columns ( "from_gid, to_gid, two_way, level, posts, minTime, registeredFor" ) . Where ( "pid=?" ) . Prepare ( ) ,
delete : acc . Delete ( ugp ) . Where ( "pid=?" ) . Prepare ( ) ,
create : acc . Insert ( ugp ) . Columns ( "from_gid, to_gid, two_way, level, posts, minTime, registeredFor" ) . Fields ( "?,?,?,?,?,?,?" ) . Prepare ( ) ,
//err := s.getByUser.QueryRow(u.Group, level, posts, mins).Scan(&g.ID, &g.To, &g.TwoWay, &g.Level, &g.Posts, &g.MinTime, &g.RegisteredFor)
//getByUserMins: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=?").DateOlderThanQ("registeredFor", "minute").Orderby("level DESC").Limit("1").Prepare(),
getByUserMins : acc . Select ( ugp ) . Columns ( "pid, to_gid, two_way, level, posts, minTime, registeredFor" ) . Where ( "from_gid=? AND level<=? AND posts<=? AND registeredFor<=?" ) . Orderby ( "level DESC" ) . Limit ( "1" ) . Prepare ( ) ,
getByUser : acc . Select ( ugp ) . Columns ( "pid, to_gid, two_way, level, posts, minTime, registeredFor" ) . Where ( "from_gid=? AND level<=? AND posts<=?" ) . Orderby ( "level DESC" ) . Limit ( "1" ) . Prepare ( ) ,
updateUser : acc . Update ( "users" ) . Set ( "group=?" ) . Where ( "group=? AND uid=?" ) . Prepare ( ) ,
updateGeneric : acc . Update ( "users" ) . Set ( "group=?" ) . Where ( "group=? AND level>=? AND posts>=?" ) . Prepare ( ) ,
}
AddScheduledFifteenMinuteTask ( prs . Tick )
return prs , acc . FirstError ( )
}
func ( s * DefaultGroupPromotionStore ) Tick ( ) error {
return nil
2019-09-29 04:56:39 +00:00
}
func ( s * DefaultGroupPromotionStore ) GetByGroup ( gid int ) ( gps [ ] * GroupPromotion , err error ) {
rows , err := s . getByGroup . Query ( gid , gid )
if err != nil {
return nil , err
}
defer rows . Close ( )
for rows . Next ( ) {
g := & GroupPromotion { }
2020-02-09 10:00:08 +00:00
err := rows . Scan ( & g . ID , & g . From , & g . To , & g . TwoWay , & g . Level , & g . Posts , & g . MinTime , & g . RegisteredFor )
2019-09-29 04:56:39 +00:00
if err != nil {
return nil , err
}
gps = append ( gps , g )
}
return gps , rows . Err ( )
}
// TODO: Cache the group promotions to avoid hitting the database as much
func ( s * DefaultGroupPromotionStore ) Get ( id int ) ( * GroupPromotion , error ) {
/ * g , err := s . cache . Get ( id )
if err == nil {
return u , nil
} * /
g := & GroupPromotion { ID : id }
2020-02-09 10:00:08 +00:00
err := s . get . QueryRow ( id ) . Scan ( & g . From , & g . To , & g . TwoWay , & g . Level , & g . Posts , & g . MinTime , & g . RegisteredFor )
2019-09-29 04:56:39 +00:00
if err == nil {
//s.cache.Set(u)
}
return g , err
}
2020-02-09 10:00:08 +00:00
// TODO: Optimise this to avoid the query
func ( s * DefaultGroupPromotionStore ) PromoteIfEligible ( u * User , level , posts int , registeredAt time . Time ) error {
mins := time . Since ( registeredAt ) . Minutes ( )
2019-09-29 04:56:39 +00:00
g := & GroupPromotion { From : u . Group }
2020-02-09 10:00:08 +00:00
//log.Printf("pre getByUserMins: %+v\n", u)
err := s . getByUserMins . QueryRow ( u . Group , level , posts , mins ) . Scan ( & g . ID , & g . To , & g . TwoWay , & g . Level , & g . Posts , & g . MinTime , & g . RegisteredFor )
2019-09-29 04:56:39 +00:00
if err == sql . ErrNoRows {
2020-02-09 10:00:08 +00:00
//log.Print("no matches found")
2019-09-29 04:56:39 +00:00
return nil
} else if err != nil {
return err
}
2020-02-09 10:00:08 +00:00
//log.Printf("g: %+v\n", g)
if g . RegisteredFor == 0 {
_ , err = s . updateGeneric . Exec ( g . To , g . From , g . Level , g . Posts )
} else {
_ , err = s . updateUser . Exec ( g . To , g . From , u . ID )
}
2019-09-29 04:56:39 +00:00
return err
}
func ( s * DefaultGroupPromotionStore ) Delete ( id int ) error {
_ , err := s . delete . Exec ( id )
return err
}
2020-02-09 10:00:08 +00:00
func ( s * DefaultGroupPromotionStore ) Create ( from , to int , twoWay bool , level , posts , registeredFor int ) ( int , error ) {
res , err := s . create . Exec ( from , to , twoWay , level , posts , 0 , registeredFor )
2019-09-29 04:56:39 +00:00
if err != nil {
return 0 , err
}
lastID , err := res . LastInsertId ( )
return int ( lastID ) , err
}